【cocos2d-x】如何使用Cocos2D-x制作一款简单的iphone&Android游戏①
2012-09-26 16:06
756 查看
写了几章教程 准备先写几个例子和游戏玩玩 这几天博客更新比较慢 主要公司项目紧
本例子从cocos2d的例子中翻译过来 经过本人重新编写测试运行之后发出,如果有c++语法问题,请指正谢谢
本文用到的图片素材 :点我下载
第一步 新建一个MainScene类 由于是一个简单例子 所以 代码都在这个类中.
先把初始化的内容写好 比如说 init()方法 创建CCScene的方法
运行 可以看到界面已经生成 不过是黑色背景 接下来 我们需要把背景变成灰白色
很简单 添加以下代码,为什么要-999呢? 主要是为了保证bgColor在最底层
完成了这个之后 就要在界面上将游戏的主角放到屏幕上。
我们把主角放到屏幕最左边的中间, 代码很简单 不了解的可以留言询问
运行程序之后 可以看到在屏幕的最左侧有一个人物 到这里 我们就完成了第一步 接下来 我们要进行第二部了
一个游戏 有主角 那就会有敌人 所以 我们要实现在屏幕上生成一些敌人 还要让他们移动 由于这是一个很简单的例子 所以 我们要不停的生成敌人 让他从屏幕的最右侧移动到最左侧
我们添加一个方法 用来添加一个敌人
完成代码的编写 代码有点多 接下来我们来慢慢讲解
4-9行是在y轴上随机生成一个数字 由于锚点是精灵的中心 所以在计算的时候要相应的处理下 比如最小的Y值是精灵高度的一半,最大值是屏幕高减去精灵高度的一半 (ps:语文不怎么好,表达能力有限)
第9行的arc4random 函数 我们来讲解下
这么一解释 代码很容易看懂了吧
第11行将敌人的初始位置放置在屏幕最右侧 x轴固定 y轴就是随机生成的位置
16-20行的作用是生成一个随机数 用于运行动作(action)的时间 就是从屏幕最左边到最右边所花的时间 代码和上面一样 不解释
24-29行是创建一个动作 让敌人从移动到最左侧 所以 我们使用到了MoveTo,create的第一个参数是指移动到坐标所需的时候 第二个参数是移动到的目的地 ,27行是函数回调 我们来看下回调spriteMoveFinished 的内容,当动作结束之后 我们需要将敌人移除 因为我们再也不需要这个敌人对象
现在 我们需要每隔一秒刷新一个靶子 怎么实现呢?通过每隔一段时间就会被调用的schedule(调度)回调函数,就能完成这个目标。
接下来在回调函数里填入如下内容:
运行程序 我们的敌人就会从右边移动到左边
接下来 我们需要让我们的主角可以发射飞镖
首先 我们要在init方法中添加以下代码 响应触屏事件
然后重写以下三个方法
先设置优先级
然后让ccTouchBegan返回true 这样就能响应ccTouchEnded方法
完成这些 我们就可以在ccTouchEnded中开始写我们的代码
第三行:获取触摸点的坐标~
第六行:由于获取的触摸点是以左上角为原点的 左右需要转换为以左下角为原点的坐标
9-13行:创建一个飞镖精灵 将飞镖的坐标初始化位置设为主角的位置
16-17行:我们通过触摸点的位置 计算出飞镖会移动到屏幕右侧外边的坐标点 看图 相信你会理解的
20-23行:我觉得不需要解释了 和敌人移动是一模一样的
好的 我们来运行一下游戏 然后去点击屏幕 是不是看到发射飞镖了?
但是 当飞镖碰到敌人的时候 敌人并没有消失? 接下来 我们就要使用碰撞检测 实现击中敌人的效果
首先,我们需要记录所有在当前场景里的靶子和飞镖对象。在MainScene类的声明中加入:
并在init方法里加入初始化数组的代码:
现在,修改addTarget方法,在靶子数组中加入一个新靶子并设置其标识(tag)留待后用,我们在方法最后添加下面代码
同样的,把在ccTouchesEnded里新建的飞镖加入到飞镖数组中并设置tag留待后用:
最后,修改spriteMoveFinished方法,根据tag分类把即将删除的对象从数组中也移除掉:
编译并运行,确保到目前为止一切都OK。虽然目前还看不到什么显著的变化,但我们已经有了做碰撞检测的基础了。
添加一下方法到MainScene中
代码看上去很多 但是不难 主要就是遍历敌人和飞镖 检测是否碰撞了 如果碰撞 就移除,注意我们必须将这些对象加入到“toDelete”结尾的数组中,因为我们没法在当前循环中从数组中删掉它
13行 a.intersectsRect(b) :判断两个矩形是否碰撞 如果碰撞 返回true
在相应的位置需要对CCArray对象加上release()进行清理
我们需要在每一帧都执行这个方法 所以在init方法的最后添加以下代码:
好了 至此 一个简单的游戏已经完成了 感觉很简单吧? 是不是觉得少了什么呢? 对的 一个游戏 肯定会有音乐的 现在 我们在游戏中添加音乐
例子中用到的音乐:点我下载
导入头文件:
在init方法中,如下所示播放背景音乐:
在ccTouchEnded方法中播放音效:
运行 音乐出来了
-------
感觉差不多了吧? 明天看看有没有什么需要讲的 如果差不多了 就准备讲解下tmx地图了
本章源码下载:点我下载
接下来一章将讲解tmx地图,如有问题,请提出
本教程根据Cocos2d教程翻译过来
使用的cocos2d-x版本为2.02
本例子从cocos2d的例子中翻译过来 经过本人重新编写测试运行之后发出,如果有c++语法问题,请指正谢谢
例子效果: 主角在屏幕左侧 敌人从屏幕右侧向左侧奔跑 主角用飞镖可以将敌人杀死 |
第一步 新建一个MainScene类 由于是一个简单例子 所以 代码都在这个类中.
先把初始化的内容写好 比如说 init()方法 创建CCScene的方法
/* * MainScene.h * * Created on: 2012-9-26 * Author: Panda */ #ifndef MAINSCENE_H_ #define MAINSCENE_H_ #include "cocos2d.h" USING_NS_CC; class MainScene: public CCLayer { public: MainScene(); virtual ~MainScene(); static CCScene *scene(); virtual bool init(); }; #endif /* MAINSCENE_H_ */
/* * MainScene.cpp * * Created on: 2012-9-26 * Author: Panda */ #include "MainScene.h" MainScene::MainScene() { // TODO Auto-generated constructor stub } MainScene::~MainScene() { // TODO Auto-generated destructor stub } CCScene *MainScene::scene() { CCScene *pScene = NULL; do { pScene = CCScene::create(); pScene->addChild(MainScene::create()); } while (0); return pScene; } bool MainScene::init() { bool bRet = false; do { bRet = true; } while (0); return bRet; }
运行 可以看到界面已经生成 不过是黑色背景 接下来 我们需要把背景变成灰白色
很简单 添加以下代码,为什么要-999呢? 主要是为了保证bgColor在最底层
//添加背景层 CCLayerColor *bgColor = CCLayerColor::create(ccc4(189, 189, 189, 255)); this->addChild(bgColor, -999);
完成了这个之后 就要在界面上将游戏的主角放到屏幕上。
我们把主角放到屏幕最左边的中间, 代码很简单 不了解的可以留言询问
//添加主角 CCSprite *pSprite = CCSprite::create("Player.png"); pSprite->setPosition(CCPointMake(pSprite->getContentSize().width / 2, size.height / 2)); this->addChild(pSprite, 0);
运行程序之后 可以看到在屏幕的最左侧有一个人物 到这里 我们就完成了第一步 接下来 我们要进行第二部了
一个游戏 有主角 那就会有敌人 所以 我们要实现在屏幕上生成一些敌人 还要让他们移动 由于这是一个很简单的例子 所以 我们要不停的生成敌人 让他从屏幕的最右侧移动到最左侧
我们添加一个方法 用来添加一个敌人
void addTarget();
void MainScene::addTarget() { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCSprite *pTarget = CCSprite::create("Target.png"); int minY = pTarget->getContentSize().height / 2; int maxY = size.height - pTarget->getContentSize().height / 2; int rangeY = maxY - minY; //获取minY到rangeY之间的整数 int actualY = (arc4random() % rangeY) + minY; pTarget->setPosition( CCPointMake(size.width-pTarget->getContentSize().width/2,actualY)); this->addChild(pTarget, 0); int minDuration = 2; int maxDuration = 4; int rangeDuration = maxDuration - minDuration; int actualDuration = (arc4random() % rangeDuration) + minDuration; //移动 //参数1 移动时间 //参数2 移动到的坐标点 CCActionInterval *move = CCMoveTo::create(actualDuration, CCPointMake(-pTarget->getContentSize().width/2,actualY)); //CCCallFuncN 有发送者无数据回调 CCCallFuncN *moveDone = CCCallFuncN::create(this, callfuncN_selector(MainScene:: spriteMoveFinished )); pTarget->runAction(CCSequence::create(move, moveDone, NULL)); }
完成代码的编写 代码有点多 接下来我们来慢慢讲解
4-9行是在y轴上随机生成一个数字 由于锚点是精灵的中心 所以在计算的时候要相应的处理下 比如最小的Y值是精灵高度的一半,最大值是屏幕高减去精灵高度的一半 (ps:语文不怎么好,表达能力有限)
第9行的arc4random 函数 我们来讲解下
//通过arc4random() 获取0到x-1之间的整数的代码如下: int value = arc4random() % x; //获取1到x之间的整数的代码如下: int value = (arc4random() % x) + 1;
这么一解释 代码很容易看懂了吧
第11行将敌人的初始位置放置在屏幕最右侧 x轴固定 y轴就是随机生成的位置
16-20行的作用是生成一个随机数 用于运行动作(action)的时间 就是从屏幕最左边到最右边所花的时间 代码和上面一样 不解释
24-29行是创建一个动作 让敌人从移动到最左侧 所以 我们使用到了MoveTo,create的第一个参数是指移动到坐标所需的时候 第二个参数是移动到的目的地 ,27行是函数回调 我们来看下回调spriteMoveFinished 的内容,当动作结束之后 我们需要将敌人移除 因为我们再也不需要这个敌人对象
void MainScene::spriteMoveFinished(CCSprite *sprite) { this->removeChild(sprite, true); }
现在 我们需要每隔一秒刷新一个靶子 怎么实现呢?通过每隔一段时间就会被调用的schedule(调度)回调函数,就能完成这个目标。
this->schedule(schedule_selector(MainScene::gameLogic), 1.0);
接下来在回调函数里填入如下内容:
void MainScene::gameLogic(ccTime time) { addTarget(); }
运行程序 我们的敌人就会从右边移动到左边
接下来 我们需要让我们的主角可以发射飞镖
首先 我们要在init方法中添加以下代码 响应触屏事件
this->setTouchEnabled(true);
然后重写以下三个方法
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual void registerWithTouchDispatcher();
先设置优先级
void MainScene::registerWithTouchDispatcher() { CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate( this, -1, true); }
然后让ccTouchBegan返回true 这样就能响应ccTouchEnded方法
bool MainScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { return true; }
完成这些 我们就可以在ccTouchEnded中开始写我们的代码
void MainScene::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCPoint touchPoint = pTouch->getLocationInView(); //convertToGL 转换成opengl坐标啊,(0,0)在左下方 touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); //初始化飞镖的坐标 CCSprite *Projectile = CCSprite::create("Projectile.png"); Projectile->setPosition( CCPointMake(Projectile->getContentSize().width,size.height/2)); this->addChild(Projectile, 0); int rightX = size.width + Projectile->getContentSize().width / 2; int rightY = rightX * (touchPoint.y - size.height / 2) / touchPoint.x + size.height / 2; CCActionInterval *move = CCMoveTo::create(2.0, CCPointMake(rightX,rightY)); CCCallFuncN *moveDone = CCCallFuncN::create(this, callfuncN_selector(MainScene::spriteMoveFinished)); Projectile->runAction(CCSequence::create(move, moveDone, NULL)); }
第三行:获取触摸点的坐标~
第六行:由于获取的触摸点是以左上角为原点的 左右需要转换为以左下角为原点的坐标
9-13行:创建一个飞镖精灵 将飞镖的坐标初始化位置设为主角的位置
16-17行:我们通过触摸点的位置 计算出飞镖会移动到屏幕右侧外边的坐标点 看图 相信你会理解的
20-23行:我觉得不需要解释了 和敌人移动是一模一样的
好的 我们来运行一下游戏 然后去点击屏幕 是不是看到发射飞镖了?
但是 当飞镖碰到敌人的时候 敌人并没有消失? 接下来 我们就要使用碰撞检测 实现击中敌人的效果
首先,我们需要记录所有在当前场景里的靶子和飞镖对象。在MainScene类的声明中加入:
CCArray *array_Targets, *array_Projectiles;
并在init方法里加入初始化数组的代码:
/*--注意:如果要想让生成的CCArray长久有效,就得调一次retain操作,在不需要的时候调release*/ array_Targets = CCArray::create(); array_Targets->retain(); array_Projectiles = CCArray::create(); array_Projectiles->retain();
现在,修改addTarget方法,在靶子数组中加入一个新靶子并设置其标识(tag)留待后用,我们在方法最后添加下面代码
pTarget->setTag(1); array_Targets->addObject(pTarget);
同样的,把在ccTouchesEnded里新建的飞镖加入到飞镖数组中并设置tag留待后用:
Projectile->setTag(2); array_Projectiles->addObject(Projectile);
最后,修改spriteMoveFinished方法,根据tag分类把即将删除的对象从数组中也移除掉:
void MainScene::spriteMoveFinished(CCSprite *sprite) { switch (sprite->getTag()) { case 1: CCLog("spriteMoveFinished---1"); array_Targets->removeObject(sprite, true); break; case 2: CCLog("spriteMoveFinished---2"); array_Projectiles->removeObject(sprite, true); break; default: break; } this->removeChild(sprite, true); }
编译并运行,确保到目前为止一切都OK。虽然目前还看不到什么显著的变化,但我们已经有了做碰撞检测的基础了。
添加一下方法到MainScene中
void MainScene::updateFrame(ccTime time) { CCArray *array_projectilesToDelete = CCArray::create(); array_projectilesToDelete->retain(); for (int i = 0; i < array_Projectiles->count(); i++) { CCSprite *Projectile = (CCSprite*) (array_Projectiles->objectAtIndex(i)); CCArray *array_targetsToDelete = CCArray::create(); array_targetsToDelete->retain(); for (int j = 0; j < array_Targets->count(); j++) { CCSprite *Target = (CCSprite*) (array_Targets->objectAtIndex(j)); if (Projectile->boundingBox().intersectsRect( Target->boundingBox())) { array_targetsToDelete->addObject(Target); } } for (int j = 0; j < array_targetsToDelete->count(); j++) { CCSprite *Target = (CCSprite*) (array_targetsToDelete->objectAtIndex(j)); array_Targets->removeObject(Target); this->removeChild(Target, true); } if (array_targetsToDelete->count() > 0) { array_projectilesToDelete->addObject(Projectile); } array_targetsToDelete->release(); } for (int i = 0; i < array_projectilesToDelete->count(); i++) { CCSprite *Projectile = (CCSprite*) (array_projectilesToDelete->objectAtIndex(i)); array_Projectiles->removeObject(Projectile); this->removeChild(Projectile, true); } array_projectilesToDelete->release(); }
代码看上去很多 但是不难 主要就是遍历敌人和飞镖 检测是否碰撞了 如果碰撞 就移除,注意我们必须将这些对象加入到“toDelete”结尾的数组中,因为我们没法在当前循环中从数组中删掉它
13行 a.intersectsRect(b) :判断两个矩形是否碰撞 如果碰撞 返回true
在相应的位置需要对CCArray对象加上release()进行清理
我们需要在每一帧都执行这个方法 所以在init方法的最后添加以下代码:
this->schedule(schedule_selector(MainScene::updateFrame));
好了 至此 一个简单的游戏已经完成了 感觉很简单吧? 是不是觉得少了什么呢? 对的 一个游戏 肯定会有音乐的 现在 我们在游戏中添加音乐
例子中用到的音乐:点我下载
导入头文件:
#include "SimpleAudioEngine.h"
在init方法中,如下所示播放背景音乐:
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav",true);
在ccTouchEnded方法中播放音效:
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav",false);
运行 音乐出来了
-------
感觉差不多了吧? 明天看看有没有什么需要讲的 如果差不多了 就准备讲解下tmx地图了
本章源码下载:点我下载
接下来一章将讲解tmx地图,如有问题,请提出
本教程根据Cocos2d教程翻译过来
使用的cocos2d-x版本为2.02
相关文章推荐
- 【cocos2d-x】如何使用Cocos2D-x制作一款简单的iphone&Android游戏②
- 【Cocos2D游戏引擎教程】如何使用Cocos2D制作一款简单的iPhone游戏(第二部分)
- 如何用cocos2d-x3.0制作一款简单的游戏:第二部分(旋转炮塔)
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏
- 如何用cocos2d-x3.0制作一款简单的游戏:第三部分(更猛的怪物和更多的关卡)
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第1部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第2部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第3部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏
- 如何使用Cocos2D制作一款基于tile的游戏
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第1部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第1部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第2部分
- 如何使用Cocos2D制作一款简单的iphone游戏
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第3部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第2部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第2部分
- 如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第3部分
- (译)如何使用cocos2d制作基于tile地图的游戏教程:第一部分
- 如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第一部分