贪吃蛇C++ cocos2d-x版

cocos2d-x是一个开源的支持多平台的2D手机游戏引擎,使用C++开发。由于参加一个游戏开发项目,是基于cocos2d-x平台的,所以想通过写贪吃蛇游戏来熟悉cocosd-x引擎。贪吃蛇C++命令行版已经在贪吃蛇C++命令行版中实现,现在把他们移植到cocos2d-x平台。cocos2d-x叫程请移步知易游戏开发教程cocos2d-x移植版
游戏描述
1. 初始时,贪吃蛇长度为4,呆在允许活动区域的左下角,有3条命,处于等级1,前进速度为20。
2. 贪吃蛇可以自动直线前进(默认向右),或者玩家通过鼠标单击方向键操纵贪吃蛇上下左右前进。
3. 在规定的活动区域内每次随机产生一颗“豆豆”,贪吃蛇每次吃到一颗豆豆后,另外一颗“豆豆”便随机产      生,贪吃蛇的长度增长1格,当贪吃蛇的长度每为8的倍数时,贪吃蛇升高1级,速度加快.
4.  贪吃蛇在规定的区域内活动,当
     ①贪吃蛇触碰到墙壁时;
     ②贪吃蛇的蛇头触碰到蛇身或者蛇尾时;
     贪吃蛇停止前进,生命数减1,通过单击方向键可继续操纵贪吃蛇前进。当生命数为0后,游戏结束,在状态      栏显示“Game Over!”。
5. 本游戏分为两个页面:主菜单页面和游戏页面(其实主菜单页面可要可不要,但俺为了熟练切换场景弄了个主菜单页面)。通过单击主菜单按钮可以实现两个页面切换。

游戏开发环境win7,Visual Studio 2012

游戏运行结果截图
1. 主菜单页面:
[转载]贪吃蛇C++ <wbr>cocos2d-x版

2. 游戏页面:
[转载]贪吃蛇C++ <wbr>cocos2d-x版


游戏代码:
主菜单:
①HelloWorldScene.h:
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

#include "SimpleAudioEngine.h"

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // there's no 'id' in cpp, so we recommand to return the exactly class pointer
    static cocos2d::CCScene* scene();

//a selector starting
void menuOnNewGame(CCObject* pSender);
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);

    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);
};

#endif  // __HELLOWORLD_SCENE_H__
②HelloWorldScene.cpp
#include "HelloWorldScene.h"
#include "GreedyChopper.h"

using namespace cocos2d;

CCScene* HelloWorld::scene()
{
    CCScene * scene = NULL;
    do 
    {
        // 'scene' is an autorelease object
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        // 'layer' is an autorelease object
        HelloWorld *layer = HelloWorld::create();
        CC_BREAK_IF(! layer);

        // add layer as a child to scene
        scene->addChild(layer);
    } while (0);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        //
        // super init first
        //

        CC_BREAK_IF(! CCLayer::init());

        //
        // add your codes below...
        //

        // 1. Add a menu item with "X" image, which is clicked to quit the program.

        // Create a "close" menu item with close icon, it's an auto release object.
        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
            "CloseNormal.png",
            "CloseSelected.png",
            this,
            menu_selector(HelloWorld::menuCloseCallback));
        CC_BREAK_IF(! pCloseItem);

        // Place the menu item bottom-right conner.
        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));

CCMenuItemImage *pStartItem = CCMenuItemImage::create(
"newGame.jpg", 
"newGame1.jpg",
this,
menu_selector(HelloWorld::menuOnNewGame));
CC_BREAK_IF(! pStartItem);
pStartItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width / 2 - 20, 30));

        // Create a menu with the "close" menu item, it's an auto release object.
        CCMenu* pMenu = CCMenu::create(pCloseItem, pStartItem, NULL);
        pMenu->setPosition(CCPointZero);
        CC_BREAK_IF(! pMenu);

        // Add the menu to HelloWorld layer as a child layer.
        this->addChild(pMenu, 1);

        // 2. Add a label shows "Hello World".

        // Create a label and initialize with string "Hello World".
        CCLabelTTF* pLabel = CCLabelTTF::create("Greedy Chopper", "MarkerFelt-Thin", 24);
        CC_BREAK_IF(! pLabel);

        // Get window size and place the label upper. 
        CCSize size = CCDirector::sharedDirector()->getWinSize();
        pLabel->setPosition(ccp(size.width / 2, 70));

        // Add the label to HelloWorld layer as a child layer.
        this->addChild(pLabel, 1);

        // 3. Add add a splash screen, show the cocos2d splash image.
        CCSprite* pSprite = CCSprite::create("welcome.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);

        bRet = true;
    } while (0);

    return bRet;
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    // "close" menu item clicked
    CCDirector::sharedDirector()->end();
}

void HelloWorld::menuOnNewGame(CCObject* pSender)
{
//到游戏页面
CCScene* scene = NULL;
do
{
scene = CCScene::create();
CC_BREAK_IF(!scene);

GreedyChopper* p = GreedyChopper::create();
CC_BREAK_IF(!p);

scene->addChild(p);
CCDirector::sharedDirector()->replaceScene(CCTransitionSlideInR::transitionWithDuration(0.5f, scene));

} while (0);
}
游戏界面:
①GreedyChopper.h:

#ifndef GREEDYCHOPPER_H
#define GREEDYCHOPPER_H

#include "HelloWorldScene.h"
#include "cocos2d.h"

#include "SimpleAudioEngine.h"

class GreedyChopper: public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // there's no 'id' in cpp, so we recommand to return the exactly class pointer
    static cocos2d::CCScene* scene();

//a selector starting
void menuOnNewGame(CCObject* pSender);
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);

void clickUp(CCObject* pSender);
void clickDown(CCObject* pSender);
void clickRight(CCObject* pSender);
void clickLeft(CCObject* pSender);
void step(float dt);

    // implement the "static node()" method manually
CREATE_FUNC(GreedyChopper);
private:
int graph[54][54], chopper[2][100];
int length, head, tail, direction, beanX, beanY, x, y, level, life, speed;
int sumTime;
cocos2d::CCSprite* sprite[54][54];
bool flag, lifeFlag;
float gameSpeed;
cocos2d::CCLabelTTF* levelTag;
cocos2d::CCLabelTTF* timeTag;
cocos2d::CCLabelTTF* lifeTag;
cocos2d::CCLabelTTF* speedTag;
};

#endif  // __HELLOWORLD_SCENE_H__
 
②GreedyChopper.cpp




   
   
#include "HelloWorldScene.h"
#include "GreedyChopper.h"
#include
#include
#include
using namespace cocos2d;
CCScene* GreedyChopper::scene()
{
      CCScene * scene = NULL;
      do 
      {
            // 'scene' is an autorelease object
            scene = CCScene::create();
            CC_BREAK_IF(! scene);
            // 'layer' is an autorelease object
GreedyChopper *layer = GreedyChopper::create();
            CC_BREAK_IF(! layer);
            // add layer as a child to scene
            scene->addChild(layer);
      } while (0);
      // return the scene
      return scene;
}
// on "init" you need to initialize your instance
bool GreedyChopper::init()
{
      bool bRet = false;
      do 
      {
            //
            // super init first
            //
            CC_BREAK_IF(! CCLayer::init());
            //
            // add your codes below...
memset(graph, 0, sizeof(graph));
//墙壁
for (int i = 0; i < 54; i++)
{
graph[0][i] = graph[53][i] = 1;
}
for (int i = 1; i < 53; i++)
{
graph[i][0] = graph[i][53] = 1;
}
for (int i = 1; i <= 3; i++)
graph[1][i] = 2;         //蛇身
graph[1][4] = 3;               //蛇头
for (int i = 0; i < 4; i++)
{
chopper[0][i] = 1;
chopper[1][i] = i + 1;
}                                     //记录贪吃蛇所在的坐标
head = 3, tail = 0, length = 4;
srand(time(0));
do
{
beanX = rand() % 52 + 1;
beanY = rand() % 52 + 1;
} while (graph[beanX][beanY]);  
graph[beanX][beanY] = 2;             //随机产生食物
for (int i = 0; i < 54; i++)
     {
for (int j = 0; j < 54; j++)
{
if (graph[i][j] == 1)
sprite[i][j] = CCSprite::create("wall.jpg");
else if (graph[i][j] == 2)
sprite[i][j] = CCSprite::create("tail.jpg");
else if (graph[i][j] == 3)
sprite[i][j] = CCSprite::create("head.jpg");
else
sprite[i][j] = CCSprite::create("grid.jpg");
sprite[i][j]->setPosition(ccp(10 * i + 5, 10 * j + 5));
this->addChild(sprite[i][j], 1);
}
}
//方向默认向上,自动前进速度默认为800ms,等级为1
life = 3, direction = 1, gameSpeed = 500, level = 1, speed = 10 / (gameSpeed / 1000);
flag = true, lifeFlag = true;
sumTime = 0;
char life_str[30], level_str[30], time_str[30], speed_str[30];
sprintf(life_str, "Life: %d", life);
lifeTag = CCLabelTTF::create(life_str, "font09.fnt", 20);
CC_BREAK_IF(!lifeTag);
lifeTag->setPosition(ccp(630, 520));
this->addChild(lifeTag, 1);
sprintf(level_str, "Level: %d", level);
levelTag = CCLabelTTF::create(level_str, "font09.fnt", 20);
CC_BREAK_IF(!levelTag);
levelTag->setPosition(ccp(630, 490));
this->addChild(levelTag, 1);
sprintf(time_str, "Time: %d s", sumTime / 1000);
timeTag = CCLabelTTF::create(time_str, "font09.fnt", 20);
CC_BREAK_IF(!levelTag);
timeTag->setPosition(ccp(630, 460));
this->addChild(timeTag, 1);
sprintf(speed_str, "Speed: %d", speed);
speedTag = CCLabelTTF::create(speed_str, "font09.fnt", 20);
CC_BREAK_IF(!speedTag);
speedTag->setPosition(ccp(630, 430));
this->addChild(speedTag, 1);
this->schedule(schedule_selector(GreedyChopper::step), gameSpeed / 1000);
CCMenuItemImage *up = CCMenuItemImage::create(
"up.jpg",
"up1.jpg",
this,
menu_selector(GreedyChopper::clickUp));
CC_BREAK_IF(! up);
up->setPosition(ccp(630, 370));
CCMenuItemImage *down = CCMenuItemImage::create(
"down.jpg",
"down1.jpg",
this,
menu_selector(GreedyChopper::clickDown));
CC_BREAK_IF(! down);
down->setPosition(ccp(630, 260));
CCMenuItemImage *right = CCMenuItemImage::create(
"right.jpg",
"right1.jpg",
this,
menu_selector(GreedyChopper::clickRight));
CC_BREAK_IF(! right);
right->setPosition(ccp(685, 315));
CCMenuItemImage *left = CCMenuItemImage::create(
"left.jpg",
"left1.jpg",
this,
menu_selector(GreedyChopper::clickLeft));
CC_BREAK_IF(! left);
left->setPosition(ccp(575, 315));
            //
            // 1. Add a menu item with "X" image, which is clicked to quit the program.
            // Create a "close" menu item with close icon, it's an auto release object.
            CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                  "CloseNormal.png",
                  "CloseSelected.png",
                  this,
menu_selector(GreedyChopper::menuCloseCallback));
            CC_BREAK_IF(! pCloseItem);
            // Place the menu item bottom-right conner.
            pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
CCMenuItemImage *pStartItem = CCMenuItemImage::create(
"newGame.jpg", 
"newGame1.jpg",
this,
menu_selector(GreedyChopper::menuOnNewGame));
CC_BREAK_IF(! pStartItem);
pStartItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 150, 20));
            // Create a menu with the "close" menu item, it's an auto release object.
            CCMenu* pMenu = CCMenu::create(up, down, right, left, pCloseItem, pStartItem, NULL);
            pMenu->setPosition(CCPointZero);
            CC_BREAK_IF(! pMenu);
            // Add the menu to HelloWorld layer as a child layer.
            this->addChild(pMenu, 1);
            // 2. Add a label shows "Hello World".
            // Create a label and initialize with string "Hello World".
            // 3. Add add a splash screen, show the cocos2d splash image.
            CCSprite* pSprite = CCSprite::create("welcome.jpg");
pSprite->setOpacity(90);
            CC_BREAK_IF(! pSprite);
CCSize size = CCDirector::sharedDirector()->getWinSize();
            // 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);
            bRet = true;
      } while (0);
      return bRet;
}
void GreedyChopper::menuCloseCallback(CCObject* pSender)
{
      // "close" menu item clicked
      CCDirector::sharedDirector()->end();
}
void GreedyChopper::menuOnNewGame(CCObject* pSender)
{
CCScene* scene = NULL;
do
{
scene = CCScene::create();
CC_BREAK_IF(!scene);
HelloWorld* pScene = HelloWorld::create();
CC_BREAK_IF(!pScene);
scene->addChild(pScene);
CCDirector::sharedDirector()->replaceScene(CCTransitionSlideInR::transitionWithDuration(0.5, scene));
} while (0);
}
void GreedyChopper::clickUp(CCObject* pSender)
{
if (flag)
direction = 1;
}
void GreedyChopper::clickDown(CCObject* pSender)
{
if (flag)
direction = 2;
}
void GreedyChopper::clickRight(CCObject* pSender)
{
if (flag)
direction = 3;
}
void GreedyChopper::clickLeft(CCObject* pSender)
{
if (flag)
direction = 4;
}
void GreedyChopper::step(float dt)
{
if (flag)
sumTime += gameSpeed;
this->removeChild(timeTag, true);
char time_str[30];
sprintf(time_str, "Time: %d s", sumTime / 1000);
timeTag = CCLabelTTF::create(time_str, "font09.fnt", 20);
timeTag->setPosition(ccp(630, 460));
this->addChild(timeTag, 1);
switch (direction)
{
//向上
case 1: x = chopper[0][head], y = chopper[1][head] + 1, lifeFlag = true;
break;
//向下
case 2: x = chopper[0][head], y = chopper[1][head] - 1, lifeFlag = true;
break;
//向右
case 3: x = chopper[0][head] + 1, y = chopper[1][head], lifeFlag = true;
break;
//向左
case 4: x = chopper[0][head] - 1, y = chopper[1][head], lifeFlag = true;
break;
default: x = chopper[0][head], y = chopper[1][head], lifeFlag = false;
break;
}
//贪吃蛇触碰到墙壁,Game Over
if ((x == 0 || x == 53 || y == 0 || y == 53) || (graph[x][y] && !(x == beanX && y == beanY)))
{
if (life && lifeFlag)
life--;
this->removeChild(lifeTag, true);
char life_str[30];
sprintf(life_str, "Life: %d", life);
lifeTag = CCLabelTTF::create(life_str, "font09.fnt", 20);
lifeTag->setPosition(ccp(630, 520));
this->addChild(lifeTag, 1);
direction = 0;
if (!life)
{
flag = false;
CCLabelTTF* pLabel = CCLabelTTF::create("Game Over!", "font09.fnt", 24);
// Get window size and place the label upper. 
CCSize size = CCDirector::sharedDirector()->getWinSize();
pLabel->setPosition(ccp(630, 70));
// Add the label to HelloWorld layer as a child layer.
this->addChild(pLabel, 1);
}
return;
}
else if (x == beanX && y == beanY)
{
length++;
if (length >= 8)
{
length -= 8;
level++;
if (gameSpeed > 50)
gameSpeed -= 50;
this->removeChild(levelTag, true);
char level_str[30];
sprintf(level_str, "Level: %d", level);
levelTag = CCLabelTTF::create(level_str, "font09.fnt", 20);
levelTag->setPosition(ccp(630, 490));
this->addChild(levelTag, 1);
this->removeChild(speedTag, true);
char speed_str[30];
speed = 10 / (gameSpeed / 1000);
sprintf(speed_str, "Speed: %d", speed);
speedTag = CCLabelTTF::create(speed_str, "font09.fnt", 20);
speedTag->setPosition(ccp(630, 430));
this->addChild(speedTag, 1);
}
graph[beanX][beanY] = 0;
graph[chopper[0][head]][chopper[1][head]] = 2;
head = (head + 1) % 100;
graph[x][y] = 3;
chopper[0][head] = x;
chopper[1][head] = y;
srand(time(0));
do
{
beanX = rand() % 52 + 1;
beanY = rand() % 52 + 1;
} while (graph[beanX][beanY]);
graph[beanX][beanY] = 2;
}
else
{
graph[chopper[0][tail]][chopper[1][tail]] = 0;
tail = (tail + 1) % 100;
graph[chopper[0][head]][chopper[1][head]] = 2;
head = (head + 1) % 100;
graph[x][y] = 3;
chopper[0][head] = x;
chopper[1][head] = y;
}
for (int i = 0; i < 54; i++)
{
for (int j = 0; j < 54; j++)
this->removeChild(sprite[i][j], true);
}
for (int i = 0; i < 54; i++)
{
for (int j = 0; j < 54; j++)
{
if (graph[i][j] == 1)
sprite[i][j] = CCSprite::create("wall.jpg");
else if (graph[i][j] == 2)
sprite[i][j] = CCSprite::create("tail.jpg");
else if (graph[i][j] == 3)
sprite[i][j] = CCSprite::create("head.jpg");
else
sprite[i][j] = CCSprite::create("grid.jpg");
sprite[i][j]->setPosition(ccp(10 * i + 5, 10 * j + 5));
this->addChild(sprite[i][j], 1);
}
}
}
 


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值