用cocosCreator 制作一款简易的游戏。 史莱姆跳跃,碰到星星,然后星星+1.
参考cocosCreator 教程 js里的游戏 用C++写一款 游戏:
1.看似简单,仔细做就不简单了。 首先史莱姆是没有脚的,所以只能一跳一跳的移动。所以在行走的时候要保持跳跃。 当然这个是没有物理引擎的。 需要让史莱姆 的跳跃频率不同。
MoveBy() 通过设置值来确定移动的方向,与距离。不是MoveTo,这两个别的博客已经写满了。
auto myMoveBy = MoveBy::create(0.3f, Vec2(10, 190));
myMoveBy->startWithTarget(player);
//逆向上一个动作。
MoveBy *myMoveBy1=myMoveBy->reverse();
//由快向慢
ActionEase *actionEase = EaseOut::create(myMoveBy,2);
//由慢向快。
ActionEase *actionEase1 = EaseIn::create(myMoveBy1,2);
//一组动作。
ActionInterval *ac=Sequence::create(actionEase,actionEase1, NULL);
这样就可以模仿,类似有重力的动作了。 而大幅度跳跃动作。只要调整MoveBy参数就可以了。
当update()更新的时候,跳跃不能像 player 移动遍历一样,持续动作。否则叠加会飞出屏幕。因为跳跃在不断的叠加中。 你需要给跳跃写一个延迟。 ** 完成动作后再继续。
//aaa 设置在外层。
if(aaa>=35){
gameFMS->changeJump1();
aaa=0;
}
aaa++;
本来想找找键盘控制优先级问题。但是没有找到!!!。 不知道有没有意识到这个问题!我查了很多博客和书,对这个问题意识到的不多!!!!!
就是当按下A键的时候。如果快速按下D键和放下D键。 那么弹回A键的动作就会和按下D键发生冲突导致player停止运动。 并不能快速长按键盘切换。 所以只能给每一个键,做一个boolean值。
当按下D键的时候为true,那么A键的弹回就会没用。 反之亦然。
void ControlLayer::onKeyPressed(EventKeyboard::KeyCode keyCode, cocos2d::Event *event){
CCLOG("aaaaaa&&&&&&&&&&& %d",(int)keyCode);
switch((int)keyCode){
//D键
case 127:
this->schedule(schedule_selector(ControlLayer::onMoveKeyboard));
move=2;
aboolean=true;
break;
//A键
case 124:
this->schedule(schedule_selector(ControlLayer::onMoveKeyboard));
move=1;
aboolean1=true;
break;
case 59:
gameFMS->changeJump();
break;
case 6:
toMenu1Layer();
break;
};
}
void ControlLayer::onKeyReleased(EventKeyboard::KeyCode keyCode, cocos2d::Event *event){
switch((int)keyCode){
case 127:
if(!aboolean1){
this->unschedule(schedule_selector(ControlLayer::onMoveKeyboard));
}
aboolean=false;
aboolean1=false;
break;
case 124:
if(!aboolean){
this->unschedule(schedule_selector(ControlLayer::onMoveKeyboard));
}
aboolean=false;
aboolean1=false;
break;
default:
break;
};
}
不知道有没有什么好的方法。 以前拳皇的时候,超高速按下 上下左右 jkl 没有问题。
当包围小星星的一个Node里 小星星的类为空时,或者查找不到小星星,那么小星星就可以再生。 曾经想偷懒,把CocosCreator里的类,重新克隆出来,但是创建出来被删除以后,只能new 了,原来CocosCreator已经被删除不能再生了。 所以只能重新把数据导出来,放进新的Sprite里。再添加
spriteEnemy=Sprite::create();
spriteEnemy->setTexture("starSprite.png");
spriteEnemy->setName("spriteEnemy");
spriteEnemy->setPosition(Vec2(146, 170));
camera1->addChild(spriteEnemy);
上上一章,打飞机游戏有一个半误区。 就是其实碰撞检测已经封装好了。 虽然只是用来测试我能力的一个白板游戏。就是根本不偷懒,也不用封装,就是纯写。这样就要检测长宽高。来做碰撞检测。
其实很简单 把找出精灵的方块大小。然后检测就可以了。
Rect rect_player=player->getBoundingBox();
Rect rect_spriteEnemy=spriteEnemy->getBoundingBox();
Rect rect_player=player->getBoundingBox();
Rect rect_spriteEnemy=spriteEnemy->getBoundingBox();
//碰撞检测。
if(rect_player.intersectsRect(rect_spriteEnemy)){
start++;
camera1->removeChild(spriteEnemy);
}
检测完成小星星+1。 我在左上角有一个计数统计。
如果写这么点那么1个小时就可以完成。 重要的是第一次尝试写一个菜单。类似于网络游戏的一个装备仓库。存储武器的的东西。
一个动态的仓库。 当键盘按下ESC的时候,场景Scene会转换。跳到一个新的场景中
replaceScene、pushScene、popScene
creator::CreatorReader* reader = creator::CreatorReader::createWithFilename("cocosMenu.ccreator");
reader->setup();
Scene *menu1Scene=reader->getSceneGraph();
menu1Layer=Menu1Layer::create();
menu1Layer->score=start;
//把菜单传入进去
menu1Layer->init_L(menu1Scene);
menu1Scene->addChild(menu1Layer);
//替换场景。 应该用pushScene什么,否则以前的数据就丢失了。除非提前 存储好。比如生成json或者xml或者什么的。
Director::getInstance()->replaceScene(menu1Scene);
进入MenuScene里边。
新的MenuScene里边,首先我做了一个ScrollView。 把数据放进里边,当然我往里边里边传递的值仅仅是一个数字,这个数字是加载的小星星。 所以新的界面小星星会非常多。 由于是动态加载的,小星星不固定。所以 当我在CocosCreator里,画了一个小星星的卡片。
layout = scene->getChildByName<Sprite *>("Layout");
auto layout1 = layout->getChildByName<Sprite *>("Layout1");
auto sprite1 = layout1->getChildByName<Sprite *>("sprite");
auto label = layout1->getChildByName<Label *>("label");
for(int i=0;i<score;i++){
auto layout_0 = Sprite::create();
layout_0->setName("layout");
layout_0->setAnchorPoint(Vec2(0.5, 0.5));
layout_0->setColor(Color3B(48, 47, 47));
layout_0->setTexture("background2.png");
layout_0->setPosition(Vec2(scroll->getPositionX()/3,2000));
layout_0->setContentSize(layout->getContentSize());
auto layout_1 = Sprite::create();
layout_1->setTexture("background2.png");
layout_1->setPosition(Vec2(layout1->getPositionX(),layout1->getPositionY()));
layout_1->setColor(Color3B(255, 255, 255));
layout_1->setContentSize(layout1->getContentSize());
layout_0->addChild(layout_1);
auto Sprite_start=Sprite::create();
Sprite_start->setTexture("starSprite.png");
Sprite_start->setPosition(sprite1->getPosition());
Sprite_start->setContentSize(sprite1->getContentSize());
layout_1->addChild(Sprite_start);
auto label_0 = Label::create();
label_0->setString("jaweklfjaiowjgifta");
label_0->setColor(Color3B(0, 0, 0));
label_0->setPosition(label->getPosition());
label_0->setContentSize(label->getContentSize());
layout_1->addChild(label_0);
vector.pushBack(layout_0);
}
取出数据,创建new 加载它。
当然一串的星星,不可能并排写,所以用%把Sprite 排开
for(int i=0;i<score;i++){
Sprite *layout=vector.at(i);
//如果除以3 为0,那么增加一行。
if(i%3==0){
j++;
}
Vec2 vec(scroll->getPositionX()/3 +300 *(i%3),4800 -j*(layout->getContentSize().height+20));
layout->setPosition(vec);
layout->setName("ddddfdfafasd");
scroll->addChild(layout,5);
}
这样就可以排成一个每行3个图标。j行的代码。
当然如果这么完了,那么就没有意义了。
放进仓库里的Sprite 需要选择, 首先从把Vector里,放进update(float dt) 迭代。迭代区域选择的部分高亮。
在.h类中设置一个值 score_l。当作键盘值。
设置键盘监听
当按一下D值,score_l +1,当A score_l-1 ,当 按下s键score_l/6 的整数值为1的时候,那么显示区域增加%12,如果按下w那么如果score_l/9 整数为一 那么显示区域减少%12。
void Menu1Layer::onKeyPressed(EventKeyboard::KeyCode keyCode, cocos2d::Event *event){
CCLOG("aaaaaa&&&&&&&&&&& %d",(int)keyCode);
int c=score_l/6;
int g=score_l/9;
switch((int)keyCode){
//D键
case 127:
score_l=score_l+1;
break;
//A键
case 124:
if(score_l>0&&score_l<score){
score_l=score_l-1;
}
break;
//W键
case 146:
//注意调整显示区域。找了很久才找到,其他的没用!!!
scroll->jumpToPercentVertical(g*15);
if(score_l>=3){
score_l=score_l-3;
}
break;
//S键
case 142:
if(score-score_l>=3&&score_l+3<=score){
score_l=score_l+3;
}
scroll->jumpToPercentVertical(c*12);
break;
case 6:
creator::CreatorReader* reader = creator::CreatorReader::createWithFilename("cocosGameShao.ccreator");
reader->setup();
Scene *creatorGame=reader->getSceneGraph();
ControlLayer *control1=ControlLayer::create();
control1->init();
control1->Scene_init(creatorGame);
creatorGame->addChild(control1);
Director::getInstance()->replaceScene(creatorGame);
break;
}
}
注意Sprite需要一个白色的图片做背景,才能setColor。 其他颜色或者没有调整不了。
for(int i=0;i<vector.size();i++){
Sprite *sprite=vector.at(i);
if(i==score_l){
//高亮
sprite->setColor(Color3B(232,201 ,100));
}else{
//普通
sprite->setColor(Color3B(72,71 ,71));
}
}