cocos2d x 入门学习(一)实例制作简单的射击小游戏Star Fighter
2014-01-08 21:10
555 查看
我们将使用cocos2d-x制作一个简单的射击游戏。
本文所用的制作环境是cocos2d x 2.0.4,VS2010。
参考资料:
1、本文的原型其实是来自cocos2d-2.0-x-2.0.4官方下载的安装软件,解压缩后可以看到该例子,即在根目录下的Samples示例文件夹里面的SimpleGame。
2、博客无幻的SimpleGame制作的文章,这里是传送门: http://blog.csdn.net/akof1314/article/details/8268882
我这里只是把他们横版的游戏变成竖版,取消白色游戏背景改为用图片背景,而图片素材则换成微信飞机的图片。将原本走掉1个就结束的游戏规则改为如果超过3个敌机跑到屏幕下方里,则游戏结束。飞机的速度和显示时间也稍做了调整。此外本文修改了以上两文中子弹路径算法的一个细微的小错漏,详情请看下文关于子弹路径的算法。
下面我们直接进入主题。制作方法如下:
1、创建工程。新建Cocos2d-win32工程,工程名为"Star Fighter",去除"Box2D"选项(该项目不需要用),勾选"Simple Audio Engine in Cocos Denshion"选项;
2、编译运行,查看HelloWorld是否正常显示。可以看到如下图所示:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/84f29ebfcbd8d95d8c72d99ed6489746)
3、下载本游戏所需的资源,将资源放置"Resources"目录下;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/a2ec527ebc96b0fca60e84176c63b598)
4、设置游戏屏幕尺寸。
打开main.cpp文件设置分辨率,
找到 setFrameSize函数把其括号里的数据,设置成你要的分辨率,用于开发。
市场上装有Andriod系统的手机分辨率常用的主要为240*320、320*480、480*800三种。
修改后的main.cpp文件代码为:
5、设置游戏背景,最简单的方法是将原本HelloWorldScene.cpp里面的HelloWorld.png文件名,直接替换为我们的背景图片bg_01.jpg。
我们可以看到修改后的代码为:
cocos2d中图片的添加也是通过添加精灵实现的,由这里我们学会了cocos2d添加精灵的方法。
6、添加显示游戏名字。最简单的方法是将原本HelloWorldScene.cpp里面显示的Hello World文字,直接替换为我们的"Star Fighter",及修改字体的大小。
7、添加玩家player,让玩家位于下方屏幕的中间,在刚刚的HelloWorldScene.cpp文件的init函数里面,(仿照添加背景的代码)添加如下的代码:
8、把HelloWorldScene.cpp文件的init函数里面,我们不需要用到的以下这段删掉。
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
9、运行编译程序,可以看到以下画面。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/ed798b508d61db6e18409edb3f4426c7)
10.接下来添加敌机,并且让它可以移动。我们在屏幕上方中间创建,建立动作让它们向下移动。
我们在HelloWorldScene.h头文件中添加函数声明void addMonster();
然后在HelloWorldScene.cpp中增加addMonster方法,代码如下:
在屏幕上方以随机的位置添加敌机精灵,注意计算精灵X轴的位置坐标(因为默认描点在中心,不能让敌机截断只有一部分)。
然后通过随机函数控制的敌机运动总时间,让敌机从上方移动到下方,
移动到离开边界后,调用回调函数spriteMoveFinished,进行删除精灵对象。
这里调用的回调函数,我们尚未对其进行声明和定义。
下面我们先在HelloWorldScene.h头文件中添加函数声明void spriteMoveFinished(CCNode *sender);
然后在HelloWorldScene.cpp中增加函数spriteMoveFinished的定义,代码如下:
接下去就是安装定时器从而定时创建敌机。我们在bool HelloWorld::init()函数的添加玩家player精灵的代码后面,安装定时器,每秒执行一次,代码如下:
增加gameLogic方法函数,在HelloWorldScene.h头文件中添加函数声明void gameLogic( float dt );
在HelloWorldScene.cpp中增加代码如下:
编译运行,可以看到屏幕上方敌机定时增加,并且以不同的速度向下移动,如下图所示:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/e00ff2d028caf7cfc974e51ebcb1d662)
11.接着让玩家可以发射子弹。
当用户在屏幕点击时,就让玩家往点击的方向进行发射子弹。
用户的屏幕点击点并不是子弹移动的最终地,借用原文的一张图片来说明:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/d065da0f7636b92ecd396c1f650e9475)
首先,我们用引擎的函数得到触摸点与子弹初始位置之差我们命名为(offset.x,offset.y)即上图的 (offx,offy)。用户的屏幕点击点并不是子弹移动的最终地,假设如果没有发生碰撞,子弹可以移动到屏幕的尽头直到子弹完全消失,我们将该点命名为(realX,realY)。
当用户点击屏幕后,我们创建子弹精灵,算出触摸点与子弹初始位置之差(offset.x,offset.y)。若触摸点(offset.y>0)在初始位置的上方(即玩家上方),则添加子弹到层上。以等比例原理方法,计算出子弹飞向屏幕上边的最终坐标。然后再用勾股定理计算飞行长度,假定速度为每秒480像素,则计算出飞行总时间。之后就是让子弹执行给定的飞行动作,以及之后的删除自身调用。
要让层可以支持触摸,需要在init方法里面添加如下代码:
然后重载ccTouchesEnded方法。在HelloWorldScene.h头文件中添加函数声明virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
在HelloWorldScene.cpp中添加代码如下:
编译运行,往屏幕点击,可以看到子弹发射出去。如下图所示。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/627e79ffad6ce5a4c0030b1b09282369)
10.当子弹碰到怪物时,怪物被消灭,子弹消失,实现这些我们需要用碰撞检测。需要在场景中跟踪目标和子弹,在HelloWorldScene.h声明如下:
void update(float dt);
cocos2d::CCArray *_monsters;
cocos2d::CCArray *_projectiles;
在HelloWorldScene.cpp构造函数和析构函数,添加如下:
然后在init函数中初始化这两个数组:
修改addMonster函数,为怪物精灵添加标签,并加入到数组,代码如下:
修改ccTouchesEnded函数,为子弹精灵添加标签,并加入到数组,代码如下:
然后修改spriteMoveFinished函数,增加如下代码:
添加如下方法:
遍历子弹数组,计算每一个子弹所可能遇到的怪物,用它们各自的边界框进行交叉检测,检测到交叉,则将怪物对象放入ToDelete(待删除)数组,不能在遍历的时候删除一个对象。若是子弹遇到了怪物,也需要放入ToDelete(待删除)数组。然后从场景和数组中移动掉。同样,也在init函数,安装定时器,代码如下:
11.编译运行,这时当子弹和怪物碰撞时,它们就会消失;
12.添加音效,在init函数添加背景音乐,代码如下:
在ccTouchesEnded函数,添加子弹音效,代码如下:
13.接下来,创建一个新的场景,来指示"You Win"或者"You Lose"。右键 工程,"Add"→"Class..."→"C++"→"Add","Base class"为CCLayerColor,"Class name"为GameOverLayer,如下图所示:
![](http://img.my.csdn.net/uploads/201212/07/1354854202_7483.png)
GameOverLayer.h文件代码为:
GameOverLayer.cpp文件代码为:
游戏结束时,切换到以上所建的场景,场景上的层显示一个文本,在3秒之后返回到HelloWorld场景中。
14.最后,为游戏添加一些游戏逻辑。
我们将规则定位:当放走3个敌机后,则游戏结束。而如果游戏结束时,被消灭敌机数量超过30个,则判断为胜利,反之为失败。
记录玩家消灭怪物的数量,进而决定该玩家输赢。在HelloWorldScene.h文件中,添加如下:
在HelloWorldScene.cpp文件,HelloWorld()构造函数,添加如下代码:
添加头文件引用:
在update定时函数中,monstersToDelete循环removeChild(monster, true)的后面添加被消灭怪物的计数,并判断胜利条件,代码如下:
最后为玩家添加游戏结束条件,规定如果超过3个敌机跑到屏幕下方里,则游戏结束。
在HelloWorldScene.h文件中,添加如下:
在HelloWorldScene.cpp文件中的spriteMoveFinished函数里,sprite->getTag() == 1条件的后面,添加如下:
最后编译并运行,即可看到游戏。到此已完成了一个简单的游戏,包含音效,并带有胜利和失败的结束。
本例子源代码附加资源下载地址:http://download.csdn.net/detail/u013174689/6826063
可以运行压缩文件夹Star Fighter源码\Debug.win32里的exe文件运行查看游戏效果。
如文章存在错误之处,欢迎指出,以便改正。
本文所用的制作环境是cocos2d x 2.0.4,VS2010。
参考资料:
1、本文的原型其实是来自cocos2d-2.0-x-2.0.4官方下载的安装软件,解压缩后可以看到该例子,即在根目录下的Samples示例文件夹里面的SimpleGame。
2、博客无幻的SimpleGame制作的文章,这里是传送门: http://blog.csdn.net/akof1314/article/details/8268882
我这里只是把他们横版的游戏变成竖版,取消白色游戏背景改为用图片背景,而图片素材则换成微信飞机的图片。将原本走掉1个就结束的游戏规则改为如果超过3个敌机跑到屏幕下方里,则游戏结束。飞机的速度和显示时间也稍做了调整。此外本文修改了以上两文中子弹路径算法的一个细微的小错漏,详情请看下文关于子弹路径的算法。
下面我们直接进入主题。制作方法如下:
1、创建工程。新建Cocos2d-win32工程,工程名为"Star Fighter",去除"Box2D"选项(该项目不需要用),勾选"Simple Audio Engine in Cocos Denshion"选项;
2、编译运行,查看HelloWorld是否正常显示。可以看到如下图所示:
3、下载本游戏所需的资源,将资源放置"Resources"目录下;
4、设置游戏屏幕尺寸。
打开main.cpp文件设置分辨率,
找到 setFrameSize函数把其括号里的数据,设置成你要的分辨率,用于开发。
市场上装有Andriod系统的手机分辨率常用的主要为240*320、320*480、480*800三种。
修改后的main.cpp文件代码为:
eglView->setFrameSize(320, 480); //本文采用(320, 480);像素开发。
5、设置游戏背景,最简单的方法是将原本HelloWorldScene.cpp里面的HelloWorld.png文件名,直接替换为我们的背景图片bg_01.jpg。
我们可以看到修改后的代码为:
// 添加背景Add a splash screen, show the cocos2d splash image. CCSprite* pSprite = CCSprite::create("bg_01.jpg"); CC_BREAK_IF(! pSprite); // 设置坐标位置Place the sprite on the center of the screen pSprite->setPosition(ccp(size.width/2, size.height/2)); // 添加到图层显示出来Add the sprite to HelloWorld layer as a child layer. this->addChild(pSprite, 0);
cocos2d中图片的添加也是通过添加精灵实现的,由这里我们学会了cocos2d添加精灵的方法。
6、添加显示游戏名字。最简单的方法是将原本HelloWorldScene.cpp里面显示的Hello World文字,直接替换为我们的"Star Fighter",及修改字体的大小。
// 添加游戏名字 Add a label shows "Star Fighter". // Create a label and initialize with string "Hello World". CCLabelTTF* pLabel = CCLabelTTF::create("Star Fighter", "Arial", 36); CC_BREAK_IF(! pLabel); // Get window size and place the label upper. CCSize size = CCDirector::sharedDirector()->getWinSize(); pLabel->setPosition(ccp(size.width / 2, size.height - 50)); // Add the label to HelloWorld layer as a child layer. this->addChild(pLabel, 1);//第二个数字是渲染的顺序
7、添加玩家player,让玩家位于下方屏幕的中间,在刚刚的HelloWorldScene.cpp文件的init函数里面,(仿照添加背景的代码)添加如下的代码:
//添加玩家player精灵 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCSprite *player = CCSprite::create("player.png"); player->setPosition(ccp(winSize.width / 2, 50));//设置坐标位置,注意(x,y)的值 this->addChild(player, 2);
8、把HelloWorldScene.cpp文件的init函数里面,我们不需要用到的以下这段删掉。
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
9、运行编译程序,可以看到以下画面。
10.接下来添加敌机,并且让它可以移动。我们在屏幕上方中间创建,建立动作让它们向下移动。
我们在HelloWorldScene.h头文件中添加函数声明void addMonster();
然后在HelloWorldScene.cpp中增加addMonster方法,代码如下:
void HelloWorld::addMonster() { CCSprite *monster = CCSprite::create("Monster1.png"); //使敌人敌机从上面出现时,左右显示是完整的,并在屏幕上方随机产生 //如果其他游戏敌人是Y轴出现,可以把以下的X统一改为Y即可 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); int minX = monster->getContentSize().width / 2; int maxX = winSize.width - monster->getContentSize().width / 2; int rangeX = maxX - minX; int actualX = (rand() % rangeX) + minX;//随机位置产生敌人 //设置敌机坐标 并显示出来 monster->setPosition(ccp(actualX,winSize.height + monster->getContentSize().height / 2)); this->addChild(monster); //使用随机函数控制飞机速度。改下面数字可以调整飞机速度,控制游戏难度,当然敌机、子弹的触碰区域大小等也会影响游戏难度。 int minDuration = 2.0; int maxDuration = 5.0; int rangeDuration = maxDuration - minDuration; int actualDuration = (rand() % rangeDuration) + minDuration; //控制敌机的结束坐标,即当整个飞机离开屏幕(注意默认锚点是图片的中心位置) CCMoveTo *actionMove = CCMoveTo::create(actualDuration, ccp(actualX,-monster->getContentSize().height / 2)); CCCallFuncN *actionMoveDone = CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)); monster->runAction(CCSequence::create(actionMove, actionMoveDone, NULL)); }
在屏幕上方以随机的位置添加敌机精灵,注意计算精灵X轴的位置坐标(因为默认描点在中心,不能让敌机截断只有一部分)。
然后通过随机函数控制的敌机运动总时间,让敌机从上方移动到下方,
移动到离开边界后,调用回调函数spriteMoveFinished,进行删除精灵对象。
这里调用的回调函数,我们尚未对其进行声明和定义。
下面我们先在HelloWorldScene.h头文件中添加函数声明void spriteMoveFinished(CCNode *sender);
然后在HelloWorldScene.cpp中增加函数spriteMoveFinished的定义,代码如下:
1 2 3 4 5 | void HelloWorld::spriteMoveFinished(CCNode *sender) //回调函数spriteMoveFinished,进行删除精灵对象 { CCSprite *sprite = (CCSprite*)sender; this->removeChild(sprite, true); } |
1 | this->schedule(schedule_selector(HelloWorld::gameLogic), 1.0); |
在HelloWorldScene.cpp中增加代码如下:
1 2 3 4 | void HelloWorld::gameLogic( float dt ) { this->addMonster(); } |
11.接着让玩家可以发射子弹。
当用户在屏幕点击时,就让玩家往点击的方向进行发射子弹。
用户的屏幕点击点并不是子弹移动的最终地,借用原文的一张图片来说明:
首先,我们用引擎的函数得到触摸点与子弹初始位置之差我们命名为(offset.x,offset.y)即上图的 (offx,offy)。用户的屏幕点击点并不是子弹移动的最终地,假设如果没有发生碰撞,子弹可以移动到屏幕的尽头直到子弹完全消失,我们将该点命名为(realX,realY)。
当用户点击屏幕后,我们创建子弹精灵,算出触摸点与子弹初始位置之差(offset.x,offset.y)。若触摸点(offset.y>0)在初始位置的上方(即玩家上方),则添加子弹到层上。以等比例原理方法,计算出子弹飞向屏幕上边的最终坐标。然后再用勾股定理计算飞行长度,假定速度为每秒480像素,则计算出飞行总时间。之后就是让子弹执行给定的飞行动作,以及之后的删除自身调用。
要让层可以支持触摸,需要在init方法里面添加如下代码:
1 | this->setTouchEnabled(true); |
然后重载ccTouchesEnded方法。在HelloWorldScene.h头文件中添加函数声明virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
在HelloWorldScene.cpp中添加代码如下:
void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) { CCTouch *touch = (CCTouch*)pTouches->anyObject(); CCPoint location = this->convertTouchToNodeSpace(touch); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCSprite *projectile = CCSprite::create("zd.png"); projectile->setPosition(ccp(winSize.width / 2, 50)); CCPoint offset = ccpSub(location, projectile->getPosition()); //关于子弹移动轨迹,主要是用了数学的勾股定理,平行线等分线段定理 CE:CB=DE:AB=CD:AC。 //若触摸点(offset.y>0)在初始位置的上方(即玩家上方),则添加子弹到层上. if (offset.y <= 0) { return; } this->addChild(projectile); CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("shoot.mp3"); int realY = winSize.height + projectile->getContentSize().height / 2; //这里是子弹的消失点,也是理解该段的重点,即子弹如果没有碰撞则会在屏幕的尽头消失。 float ratio = (float)offset.x/ (float)offset.y; //offset.x,offset.y是上面CCPoint offset = ccpSub(location, projectile->getPosition());电脑算出来的。 int realX = (realY - projectile->getPosition().y) * ratio + projectile->getPosition().x;//利用等比例原理算出了realY的位置。 //原文该行(realX - projectile->getPosition().x) 直接写成了realX 错误导致两侧的子弹会跟鼠标稍有偏差,但偏差不大不仔细看不出来。 CCPoint realDest = ccp(realX, realY);//算出了预计子弹的消失点 //通过子弹经过的路径长度,等比例地控制子弹的运行时间 int offRealX = realX - projectile->getPosition().x; int offRealY = realY - projectile->getPosition().y; float length = sqrtf(offRealX * offRealX + offRealY * offRealY); float velocity = 480 / 1;//修改480该数字可以调整子弹运行的快慢 float realMoveDuration = length / velocity; projectile->runAction(CCSequence::create(CCMoveTo::create(realMoveDuration, realDest), CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL)); //如果横板游戏子弹发射点是x轴左侧的,就用该段。 //if (offset.x <= 0) //{ // return; //} //this->addChild(projectile); //int realX = winSize.width + projectile->getContentSize().width / 2; //这里是子弹的消失点,也是理解该段的重点,即子弹如果没有碰撞则会在屏幕的尽头消失。 //float ratio = (float)offset.y / (float)offset.x;//offset.x,offset.y是上面CCPoint offset = ccpSub(location, projectile->getPosition());电脑算出来的。 //int realY = (realX - projectile->getPosition().x) * ratio + projectile->getPosition().y;//利用等比例原理算出了realY的位置。 ////原文该行(realX - projectile->getPosition().x) 直接写成了realX 错误 两侧的子弹会跟鼠标稍有偏差,偏差不大不仔细看不出来。 //CCPoint realDest = ccp(realX, realY);//算出了预计子弹的消失点 ////通过子弹经过的路径长度,等比例地控制子弹的运行时间 //int offRealX = realX - projectile->getPosition().x; //int offRealY = realY - projectile->getPosition().y; //float length = sqrtf(offRealX * offRealX + offRealY * offRealY); //float velocity = 480 / 1;//修改480该数字可以调整子弹运行的快慢 //float realMoveDuration = length / velocity; //projectile->runAction(CCSequence::create(CCMoveTo::create(realMoveDuration, realDest), //CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL)); }
编译运行,往屏幕点击,可以看到子弹发射出去。如下图所示。
10.当子弹碰到怪物时,怪物被消灭,子弹消失,实现这些我们需要用碰撞检测。需要在场景中跟踪目标和子弹,在HelloWorldScene.h声明如下:
void update(float dt);
cocos2d::CCArray *_monsters;
cocos2d::CCArray *_projectiles;
在HelloWorldScene.cpp构造函数和析构函数,添加如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | HelloWorld::HelloWorld() { _monsters = NULL; _projectiles = NULL; } HelloWorld::~HelloWorld() { if (_monsters) { _monsters->release(); _monsters = NULL; } if (_projectiles) { _projectiles->release(); _projectiles = NULL; } } |
1 2 3 4 | this->_monsters = CCArray::create(); this->_monsters->retain(); this->_projectiles = CCArray::create(); this->_projectiles->retain(); |
1 2 | monster->setTag(1); _monsters->addObject(monster); |
1 2 | projectile->setTag(2); _projectiles->addObject(projectile); |
1 2 3 4 5 6 7 8 | if (sprite->getTag() == 1) { _monsters->removeObject(sprite); } else if (sprite->getTag() == 2) { _projectiles->removeObject(sprite); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | void HelloWorld::update(float dt) { CCArray *projectilesToDelete = CCArray::create(); CCObject *pObject = NULL; CCObject *pObject2 = NULL; CCARRAY_FOREACH(_projectiles, pObject) { CCSprite *projectile = (CCSprite*)pObject; CCArray *monstersToDelete = CCArray::create(); CCARRAY_FOREACH(_monsters, pObject2) { CCSprite *monster = (CCSprite*)pObject2; if (CCRect::CCRectIntersectsRect(projectile->boundingBox(), monster->boundingBox())) { monstersToDelete->addObject(monster); } } CCARRAY_FOREACH(monstersToDelete, pObject2) { CCSprite *monster = (CCSprite*)pObject2; _monsters->removeObject(monster); this->removeChild(monster, true); } if (monstersToDelete->count() > 0) { projectilesToDelete->addObject(projectile); } monstersToDelete->release(); } CCARRAY_FOREACH(projectilesToDelete, pObject) { CCSprite *projectile = (CCSprite*)pObject; _projectiles->removeObject(projectile); this->removeChild(projectile, true); } projectilesToDelete->release(); } |
1 | this->schedule(schedule_selector(HelloWorld::update)); |
12.添加音效,在init函数添加背景音乐,代码如下:
1 | CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav"); |
1 | CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("shoot.mp3"); |
![](http://img.my.csdn.net/uploads/201212/07/1354854202_7483.png)
GameOverLayer.h文件代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #pragma once #include "cocos2d.h" class GameOverLayer : public cocos2d::CCLayerColor { public: GameOverLayer(void); ~GameOverLayer(void); bool initWithWon(bool won); static cocos2d::CCScene* sceneWithWon(bool won); static GameOverLayer* createWithWon(bool won); void gameOverDone(); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #include "GameOverLayer.h" #include "HelloWorldScene.h" using namespace cocos2d; GameOverLayer::GameOverLayer(void) { } GameOverLayer::~GameOverLayer(void) { } GameOverLayer* GameOverLayer::createWithWon(bool won) { GameOverLayer *pRet = new GameOverLayer(); if (pRet && pRet->initWithWon(won)) { pRet->autorelease(); return pRet; } else { CC_SAFE_DELETE(pRet); return NULL; } } bool GameOverLayer::initWithWon(bool won) { bool bRet = false; do { CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4(255, 255, 255, 255)));//设置屏幕为白色 char *message; if (won) { message = "You Won!";//显示你赢了 } else { message = "You Lose :[";//显示你输了 } CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create(message, "Arial", 32);//控制字体大小 label->setColor(ccc3(0, 0, 0));//控制字体颜色 label->setPosition(ccp(winSize.width / 2, winSize.height / 2));//设置坐标位置 this->addChild(label);//添加到屏幕 //场景上的层显示一个文本,在3秒之后调用gameOverDone函数从而返回到HelloWorld场景中 this->runAction(CCSequence::create(CCDelayTime::create(3), CCCallFunc::create(this, callfunc_selector(GameOverLayer::gameOverDone)), NULL)); bRet = true; } while (0); return bRet; } cocos2d::CCScene* GameOverLayer::sceneWithWon(bool won) { CCScene * scene = NULL; do { scene = CCScene::create(); CC_BREAK_IF(! scene); GameOverLayer *layer = GameOverLayer::createWithWon(won); CC_BREAK_IF(! layer); scene->addChild(layer); } while (0); return scene; } //gameOverDone()函数控制场景,跳转回到HelloWorld游戏场景 void GameOverLayer::gameOverDone() { CCDirector::sharedDirector()->replaceScene(HelloWorld::scene()); } |
14.最后,为游戏添加一些游戏逻辑。
我们将规则定位:当放走3个敌机后,则游戏结束。而如果游戏结束时,被消灭敌机数量超过30个,则判断为胜利,反之为失败。
记录玩家消灭怪物的数量,进而决定该玩家输赢。在HelloWorldScene.h文件中,添加如下:
1 | int _monstersDestroyed; |
1 | _monstersDestroyed = 0; |
1 | #include "GameOverLayer.h" |
1 2 3 4 5 6 | _monstersDestroyed++; //计算消灭的敌机数量 if (_monstersDestroyed > 30)//当放走3个敌机后游戏结束时,如果敌机数量超过30个,则判断为胜利,反之为失败。 { CCScene *gameOverScene = GameOverLayer::sceneWithWon(true); CCDirector::sharedDirector()->replaceScene(gameOverScene); } |
在HelloWorldScene.h文件中,添加如下:
int _life;
在HelloWorldScene.cpp文件中的spriteMoveFinished函数里,sprite->getTag() == 1条件的后面,添加如下:
//统计放跑敌机的数量,如果超过3个则游戏结束 _life++; if(_life>=3) { CCScene *gameOverScene = GameOverLayer::sceneWithWon(false); CCDirector::sharedDirector()->replaceScene(gameOverScene); }
最后编译并运行,即可看到游戏。到此已完成了一个简单的游戏,包含音效,并带有胜利和失败的结束。
本例子源代码附加资源下载地址:http://download.csdn.net/detail/u013174689/6826063
可以运行压缩文件夹Star Fighter源码\Debug.win32里的exe文件运行查看游戏效果。
如文章存在错误之处,欢迎指出,以便改正。
相关文章推荐
- cocos2d x 入门学习(二)Star Fighter项目交叉编译时遇到的问题
- 基于Dreamweaver的网页制作学习1----简单入门
- 实例学习SSIS(一)--制作一个简单的ETL包
- activiti学习笔记 最简单入门实例
- 三大框架学习:Struts2简单入门(通过一个简单的登陆实例详解)
- 【Unity 3D】学习笔记二十九:游戏实例——简单小地图制作
- dubbo学习(1)--简单的入门搭建实例
- salesforce 零基础开发入门学习(八)数据分页简单制作
- Spring框架的学习(零)-简单介绍与入门实例
- cocos2d-x学习(4)---游戏实例开发:一个简单的射击游戏三
- JSTL简单入门学习实例
- dialplan 学习之简单入门实例
- cocos2d-x学习(2)---游戏实例开发:一个简单的射击游戏一
- 实例学习SSIS(一)--制作一个简单的ETL包
- 一个简单的jQuery插件制作,学习过程及实例
- SiteMesh 2学习(1):入门简介和简单实例
- Ant学习--简单实例入门
- 【Spring学习03】Spring简单入门实例
- spring Boot学习入门篇-idea开发简单的hello world实例
- cocos2d x 入门学习(三)如何制作一个塔防游戏 Cocos2d-x 2.0.4