写了几章教程  准备先写几个例子和游戏玩玩   这几天博客更新比较慢  主要公司项目紧

  本例子从cocos2d的例子中翻译过来 经过本人重新编写测试运行之后发出,如果有c++语法问题,请指正谢谢

 例子效果:  主角在屏幕左侧   敌人从屏幕右侧向左侧奔跑  主角用飞镖可以将敌人杀死

本文用到的图片素材 :点我下载


第一步  新建一个MainScene类 由于是一个简单例子  所以 代码都在这个类中.

先把初始化的内容写好  比如说  init()方法   创建CCScene的方法

 
  
  1. /* 
  2.  * MainScene.h 
  3.  * 
  4.  *  Created on: 2012-9-26 
  5.  *      Author: Panda 
  6.  */ 
  7.  
  8. #ifndef MAINSCENE_H_ 
  9. #define MAINSCENE_H_ 
  10. #include "cocos2d.h" 
  11.  
  12. USING_NS_CC; 
  13.  
  14. class MainScene: public CCLayer { 
  15. public
  16.     MainScene(); 
  17.     virtual ~MainScene(); 
  18.  
  19.     static CCScene *scene(); 
  20.     virtual bool init(); 
  21. }; 
  22.  
  23. #endif /* MAINSCENE_H_ */ 
 
  
  1. /* 
  2.  * MainScene.cpp 
  3.  * 
  4.  *  Created on: 2012-9-26 
  5.  *      Author: Panda 
  6.  */ 
  7.  
  8. #include "MainScene.h" 
  9.  
  10. MainScene::MainScene() { 
  11.     // TODO Auto-generated constructor stub 
  12.  
  13.  
  14. MainScene::~MainScene() { 
  15.     // TODO Auto-generated destructor stub 
  16.  
  17. CCScene *MainScene::scene() { 
  18.     CCScene *pScene = NULL; 
  19.     do { 
  20.         pScene = CCScene::create(); 
  21.         pScene->addChild(MainScene::create()); 
  22.     } while (0); 
  23.     return pScene; 
  24.  
  25. bool MainScene::init() { 
  26.     bool bRet = false
  27.     do { 
  28.         bRet = true
  29.     } while (0); 
  30.     return bRet; 

运行  可以看到界面已经生成  不过是黑色背景  接下来  我们需要把背景变成灰白色 

很简单  添加以下代码,为什么要-999呢?   主要是为了保证bgColor在最底层 

 
  
  1. //添加背景层 
  2.         CCLayerColor *bgColor = CCLayerColor::create(ccc4(189, 189, 189, 255)); 
  3.         this->addChild(bgColor, -999); 

完成了这个之后 就要在界面上将游戏的主角放到屏幕上。

我们把主角放到屏幕最左边的中间, 代码很简单  不了解的可以留言询问

 
  
  1. //添加主角 
  2.         CCSprite *pSprite = CCSprite::create("Player.png"); 
  3.         pSprite->setPosition(CCPointMake(pSprite->getContentSize().width / 2, 
  4.                 size.height / 2)); 
  5.         this->addChild(pSprite, 0); 

 运行程序之后  可以看到在屏幕的最左侧有一个人物  到这里  我们就完成了第一步  接下来  我们要进行第二部了

一个游戏  有主角  那就会有敌人 所以  我们要实现在屏幕上生成一些敌人 还要让他们移动  由于这是一个很简单的例子  所以  我们要不停的生成敌人  让他从屏幕的最右侧移动到最左侧

我们添加一个方法  用来添加一个敌人 

 
  
  1. void addTarget(); 
 
  
  1. void MainScene::addTarget() { 
  2.     CCSize size = CCDirector::sharedDirector()->getWinSize(); 
  3.  
  4.     CCSprite *pTarget = CCSprite::create("Target.png"); 
  5.     int minY = pTarget->getContentSize().height / 2; 
  6.     int maxY = size.height - pTarget->getContentSize().height / 2; 
  7.     int rangeY = maxY - minY; 
  8.     //获取minY到rangeY之间的整数 
  9.     int actualY = (arc4random() % rangeY) + minY; 
  10.  
  11.     pTarget->setPosition( 
  12.             CCPointMake(size.width-pTarget->getContentSize().width/2,actualY)); 
  13.  
  14.     this->addChild(pTarget, 0); 
  15.  
  16.     int minDuration = 2; 
  17.     int maxDuration = 4; 
  18.     int rangeDuration = maxDuration - minDuration; 
  19.     int actualDuration = (arc4random() % rangeDuration) + minDuration; 
  20.  
  21.     //移动 
  22.     //参数1 移动时间 
  23.     //参数2 移动到的坐标点 
  24.     CCActionInterval *move = CCMoveTo::create(actualDuration, 
  25.             CCPointMake(-pTarget->getContentSize().width/2,actualY)); 
  26.     //CCCallFuncN 有发送者无数据回调 
  27.     CCCallFuncN *moveDone = CCCallFuncN::create(this
  28.             callfuncN_selector(MainScene:: spriteMoveFinished )); 
  29.     pTarget->runAction(CCSequence::create(move, moveDone, NULL)); 

完成代码的编写   代码有点多  接下来我们来慢慢讲解

4-9行是在y轴上随机生成一个数字 由于锚点是精灵的中心  所以在计算的时候要相应的处理下  比如最小的Y值是精灵高度的一半,最大值是屏幕高减去精灵高度的一半 (ps:语文不怎么好,表达能力有限) 

第9行的arc4random 函数 我们来讲解下

 
  
  1. //通过arc4random() 获取0到x-1之间的整数的代码如下:  
  2. int value = arc4random() % x;   
  3.   
  4. //获取1到x之间的整数的代码如下:  
  5. int value = (arc4random() % x) + 1; 

这么一解释  代码很容易看懂了吧

11行将敌人的初始位置放置在屏幕最右侧 x轴固定 y轴就是随机生成的位置

16-20行的作用是生成一个随机数  用于运行动作(action)的时间  就是从屏幕最左边到最右边所花的时间  代码和上面一样  不解释

24-29行是创建一个动作  让敌人从移动到最左侧  所以  我们使用到了MoveTo,create的第一个参数是指移动到坐标所需的时候   第二个参数是移动到的目的地 ,27行是函数回调  我们来看下回调spriteMoveFinished 的内容,当动作结束之后 我们需要将敌人移除 因为我们再也不需要这个敌人对象  

 
  
  1. void MainScene::spriteMoveFinished(CCSprite *sprite) { 
  2.     this->removeChild(sprite, true); 

现在 我们需要每隔一秒刷新一个靶子 怎么实现呢?通过每隔一段时间就会被调用的schedule(调度)回调函数,就能完成这个目标。

 
  
  1. this->schedule(schedule_selector(MainScene::gameLogic), 1.0); 

接下来在回调函数里填入如下内容:

 
  
  1. void MainScene::gameLogic(ccTime time) { 
  2.     addTarget(); 

 运行程序  我们的敌人就会从右边移动到左边


 接下来  我们需要让我们的主角可以发射飞镖  

首先 我们要在init方法中添加以下代码  响应触屏事件

 
  
  1. this->setTouchEnabled(true); 

 然后重写以下三个方法

 
  
  1. virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); 
  2. virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); 
  3. virtual void registerWithTouchDispatcher(); 

先设置优先级

 
  
  1. void MainScene::registerWithTouchDispatcher() { 
  2.     CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate( 
  3.             this, -1, true); 

然后让ccTouchBegan返回true 这样就能响应ccTouchEnded方法

 
  
  1. bool MainScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { 
  2.     return true

完成这些  我们就可以在ccTouchEnded中开始写我们的代码

 
  
  1. void MainScene::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) { 
  2.     CCSize size = CCDirector::sharedDirector()->getWinSize(); 
  3.     CCPoint touchPoint = pTouch->getLocationInView(); 
  4.  
  5.     //convertToGL  转换成opengl坐标啊,(0,0)在左下方 
  6.     touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); 
  7.  
  8.     //初始化飞镖的坐标 
  9.     CCSprite *Projectile = CCSprite::create("Projectile.png"); 
  10.     Projectile->setPosition( 
  11.             CCPointMake(Projectile->getContentSize().width,size.height/2)); 
  12.  
  13.     this->addChild(Projectile, 0); 
  14.  
  15.  
  16.     int rightX = size.width + Projectile->getContentSize().width / 2; 
  17.     int rightY = rightX * (touchPoint.y - size.height / 2) / touchPoint.x 
  18.             + size.height / 2; 
  19.  
  20.     CCActionInterval *move = CCMoveTo::create(2.0, CCPointMake(rightX,rightY)); 
  21.     CCCallFuncN *moveDone = CCCallFuncN::create(this
  22.             callfuncN_selector(MainScene::spriteMoveFinished)); 
  23.     Projectile->runAction(CCSequence::create(move, moveDone, NULL)); 

第三行:获取触摸点的坐标~

第六行:由于获取的触摸点是以左上角为原点的  左右需要转换为以左下角为原点的坐标

9-13行:创建一个飞镖精灵 将飞镖的坐标初始化位置设为主角的位置

16-17行:我们通过触摸点的位置  计算出飞镖会移动到屏幕右侧外边的坐标点 看图 相信你会理解的

20-23行:我觉得不需要解释了  和敌人移动是一模一样的

好的  我们来运行一下游戏   然后去点击屏幕  是不是看到发射飞镖了? 

但是 当飞镖碰到敌人的时候  敌人并没有消失?  接下来 我们就要使用碰撞检测  实现击中敌人的效果


 首先,我们需要记录所有在当前场景里的靶子和飞镖对象。在MainScene类的声明中加入:

 
  
  1. CCArray *array_Targets, *array_Projectiles; 

并在init方法里加入初始化数组的代码:

 
  
  1. /*--注意:如果要想让生成的CCArray长久有效,就得调一次retain操作,在不需要的时候调release*/ 
  2.         array_Targets = CCArray::create(); 
  3.         array_Targets->retain(); 
  4.         array_Projectiles = CCArray::create(); 
  5.         array_Projectiles->retain(); 

现在,修改addTarget方法,在靶子数组中加入一个新靶子并设置其标识(tag)留待后用,我们在方法最后添加下面代码

 
  
  1. pTarget->setTag(1); 
  2. array_Targets->addObject(pTarget); 

同样的,把在ccTouchesEnded里新建的飞镖加入到飞镖数组中并设置tag留待后用:

 
  
  1. Projectile->setTag(2); 
  2. array_Projectiles->addObject(Projectile); 

最后,修改spriteMoveFinished方法,根据tag分类把即将删除的对象从数组中也移除掉:

 
  
  1. void MainScene::spriteMoveFinished(CCSprite *sprite) { 
  2.     switch (sprite->getTag()) { 
  3.     case 1: 
  4.         CCLog("spriteMoveFinished---1"); 
  5.         array_Targets->removeObject(sprite, true); 
  6.         break
  7.     case 2: 
  8.         CCLog("spriteMoveFinished---2"); 
  9.         array_Projectiles->removeObject(sprite, true); 
  10.         break
  11.     default
  12.         break
  13.     } 
  14.     this->removeChild(sprite, true); 
  15.  

编译并运行,确保到目前为止一切都OK。虽然目前还看不到什么显著的变化,但我们已经有了做碰撞检测的基础了。

 添加一下方法到MainScene中

 
  
  1. void MainScene::updateFrame(ccTime time) { 
  2.     CCArray *array_projectilesToDelete = CCArray::create(); 
  3.     array_projectilesToDelete->retain(); 
  4.  
  5.     for (int i = 0; i < array_Projectiles->count(); i++) { 
  6.         CCSprite *Projectile = (CCSprite*) (array_Projectiles->objectAtIndex(i)); 
  7.  
  8.         CCArray *array_targetsToDelete = CCArray::create(); 
  9.         array_targetsToDelete->retain(); 
  10.  
  11.         for (int j = 0; j < array_Targets->count(); j++) { 
  12.             CCSprite *Target = (CCSprite*) (array_Targets->objectAtIndex(j)); 
  13.             if (Projectile->boundingBox().intersectsRect( 
  14.                     Target->boundingBox())) { 
  15.                 array_targetsToDelete->addObject(Target); 
  16.             } 
  17.         } 
  18.  
  19.         for (int j = 0; j < array_targetsToDelete->count(); j++) { 
  20.             CCSprite *Target = 
  21.                     (CCSprite*) (array_targetsToDelete->objectAtIndex(j)); 
  22.             array_Targets->removeObject(Target); 
  23.             this->removeChild(Target, true); 
  24.         } 
  25.         if (array_targetsToDelete->count() > 0) { 
  26.             array_projectilesToDelete->addObject(Projectile); 
  27.         } 
  28.         array_targetsToDelete->release(); 
  29.     } 
  30.  
  31.     for (int i = 0; i < array_projectilesToDelete->count(); i++) { 
  32.         CCSprite *Projectile = 
  33.                 (CCSprite*) (array_projectilesToDelete->objectAtIndex(i)); 
  34.         array_Projectiles->removeObject(Projectile); 
  35.         this->removeChild(Projectile, true); 
  36.     } 
  37.     array_projectilesToDelete->release(); 

代码看上去很多  但是不难   主要就是遍历敌人和飞镖  检测是否碰撞了 如果碰撞 就移除,注意我们必须将这些对象加入到“toDelete”结尾的数组中,因为我们没法在当前循环中从数组中删掉它 

13行 a.intersectsRect(b) :判断两个矩形是否碰撞 如果碰撞 返回true

在相应的位置需要对CCArray对象加上release()进行清理

我们需要在每一帧都执行这个方法  所以在init方法的最后添加以下代码:

 
  
  1. this->schedule(schedule_selector(MainScene::updateFrame)); 

好了 至此  一个简单的游戏已经完成了   感觉很简单吧? 是不是觉得少了什么呢?  对的   一个游戏  肯定会有音乐的   现在  我们在游戏中添加音乐

例子中用到的音乐:点我下载

导入头文件:

 
  
  1. #include "SimpleAudioEngine.h" 

在init方法中,如下所示播放背景音乐:

 
  
  1. CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav",true); 

在ccTouchEnded方法中播放音效:

 
  
  1. CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav",false); 

运行   音乐出来了 

-------

感觉差不多了吧?   明天看看有没有什么需要讲的   如果差不多了 就准备讲解下tmx地图了

本章×××:点我下载


 

接下来一章将讲解tmx地图,如有问题,请提出

本教程根据Cocos2d教程翻译过来

使用的cocos2d-x版本为2.02