原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/8363028
上一篇中完成了再地图中添加西瓜,让hero吃,这篇将会完成这个游戏。
1.添加敌人
在对象层中加入敌人,
注意,加入了一个键值对,键为n,值为1。这个键值对主要就是为了区分敌人和英雄。将敌人画在地图上。
for(int i=0;i<int(objects->getObjects()->count());i++)这段代码从对象层中获得所有对象,判断键为n的是否为1,有则为敌人,加入到地图中,并且让敌人运动。 在运动完后调用goon函数:
{
CCDictionary *enemy=(CCDictionary *)objects->getObjects()->objectAtIndex(i);
if(enemy->valueForKey("n")->intValue()==1)
{
CCSprite *s=CCSprite::create("enemy1.png");
float x=enemy->valueForKey("x")->floatValue();
float y=enemy->valueForKey("y")->floatValue();
s->setPosition(ccp(x,y));
s->setAnchorPoint(CCPoint(0,0));
_tileMap->addChild(s,4);
CCActionInterval *move=CCMoveBy::create(2,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));//
CCFiniteTimeAction *func=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::goon));
s->runAction(CCSequence::create(move,func,NULL));
}
}
void HelloWorld::goon(CCNode *pSender)在goon函数中继续调用自己,这样敌人就一直向英雄运动。
{
CCSprite *s=(CCSprite *)pSender;
CCActionInterval *move=CCMoveBy::actionWithDuration(2,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));//
CCFiniteTimeAction *func=CCCallFuncN::actionWithTarget(this,callfuncN_selector(HelloWorld::goon));
s->runAction(CCSequence::actions(move,func,NULL));
}
2.使英雄可以攻击
现在游戏的点击是使得英雄移动向指定的位置,所以,为了使得英雄有攻击,可以添加一个状态,状态为true的话,控制英雄移动,状态为false的话,控制发射子弹。在头文件中加入bool mode;
在屏幕上添加菜单
CCMenuItem *oon,*ooff;
oon=CCMenuItemImage::create("projectile-button-on.png","projectile-button-on.png");
ooff=CCMenuItemImage::create("projectile-button-off.png","projectile-button-off.png");
CCMenuItemToggle *toggle=CCMenuItemToggle::createWithTarget(this,//回调函数所在的类
menu_selector(HelloWorld::toggleGame),//回调函数
ooff,oon,NULL //添加的菜单
);
CCMenu *menu=CCMenu::create(toggle,NULL);
menu->setPosition(ccp(oon->getContentSize().width/2,oon->getContentSize().height/2));
addChild(menu);
在toggleGame函数中添加控制状态改变的代码:
void HelloWorld::toggleGame(CCObject *pSender)
{
mode=mode?false:true;
}
当状态为false的时候,hero发射子弹:
else发射完子弹后,让子弹移动到地图外,通过hero的位置和点击的位置,可以知道发射子弹的角度,然后通过相似三角形对应边成比例的原理,可以知道x超出地图的位置。这样让子弹移出地图。
{
CCSprite *s=CCSprite::create("Projectile.png");
s->setPosition(_player->getPosition());
_tileMap->addChild(s,4);
float dx=pp.x-_player->getPosition().x;
float dy=pp.y-_player->getPosition().y;
if(dx>0)
{
float lx=32*30-_player->getPosition().x;
float ly=dy/dx*lx;
CCActionInterval *move=CCMoveBy::create(3,ccp(lx+s->getContentSize().width,ly));
CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::targetFinish));
s->runAction(CCSequence::actions(move,ff,NULL));
}
else
{
float lx=0-_player->getPosition().x;
float ly=dy/dx*lx;
CCActionInterval *move=CCMoveBy::actionWithDuration(3,ccp(lx-s->getContentSize().width,ly);
CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::targetFinish));
s->runAction(CCSequence::actions(move,ff,NULL));
}
3.后期工作
现在地图上该有什么的都有了,就只剩下判断胜负的问题了。具体而言,英雄吃完所有西瓜就赢了,被敌人碰到了就输了。这就是要求做碰撞检测。在cocos2d-x中判断碰撞很好做,我只说一说原理,具体实现没有什么难度。将所有的敌人加入到一个CCArray中,将所有的子弹加入到另外一个CCArray中,在这个CCLayer中加入一个schedule,每隔一定的时间对敌人的CCArray与子弹的CCArray做碰撞检测,如果碰撞了,移除碰撞的敌人和子弹,还要检测敌人和hero的碰撞检测,如果碰撞了,就结束游戏。具体怎么检测碰撞,我们可以得到子弹的CCRect,敌人的CCRect,英雄的CCRect,使用CCRect的成员函数
bool intersectsRect (const CCRect & rect) const来判断碰撞。
好了,使用Tiled制作游戏就结束了,最后这个游戏该怎么样做的更好,从以下几个方面考虑1.增加更多的敌人2.增加更多的物品3.地图变大,变复杂4.增加关卡5.制作更好的游戏画面6.显示英雄的生命值
最后给出工程代码下载:【Cocos2d-x游戏引擎开发笔记(15)】Tiled Map Editor(三)