Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例全

---------------------------------快过节了,弄个案例,大家不妨假期做做,

运行效果展示:


全部代码和资源:

http://download.csdn.net/detail/sdhjob/7424329

1.准备资源

背景图片menuback.png:


节点图片

greenstar.png

redstar.png

yellowstar.png

2.创建一个新项目(如何配置环境和创建新项目,参考前面教程):

cocos new -p com.xdl.game -l cpp -d ~/Desktop/test0515 snamegame

3.添加文件

首先将HelloWoldScene.h HelloWorld.cpp移走,然后添加GameScene.h GameScene.cpp HelpScene.h HelpScene.cpp MainMenu.h MainMenu.cpp

加上原来自动生成的AppDelegate.h 和AppDelegate.cpp共8个文件

4.编码

AppDelegate.h (这个文件基本没改动)

#ifndef _APP_DELEGATE_H_

#define _APP_DELEGATE_H_

#include"cocos2d.h"

class AppDelegate :privatecocos2d::Application

{

public:

AppDelegate();

virtual~AppDelegate();

virtualboolapplicationDidFinishLaunching();

virtualvoidapplicationDidEnterBackground();

virtualvoidapplicationWillEnterForeground();

};

#endif// _APP_DELEGATE_H_

AppDelegate.cpp

#include"AppDelegate.h"

#include"MainMenu.h"

#include"SimpleAudioEngine.h"

USING_NS_CC;

usingnamespaceCocosDenshion;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate()

{

boolAppDelegate::applicationDidFinishLaunching() {

// initialize director

autodirector =Director::getInstance();

autoglview = director->getopenGLView();

if(!glview) {

glview =GLView::create("My Game");

director->setopenGLView(glview);

}

// turn on display FPS

director->setdisplayStats(false);

// set FPS. the default value is 1.0/60 if you don't call this

director->setAnimationInterval(1.0/60);

// create a scene. it's an autorelease object

autoscene =MainMenu::createScene();

// run

director->runWithScene(scene);

//开始播放背景音乐

SimpleAudioEngine::getInstance()->playBackgroundMusic("background.mp3");

returntrue;

}


// This function will be called when the app is inactive. When comes a phone call,it's be invoked too

voidAppDelegate::applicationDidEnterBackground() {

Director::getInstance()->stopAnimation();

// if you use SimpleAudioEngine,it must be pause

SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

// this function will be called when the app is active again

voidAppDelegate::applicationWillEnterForeground() {

Director::getInstance()->startAnimation();

SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

}

说明: 在入口类中加入了背景音乐的播放,并且入口场景设计为MainMenu,往下看

MainMenu.h

#ifndef __snakegame__MainMenu__

#define __snakegame__MainMenu__

#include"cocos2d.h"

classMainMenu:publicLayer{

public:

staticScene* createScene();

CREATE_FUNC(MainMenu);

virtualboolinit();

voidmenuCallBack(Ref* object);

};

#endif


MainMenu.cpp #include"MainMenu.h"

#include"GameScene.h"

#include"HelpScene.h"

Scene*MainMenu::createScene()

{ autoscene=Scene::create();

autolayer=MainMenu::create();

scene->addChild(layer);

returnscene;

boolMainMenu::init(){

if(!Layer::init())

{

returnfalse;

autosize=Director::getInstance()->getWinSize();

//添加背景

autospriteBK=Sprite::create("menuback.png");

spriteBK->setPosition(Point(size.width/2,size.height/2));

this->addChild(spriteBK);

//添加2菜单条目

automenuItemStart=MenuItemFont::create("Start",CC_CALLBACK_1(MainMenu::menuCallBack,this));

menuItemStart->setTag(1);

automenuItemHelp=MenuItemFont::create("Help",51); font-family:Arial; font-size:14px; line-height:26px"> menuItemHelp->setTag(2);

automenu=Menu::create(menuItemStart,menuItemHelp,NULL);

menu->setPosition(Point::ZERO);

menuItemStart->setPosition(Point(size.width-menuItemStart->getContentSize().width-100,menuItemStart->getContentSize().height+10));

menuItemHelp->setPosition(Point(size.width-menuItemHelp->getContentSize().width-10,menuItemHelp->getContentSize().height+10));

this->addChild(menu);

returntrue;

voidMainMenu::menuCallBack(Ref* object){

autotarget=(Node*)object;

Scene* scene;

switch(target->getTag()) {

case1://startgame

scene=Game::createScene();

break;

case2://Helpgame

scene=Help::createScene();

default:

Director::getInstance()->replaceScene(scene);

}

说明:在菜单场景中实现了跳转到帮助场景和游戏场景,往下看: HelpScene.h

#ifndef __snakegame__HelpScene__

#define __snakegame__HelpScene__

USING_NS_CC;

classHelp:publicLayer{

public:

staticScene* createScene();

CREATE_FUNC(Help);

virtualboolinit();

voidmenuCallBack(Ref* object);

#endif

HelpScene.cpp #include"HelpScene.h"

#include"MainMenu.h"

Scene*Help::createScene(){

autoscene=Scene::create();

autolayer=Help::create();

returnscene;

}

boolHelp::init(){

{

returnfalse;

}

autosize=Director::getInstance()->getWinSize();

spriteBK->setopacity(75);

//帮助信息

autolabelscore=Label::create("帮助信息","宋体",25);

labelscore->setPosition(Point(size.width-80,size.height-50));

this->addChild(labelscore);

//返回按钮

automenuItemBack=MenuItemFont::create("Back",CC_CALLBACK_1(Help::menuCallBack,51); font-family:Arial; font-size:14px; line-height:26px"> automenu=Menu::create(menuItemBack,51); font-family:Arial; font-size:14px; line-height:26px"> menuItemBack->setPosition(Point(size.width-menuItemBack->getContentSize().width-100,menuItemBack->getContentSize().height+10));

voidHelp::menuCallBack(Ref* object){

autoscene=MainMenu::createScene();

Director::getInstance()->replaceScene(scene);

说明:这里只是实现了一个帮助信息显示,可以返回到菜单,下面看游戏场景 GameScene.h

#ifndef __snakegame__GameScene__

#define __snakegame__GameScene__

enumclassENUM_DIR{

DIR_UP,

DIR_DOWN,51); font-family:Arial; font-size:14px; line-height:26px"> DIR_LEFT,51); font-family:Arial; font-size:14px; line-height:26px"> DIR_RIGHT,51); font-family:Arial; font-size:14px; line-height:26px"> DIR_STOP

};

classSnakeNode:publicSprite

{

public:

enumENUM_DIRm_dir;//移动方向

intnodeType; //节点类型1蛇头2身体3食物

intm_row,m_col; //当前节点的行列坐标

staticSnakeNode* create(inttype);

virtualboolinit(inttype);

voidsetPositionRC(introw,intcol);//设置节点的坐标

};

classGame:publicLayer{

SnakeNode* spFood;//食物

SnakeNode* spHead;//蛇头

intm_score;

Vector<SnakeNode*> allBody;//身体

CREATE_FUNC(Game);

voidgameLogic(floatt);

voidnewBody();//添加一个新的身体节点

voidmoveBody();//移动所有的身体节点

GameScene.cpp //

// GameScene.cpp

// Created byshen on 14-5-27.

//


#include"SimpleAudioEngine.h"

usingnamespaceCocosDenshion;

Scene * Game::createScene(){

autoscene=Scene::create();

autolayer=Game::create();

scene->addChild(layer);

returnscene;


SnakeNode* SnakeNode::create(inttype)

SnakeNode *pRet =newSnakeNode();

if(pRet && pRet->init(type))

pRet->autorelease();

returnpRet;

else

deletepRet;

pRet =NULL;

returnNULL;

}

boolSnakeNode::init(inttype){

if(!Sprite::init())

returnfalse;

///根据类型不同初始化不同的纹理

switch(type) {

case1://蛇头

{autosprite=Sprite::create("redstar.png");

sprite->setAnchorPoint(Point::ZERO);

this->addChild(sprite);

m_dir=ENUM_DIR::DIR_RIGHT;//向右移动

break;

case2://身体

{autosprite=Sprite::create("greenstar.png");

this->addChild(sprite);

m_dir=ENUM_DIR::DIR_STOP;//

case3://食物

{autosprite=Sprite::create("yellowstar.png");

default:

}

returntrue;

voidSnakeNode::setPositionRC(introw,intcol)//设置节点的坐标

{ this->m_row=row;

this->m_col=col;

setPosition(Point(col*32,row*32));

bool Game::init(){

if(!Layer::init())

}

//添加地图

autodraw=DrawNode::create();

draw->setAnchorPoint(Point::ZERO);

draw->setPosition(Point::ZERO);

this->addChild(draw);

for(inti=0;i<11;i++)

{

draw->drawSegment(Point(0,32*i),Point(320,1,Color4F(1,1));

draw->drawSegment(Point(32*i,0),Point(32*i,320),51); font-family:Arial; font-size:14px; line-height:26px"> //添加蛇头

spHead=SnakeNode::create(1);

this->addChild(spHead);

//添加身体

//添加食物

spFood=SnakeNode::create(3);

introw=rand()%10;

intcol=rand()%10;

spFood->setPositionRC(row,col);

this->addChild(spFood);

autosize=Director::getInstance()->getWinSize();

//添加背景

autospriteBK=Sprite::create("menuback.png");

spriteBK->setPosition(Point(size.width/2,size.height/2));

spriteBK->setopacity(75);

this->addChild(spriteBK);

//分数显示

m_score=0;

autolabelscore=Label::create("分数:0","宋体",25);

labelscore->setTag(110);

labelscore->setPosition(Point(size.width-80,size.height-50));

this->addChild(labelscore);

//返回按钮

automenuItemBack=MenuItemFont::create("Back",CC_CALLBACK_1(Game::menuCallBack,this));

automenu=Menu::create(menuItemBack,NULL);

menu->setPosition(Point::ZERO);

menuItemBack->setPosition(Point(size.width-menuItemBack->getContentSize().width-50,menuItemBack->getContentSize().height+10));

this->addChild(menu);

//计划任务

this->schedule(schedule_selector(Game::gameLogic),0.5);

//加入用户触摸事件侦听

autolistener=EventListenerTouchOneByOne::create();

listener->setSwallowtouches(true);

listener->onTouchBegan=[&](Touch * t,Event * e){

//改变贪食蛇移动的方向

intcol=t->getLocation().x/32;

introw=t->getLocation().y/32;

intspHeadCol=spHead->getPositionX()/32;

intspHeadRow=spHead->getPositionY()/32;

if(abs(spHeadCol-col)>abs(spHeadRow-row))

if(spHeadCol<col)

{

spHead->m_dir=ENUM_DIR::DIR_RIGHT;

}else

spHead->m_dir=ENUM_DIR::DIR_LEFT;

}

else

{if(spHeadRow<row)

{

spHead->m_dir=ENUM_DIR::DIR_UP;

}else

{

spHead->m_dir=ENUM_DIR::DIR_DOWN;

}

}

returntrue;

};

_eventdispatcher->addEventListenerWithSceneGraPHPriority(listener,this);

void Game::menuCallBack(Ref * object){

autoscene=MainMenu::createScene();

Director::getInstance()->replaceScene(scene);

voidGame::gameLogic(floatt)

{ moveBody();//移动所有身体节点

//蛇头移动

switch(spHead->m_dir) {

caseENUM_DIR::DIR_RIGHT:

spHead->runAction(MoveBy::create(0.3,Point(32,0)));

spHead->m_coL++;

caseENUM_DIR::DIR_LEFT:

32,51); font-family:Arial; font-size:14px; line-height:26px"> spHead->m_col--;

caseENUM_DIR::DIR_DOWN:

0,-32)));

spHead->m_row--;

caseENUM_DIR::DIR_UP:

32)));

spHead->m_row++;

break;

//碰撞检测

if(spHead->m_row==spFood->m_row&&

spHead->m_col==spFood->m_col)

{//音效的播放

SimpleAudioEngine::getInstance()->playEffect("eat.wav");

//分数增加

this->m_score+=100;

Label * label=(Label *)this->getChildByTag(110);

charstrscore[20];

sprintf(strscore,"分数:%d",m_score);

label->setString(strscore);

//食物产生新的位置

introw=rand()%10;

intcol=rand()%10;

spFood->setPositionRC(row,51); font-family:Arial; font-size:14px; line-height:26px"> //添加节点

newBody();

}

voidGame::newBody()//添加一个新的身体节点

autobodynode=SnakeNode::create(2);

//设置这个节点的方向和坐标

if(allBody.size()>0)//有身体节点

{//最后一个身体的节点

autolastbody=allBody.at(allBody.size()-1);

bodynode->m_dir=lastbody->m_dir;

switch(bodynode->m_dir) {

caseENUM_DIR::DIR_UP:

bodynode->setPositionRC(lastbody->m_row-1,lastbody->m_col);

break;

caseENUM_DIR::DIR_DOWN:

bodynode->setPositionRC(lastbody->m_row+1,51); font-family:Arial; font-size:14px; line-height:26px"> caseENUM_DIR::DIR_LEFT:

bodynode->setPositionRC(lastbody->m_row,lastbody->m_col+1);

caseENUM_DIR::DIR_RIGHT:

1);

default:

}else

{//新节点的方向等于蛇头的方向

bodynode->m_dir=spHead->m_dir;

bodynode->setPositionRC(spHead->m_row-1,spHead->m_col);

bodynode->setPositionRC(spHead->m_row+1,51); font-family:Arial; font-size:14px; line-height:26px"> bodynode->setPositionRC(spHead->m_row,spHead->m_col+1);

1);

//添加节点到当前图层

this->addChild(bodynode);

//添加节点到集合中

allBody.pushBack(bodynode);

voidGame::moveBody()//移动所有的身体节点

if(allBody.size()==0){return;}

for(autobodynode:allBody)

switch(bodynode->m_dir) {

bodynode->runAction(MoveBy::create(0.3,51); font-family:Arial; font-size:14px; line-height:26px"> bodynode->m_coL++;

bodynode->m_col--;

bodynode->m_row--;

bodynode->m_row++;

//移动完成之后,改变每个body的方向

for(inti=allBody.size()-1;i>0;i--)

{//每个节点的方向调整为它前一个节点的方向

allBody.at(i)->m_dir=allBody.at(i-1)->m_dir;

allBody.at(0)->m_dir=spHead->m_dir;

--------------------------------------------祝你成功-----------------------

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...