Cocos2d-x Tiled Map Editor(三)

转自:http://blog.csdn.net/zhy_cheng/article/details/8363028

 

上一篇中完成了再地图中添加西瓜,让hero吃,这篇将会完成这个游戏。

1.添加敌人

在对象层中加入敌人,

Cocos2d-x Tiled Map Editor(三)_第1张图片

注意,加入了一个键值对,键为n,值为1。这个键值对主要就是为了区分敌人和英雄。将敌人画在地图上。
[cpp]  view plain copy
  1. for(int i=0;i<int(objects->getObjects()->count());i++)
  2. {
  3. CCDictionary *enemy=(CCDictionary *)objects->getObjects()->objectAtIndex(i);
  4. if(enemy->valueForKey("n")->intValue()==1)
  5. {
  6. CCSprite *s=CCSprite::create("enemy1.png");
  7. float x=enemy->valueForKey("x")->floatValue();
  8. float y=enemy->valueForKey("y")->floatValue();
  9. s->setPosition(ccp(x,y));
  10. s->setAnchorPoint(CCPoint(0,0));
  11. _tileMap->addChild(s,4);
  12. CCActionInterval *move=CCMoveBy::create(2,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));//
  13. CCFiniteTimeAction *func=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::goon));
  14. s->runAction(CCSequence::create(move,func,NULL));
  15. }
  16. }
[cpp]  view plain copy
  1. for(int i=0;i<int(objects->getObjects()->count());i++)  
  2.         {  
  3.             CCDictionary *enemy=(CCDictionary *)objects->getObjects()->objectAtIndex(i);  
  4.             if(enemy->valueForKey("n")->intValue()==1)  
  5.             {  
  6.                 CCSprite *s=CCSprite::create("enemy1.png");  
  7.                 float x=enemy->valueForKey("x")->floatValue();  
  8.                 float y=enemy->valueForKey("y")->floatValue();  
  9.                 s->setPosition(ccp(x,y));  
  10.                 s->setAnchorPoint(CCPoint(0,0));  
  11.                 _tileMap->addChild(s,4);  
  12.                 CCActionInterval *move=CCMoveBy::create(2,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));//  
  13.                 CCFiniteTimeAction *func=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::goon));  
  14.                 s->runAction(CCSequence::create(move,func,NULL));  
  15.             }  
  16.         }  
这段代码从对象层中获得所有对象,判断键为n的是否为1,有则为敌人,加入到地图中,并且让敌人运动。
在运动完后调用 goon函数:
[cpp]  view plain copy
  1. void HelloWorld::goon(CCNode *pSender)
  2. {
  3. CCSprite *s=(CCSprite *)pSender;
  4. CCActionInterval *move=CCMoveBy::actionWithDuration(2,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));//
  5. CCFiniteTimeAction *func=CCCallFuncN::actionWithTarget(this,callfuncN_selector(HelloWorld::goon));
  6. s->runAction(CCSequence::actions(move,func,NULL));
  7. }
[cpp]  view plain copy
  1. void HelloWorld::goon(CCNode *pSender)  
  2. {  
  3.     CCSprite *s=(CCSprite *)pSender;  
  4.     CCActionInterval *move=CCMoveBy::actionWithDuration(2,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));//  
  5.                 CCFiniteTimeAction *func=CCCallFuncN::actionWithTarget(this,callfuncN_selector(HelloWorld::goon));  
  6.                 s->runAction(CCSequence::actions(move,func,NULL));  
  7. }  
在goon函数中继续调用自己,这样敌人就一直向英雄运动。

2.使英雄可以攻击

现在游戏的点击是使得英雄移动向指定的位置,所以,为了使得英雄有攻击,可以添加一个状态,状态为true的话,控制英雄移动,状态为false的话,控制发射子弹。在头文件中加入
[cpp]  view plain copy
  1. bool mode;
[cpp]  view plain copy
  1. bool mode;  

在屏幕上添加菜单
[cpp]  view plain copy
  1. CCMenuItem *oon,*ooff;
  2. oon=CCMenuItemImage::create("projectile-button-on.png","projectile-button-on.png");
  3. ooff=CCMenuItemImage::create("projectile-button-off.png","projectile-button-off.png");
  4. CCMenuItemToggle *toggle=CCMenuItemToggle::createWithTarget(this,//回调函数所在的类
  5. menu_selector(HelloWorld::toggleGame),//回调函数
  6. ooff,oon,NULL //添加的菜单
  7. );
  8. CCMenu *menu=CCMenu::create(toggle,NULL);
  9. menu->setPosition(ccp(oon->getContentSize().width/2,oon->getContentSize().height/2));
  10. addChild(menu);
[cpp]  view plain copy
  1. CCMenuItem *oon,*ooff;  
  2. oon=CCMenuItemImage::create("projectile-button-on.png","projectile-button-on.png");  
  3. ooff=CCMenuItemImage::create("projectile-button-off.png","projectile-button-off.png");  
  4. CCMenuItemToggle *toggle=CCMenuItemToggle::createWithTarget(this,//回调函数所在的类     
  5. menu_selector(HelloWorld::toggleGame),//回调函数     
  6. ooff,oon,NULL    //添加的菜单     
  7.   );    
  8. CCMenu *menu=CCMenu::create(toggle,NULL);  
  9. menu->setPosition(ccp(oon->getContentSize().width/2,oon->getContentSize().height/2));  
  10. addChild(menu);  

在toggleGame函数中添加控制状态改变的代码:
[cpp]  view plain copy
  1. void HelloWorld::toggleGame(CCObject *pSender)
  2. {
  3. mode=mode?false:true;
  4. }
[cpp]  view plain copy
  1. void HelloWorld::toggleGame(CCObject *pSender)  
  2. {  
  3.     mode=mode?false:true;  
  4. }  

当状态为false的时候,hero发射子弹:
[cpp]  view plain copy
  1. else
  2. {
  3. CCSprite *s=CCSprite::create("Projectile.png");
  4. s->setPosition(_player->getPosition());
  5. _tileMap->addChild(s,4);
  6. float dx=pp.x-_player->getPosition().x;
  7. float dy=pp.y-_player->getPosition().y;
  8. if(dx>0)
  9. {
  10. float lx=32*30-_player->getPosition().x;
  11. float ly=dy/dx*lx;
  12. CCActionInterval *move=CCMoveBy::create(3,ccp(lx+s->getContentSize().width,ly));
  13. CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::targetFinish));
  14. s->runAction(CCSequence::actions(move,ff,NULL));
  15. }
  16. else
  17. {
  18. float lx=0-_player->getPosition().x;
  19. float ly=dy/dx*lx;
  20. CCActionInterval *move=CCMoveBy::actionWithDuration(3,ccp(lx-s->getContentSize().width,ly);
  21. CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::targetFinish));
  22. s->runAction(CCSequence::actions(move,ff,NULL));
  23. }
[cpp]  view plain copy
  1. else  
  2. {  
  3.     CCSprite *s=CCSprite::create("Projectile.png");  
  4.     s->setPosition(_player->getPosition());  
  5.     _tileMap->addChild(s,4);  
  6.     float dx=pp.x-_player->getPosition().x;  
  7.     float dy=pp.y-_player->getPosition().y;  
  8.     if(dx>0)  
  9.     {  
  10.         float lx=32*30-_player->getPosition().x;  
  11.         float ly=dy/dx*lx;  
  12.         CCActionInterval *move=CCMoveBy::create(3,ccp(lx+s->getContentSize().width,ly));  
  13.         CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::targetFinish));  
  14.         s->runAction(CCSequence::actions(move,ff,NULL));  
  15.     }  
  16.     else  
  17.     {  
  18.         float lx=0-_player->getPosition().x;  
  19.         float ly=dy/dx*lx;  
  20.         CCActionInterval *move=CCMoveBy::actionWithDuration(3,ccp(lx-s->getContentSize().width,ly);  
  21.         CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(HelloWorld::targetFinish));  
  22.         s->runAction(CCSequence::actions(move,ff,NULL));  
  23.     }  
发射完子弹后,让子弹移动到地图外,通过hero的位置和点击的位置,可以知道发射子弹的角度,然后通过相似三角形对应边成比例的原理,可以知道x超出地图的位置。这样让子弹移出地图。

3.后期工作

现在地图上该有什么的都有了,就只剩下判断胜负的问题了。具体而言,英雄吃完所有西瓜就赢了,被敌人碰到了就输了。这就是要求做碰撞检测。在cocos2d-x中判断碰撞很好做,我只说一说原理,具体实现没有什么难度。
将所有的敌人加入到一个CCArray中,将所有的子弹加入到另外一个CCArray中,在这个CCLayer中加入一个schedule,每隔一定的时间对敌人的CCArray与子弹的CCArray做碰撞检测,如果碰撞了,移除碰撞的敌人和子弹,还要检测敌人和hero的碰撞检测,如果碰撞了,就结束游戏。

具体怎么检测碰撞,我们可以得到子弹的CCRect,敌人的CCRect,英雄的CCRect,使用CCRect的成员函数
[cpp]  view plain copy
  1. bool intersectsRect (const CCRect & rect) const
[cpp]  view plain copy
  1. bool intersectsRect (const CCRect & rect) const  
来判断碰撞。



好了,使用Tiled制作游戏就结束了,最后这个游戏该怎么样做的更好,从以下几个方面考虑
1.增加更多的敌人
2.增加更多的物品
3.地图变大,变复杂
4.增加关卡
5.制作更好的游戏画面
6.显示英雄的生命值

最后给出工程代码下载:【Cocos2d-x游戏引擎开发笔记(15)】Tiled Map Editor(三)

你可能感兴趣的:(Cocos2d-x Tiled Map Editor(三))