如何制作一个简单的游戏 Cocos2d-x 2.0.4

      本文实践自 Ray Wenderlich 的文章《 How To Make A Simple iPhone Game with Cocos2D 2.X Tutorial》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.0.4进行学习和移植,前者是用Object-C所写,所以移植到Cocos2D-x会有些差异,比如某些函数、某些功能不能跟原文一样直接实现,需另转换方法实现。之前已经对Cocos2D-x的安装以及简单使用进行了介绍,这里不再介绍,直接进入主题。
 
步骤如下:
1.新建Cocos2d-win32工程,工程名为" SimpleGame",去除" Box2D"选项,勾选" Simple Audio Engine in Cocos Denshion"选项;
2.编译运行,可以看到如下图所示:

3.下载本游戏所需的资源,将资源放置" Resources"目录下;

4.游戏需要一个白色的背景,最简单的方法是使用CCLayerColor,将 HelloWorldScene.h文件"HelloWorld"类改为如下: 
1
class HelloWorld :  public cocos2d::CCLayerColor
首先添加玩家,让玩家位于左边屏幕中间,将 HelloWorldScene.cpp文件的 init函数,改为如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool HelloWorld::init()
{
     bool bRet =  false;
     do 
    {
        CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4( 255255255255)));

        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
        CCSprite *player = CCSprite::create( "player.png", CCRectMake( 002740));
        player->setPosition(ccp(player->getContentSize().width /  2, winSize.height /  2));
         this->addChild(player);   

        bRet =  true;
    }  while ( 0);

     return bRet;
}
5.编译运行,可以看到玩家精灵在白色背景上,如下图所示:

6.接下来添加怪物,并且让怪物可以移动,我们在屏幕右边创建怪物,建立动作让它们向左移动,增加 addMonster方法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void HelloWorld::addMonster()
{
    CCSprite *monster = CCSprite::create( "monster.png");

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
     int minY = monster->getContentSize().height /  2;
     int maxY = winSize.height - monster->getContentSize().height /  2;
     int rangeY = maxY - minY;
     int actualY = (rand() % rangeY) + minY;

    monster->setPosition(ccp(winSize.width + monster->getContentSize().width /  2, actualY));
     this->addChild(monster);

     int minDuration =  2. 0;
     int maxDuration =  4. 0;
     int rangeDuration = maxDuration - minDuration;
     int actualDuration = (rand() % rangeDuration) + minDuration;

    CCMoveTo *actionMove = CCMoveTo::create(actualDuration, ccp(-monster->getContentSize().width /  2, actualY));
    CCCallFuncN *actionMoveDone = CCCallFuncN::create( this, callfuncN_selector(HelloWorld::spriteMoveFinished));
    monster->runAction(CCSequence::create(actionMove, actionMoveDone,  NULL));
}

在右边屏幕以随机的位置添加怪物精灵,注意计算精灵的位置坐标,默认描点在中心,不要让怪物截断了。然后再以2~4秒的随机总时间,让怪物从右边移动到左边,移动出边界后,即回调函数spriteMoveFinished,进行删除精灵对象,增加的spriteMoveFinished方法如下:

1
2
3
4
5
void HelloWorld::spriteMoveFinished(CCNode *sender)
{
    CCSprite *sprite = (CCSprite*)sender;
     this->removeChild(sprite,  true);
}
接下去就是定时创建怪物,在 init函数返回之前,安装定时器,每秒执行一次,代码如下:
1
this->schedule(schedule_selector(HelloWorld::gameLogic),  1. 0);
增加 gameLogic方法,代码如下:
1
2
3
4
void HelloWorld::gameLogic(  float dt )
{
     this->addMonster();
}
7.编译运行,可以看到右边怪物定时增加,并且以不同的速度向左边移动,如下图所示:

8.接着让玩家可以射击子弹,当用户在屏幕点击时,就让玩家往点击的方向进行发送子弹,用户的屏幕点击点并不是子弹移动的最终地,借用原文的一张图片来说明:

要让层可以支持触摸,需要在 init方法,添加如下代码:
1
this->setTouchEnabled( true);
然后重载 ccTouchesEnded方法,代码如下:

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
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( "projectile.png");
    projectile->setPosition(ccp( 20, winSize.height /  2));

    CCPoint offset = ccpSub(location, projectile->getPosition());

     if (offset.x <=  0)
    {
         return;
    }

     this->addChild(projectile);

     int realX = winSize.width + projectile->getContentSize().width /  2;
     float ratio = ( float)offset.y / ( float)offset.x;
     int realY = realX * ratio + projectile->getPosition().y;
    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;
     float realMoveDuration = length / velocity;

    projectile->runAction(CCSequence::create(CCMoveTo::create(realMoveDuration, realDest), 
        CCCallFuncN::create( this, callfuncN_selector(HelloWorld::spriteMoveFinished)),  NULL));
}

首先,得到触摸点,然后创建子弹精灵,算出触摸点与子弹初始位置之差,若触摸点在初始位置的前方(即玩家前方),则添加子弹到层上。以同比例方法,计算出子弹飞向屏幕右边的最终坐标。然后再用勾股定理计算飞行长度,假定速度为每秒480像素,则计算出飞行总时间。之后就是让子弹执行给定的飞行动作,以及之后的删除自身调用。
9.编译运行,往屏幕点击,可以看到子弹发射出去,如下图所示:

10.当子弹碰到怪物时,怪物被消灭,子弹消失,即碰撞检测。需要在场景中跟踪目标和子弹,在HelloWorldScene.h声明如下:

1
2
cocos2d::CCArray *_monsters;
cocos2d::CCArray *_projectiles;
在构造函数和析构函数,添加如下:

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;
    }
}

然后在init函数中初始化这两个数组:

1
2
3
4
this->_monsters = CCArray::create();
this->_monsters->retain();
this->_projectiles = CCArray::create();
this->_projectiles->retain();
修改 addMonster函数,为怪物精灵添加标签,并加入到数组,代码如下:
1
2
monster->setTag( 1);
_monsters->addObject(monster);
修改 ccTouchesEnded函数,为子弹精灵添加标签,并加入到数组,代码如下:
1
2
projectile->setTag( 2);
_projectiles->addObject(projectile);
然后修改 spriteMoveFinished函数,增加如下代码:
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();
}

遍历子弹数组,计算每一个子弹所可能遇到的怪物,用它们各自的边界框进行交叉检测,检测到交叉,则将怪物对象放入ToDelete(待删除)数组,不能在遍历的时候删除一个对象。若是子弹遇到了怪物,也需要放入ToDelete(待删除)数组。然后从场景和数组中移动掉。同样,也在init函数,安装定时器,代码如下:

1
this->schedule(schedule_selector(HelloWorld::update));
11.编译运行,这时当子弹和怪物碰撞时,它们就会消失;
12.添加音效,在 init函数添加背景音乐,代码如下:
1
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic( "background-music-aac.wav");
ccTouchesEnded函数,添加子弹音效,代码如下:
1
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect( "pew-pew-lei.wav");
13.接下来,创建一个新的场景,来指示"You Win"或者"You Lose"。右键 工程,"Add"→"Class..."→"C++"→"Add","Base class"为CCLayerColor,"Class name"为 GameOverLayer,如下图所示:

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();
};

GameOverLayer.cpp文件代码为:

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( 255255255255)));

         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( 000));
        label->setPosition(ccp(winSize.width /  2, winSize.height /  2));
         this->addChild(label);

         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;
}

void GameOverLayer::gameOverDone()
{
    CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());
}

游戏结束时,切换到以上所建的场景,场景上的层显示一个文本,在3秒之后返回到HelloWorld场景中。
14.最后,为游戏添加一些游戏逻辑。记录玩家消灭怪物的数量,进而决定该玩家输赢。在HelloWorldScene.h文件中,添加如下:

1
int _monstersDestroyed;
HelloWorldScene.cpp文件,HelloWorld()构造函数,添加如下代码:
1
_monstersDestroyed =  0;
添加头文件引用:
1
#include  "GameOverLayer.h"
update定时函数中,monstersToDelete循环removeChild(monster, true)的后面添加被消灭怪物的计数,并判断胜利条件,代码如下:
1
2
3
4
5
6
_monstersDestroyed++;
if (_monstersDestroyed >  30)
{
    CCScene *gameOverScene = GameOverLayer::sceneWithWon( true);
    CCDirector::sharedDirector()->replaceScene(gameOverScene);
}
最后为玩家添加失败条件,规定只要有一只怪物跑到左边屏幕里,则玩家失败,在 spriteMoveFinished函数里,sprite->getTag() == 1条件的后面,添加如下:
1
2
CCScene *gameOverScene = GameOverLayer::sceneWithWon( false);
CCDirector::sharedDirector()->replaceScene(gameOverScene);
14.编译并运行,到此已完成了一个简单的游戏,包含音效,并带有胜利和失败的结束。游戏效果如下:

参考资料:
1.How To Make A Simple iPhone Game with Cocos2D 2.X Tutorial http://www.raywenderlich.com/25736/how-to-make-a-simple-iphone-game-with-cocos2d-2-x-tutorial
2.如何用Cocos2d来开发简单的IPhone游戏教程 http://www.cocoachina.com/bbs/read.php?tid-15554.html
3.Cocos2d Classic Tutorial Demo Revisit:(1) http://www.zilongshanren.com/cocos2d-classic-tutorial-demo-revisit-1/

非常感谢以上资料,本例子源代码附加资源下载地址http://download.csdn.net/detail/akof1314/4857315
如文章存在错误之处,欢迎指出,以便改正。

 

  • 18
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 55
    评论
### 回答1: cocos2d-x是一款流行的开源游戏引擎,它可以用作开发本地移动游戏和桌面游戏。利用cocos2d-x游戏源码,开发人员可以快速构建流畅、高效、具有吸引力的游戏。该引擎使用C ++语言和脚本语言Lua来实现游戏开发,用户可以根据自己的需要进行选择。 cocos2d-x游戏源码包含许多强大的功能和工具,例如精灵、动画、场景管理、碰撞检测和音频控制等。通过这些功能,开发人员可以方便地创建各种类型的游戏,例如动作游戏、射击游戏、冒险游戏和益智游戏等。 此外,cocos2d-x游戏源码还具有高度定制化的特性,允许开发人员根据他们的需求自定义游戏元素。这种定制化可以通过改进游戏画面,添加新的模式和关卡,甚至整个新的游戏玩法来完成。 总之,cocos2d-x游戏源码是一款功能强大、易于使用和高度定制的游戏引擎,它可以帮助开发人员快速开发各种类型的游戏。无论你是专业开发人员还是无经验的游戏制作者,cocos2d-x都是一个极好的选择。 ### 回答2: Cocos2d-x游戏源码是使用Cocos2d-x引擎进行开发的游戏程序代码。Cocos2d-x引擎是一个开源的跨平台游戏引擎,可以支持iOS、Android、Windows Phone、Windows、MacOS和Linux等多个平台,并且提供了丰富的游戏开发API和工具集。Cocos2d-x游戏源码包含了游戏的核心逻辑、UI设计、动画效果、音频效果等各方面的代码,可以作为开发者学习和借鉴的重要资料。 由于Cocos2d-x引擎支持多种编程语言(如C++、Lua等),因此Cocos2d-x游戏源码也会有对应的编程语言版本。开发者可以通过阅读Cocos2d-x游戏源码,了解游戏开发过程中的技术细节,学习如何使用Cocos2d-x引擎进行游戏开发。同时,开发者也可以通过对Cocos2d-x游戏源码进行修改和优化,来满足游戏的特定需求,提升游戏的性能和用户体验。 总之,Cocos2d-x游戏源码是游戏开发者必备的重要资源,可以帮助开发者更好地了解游戏开发技术,提升游戏开发水平。 ### 回答3: cocos2d-x是一款优秀的游戏开发引擎,其源码包含了许多功能强大的游戏开发工具和API。使用cocos2d-x可以帮助开发者更快速更高效地开发出优秀的游戏作品。 cocos2d-x游戏源码非常丰富,其包含了许多不同类型的游戏示例和模板,如平面射击、塔防、解谜等,这些示例可以帮助开发者更好地了解cocos2d-x的使用方法和原理。 cocos2d-x的源码还包含了许多强大的API和工具,例如场景管理、动画控制、音频引擎等,这些工具和API能够帮助开发者更好地完成游戏的开发和调试。 此外,cocos2d-x的源码还提供了完整的游戏开发框架,包括资源管理、内存管理、事件机制等,这些框架可以帮助开发者更好地组织代码和提高代码的可维护性。 总的来说,cocos2d-x游戏源码提供了丰富的工具和API,可以帮助开发者更高效地进行游戏开发,大大降低了开发难度和成本,是一款非常适合游戏开发者使用的引擎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 55
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值