您的位置:首页 > 移动开发 > Cocos引擎

【cocos2d-x】如何使用Cocos2D-x制作一款简单的iphone&Android游戏①

2012-09-26 16:06 756 查看
写了几章教程 准备先写几个例子和游戏玩玩 这几天博客更新比较慢 主要公司项目紧

本例子从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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  游戏 cocos 2dx
相关文章推荐