多语言展示
当前在线:1470今日阅读:23今日分享:25

Cocos2d-x 3.0final 教程13-贪食蛇游戏案例

运行效果展示:全部代码和资源:http://download.csdn.net/detail/sdhjob/74243291.准备资源背景图片menuback.png:节点图片greenstar.png redstar.png yellowstar.png2.创建一个新项目(如何配置环境和创建新项目,参考前面教程):cocos new -p com.xdl.game -l cpp -d ~/Desktop/test0515 snamegame3.添加文件首先将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 directorautodirector =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 objectautoscene =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 toovoidAppDelegate::applicationDidEnterBackground() {Director::getInstance()->stopAnimation();// if you use SimpleAudioEngine, it must be pauseSimpleAudioEngine::getInstance()->pauseBackgroundMusic();}// this function will be called when the app is active againvoidAppDelegate::applicationWillEnterForeground() {Director::getInstance()->startAnimation();// if you use SimpleAudioEngine, it must resume hereSimpleAudioEngine::getInstance()->resumeBackgroundMusic();}说明: 在入口类中加入了背景音乐的播放,并且入口场景设计为MainMenu,往下看MainMenu.h#ifndef __snakegame__MainMenu__#define __snakegame__MainMenu__#include"cocos2d.h"USING_NS_CC;classMainMenu:publicLayer{public:staticScene* createScene();CREATE_FUNC(MainMenu);virtualboolinit();voidmenuCallBack(Ref* object);};#endifMainMenu.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",CC_CALLBACK_1(MainMenu::menuCallBack,this)); 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();break;default:break; }Director::getInstance()->replaceScene(scene); }说明:在菜单场景中实现了跳转到帮助场景和游戏场景,往下看:HelpScene.h#ifndef __snakegame__HelpScene__#define __snakegame__HelpScene__#include"cocos2d.h"USING_NS_CC;classHelp:publicLayer{public:staticScene* createScene();CREATE_FUNC(Help);virtualboolinit();voidmenuCallBack(Ref* object);};#endifHelpScene.cpp#include"HelpScene.h"#include"MainMenu.h"Scene*Help::createScene(){autoscene=Scene::create();autolayer=Help::create(); scene->addChild(layer);returnscene; }boolHelp::init(){if(!Layer::init()) {returnfalse; }autosize=Director::getInstance()->getWinSize();//添加背景autospriteBK=Sprite::create("menuback.png"); spriteBK->setPosition(Point(size.width/2,size.height/2)); spriteBK->setOpacity(75);this->addChild(spriteBK);//帮助信息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,this));automenu=Menu::create(menuItemBack,NULL); menu->setPosition(Point::ZERO); menuItemBack->setPosition(Point(size.width-menuItemBack->getContentSize().width-100,menuItemBack->getContentSize().height+10));this->addChild(menu);returntrue;}voidHelp::menuCallBack(Ref* object){autoscene=MainMenu::createScene();Director::getInstance()->replaceScene(scene);}说明:这里只是实现了一个帮助信息显示,可以返回到菜单,下面看游戏场景GameScene.h#ifndef __snakegame__GameScene__#define __snakegame__GameScene__#include"cocos2d.h"USING_NS_CC;enumclassENUM_DIR{ DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT, 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{public:SnakeNode* spFood;//食物SnakeNode* spHead;//蛇头intm_score;Vector allBody;//身体staticScene* createScene();CREATE_FUNC(Game);virtualboolinit();voidmenuCallBack(Ref* object);voidgameLogic(floatt);voidnewBody();//添加一个新的身体节点voidmoveBody();//移动所有的身体节点};#endifGameScene.cpp//// GameScene.cpp// Created by沈shen on 14-5-27.//#include"GameScene.h"#include"MainMenu.h"#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"); sprite->setAnchorPoint(Point::ZERO);this->addChild(sprite); } m_dir=ENUM_DIR::DIR_STOP;//break;case3://食物 {autosprite=Sprite::create("yellowstar.png"); sprite->setAnchorPoint(Point::ZERO);this->addChild(sprite); } m_dir=ENUM_DIR::DIR_STOP;//break;default:break; }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()) {returnfalse; }//添加地图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,32*i),1, Color4F(1,1,1,1)); draw->drawSegment(Point(32*i,0), Point(32*i,320),1, Color4F(1,1,1,1)); }//添加蛇头 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(spHeadColm_dir=ENUM_DIR::DIR_RIGHT; }else { spHead->m_dir=ENUM_DIR::DIR_LEFT; } }else {if(spHeadRowm_dir=ENUM_DIR::DIR_UP; }else { spHead->m_dir=ENUM_DIR::DIR_DOWN; } }returntrue; }; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);returntrue;}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++;break;caseENUM_DIR::DIR_LEFT: spHead->runAction(MoveBy::create(0.3, Point(-32,0))); spHead->m_col--;break;caseENUM_DIR::DIR_DOWN: spHead->runAction(MoveBy::create(0.3, Point(0,-32))); spHead->m_row--;break;caseENUM_DIR::DIR_UP: spHead->runAction(MoveBy::create(0.3, Point(0,32))); spHead->m_row++;break;default: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,col);//添加节点 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, lastbody->m_col);break;caseENUM_DIR::DIR_LEFT: bodynode->setPositionRC(lastbody->m_row, lastbody->m_col+1);break;caseENUM_DIR::DIR_RIGHT: bodynode->setPositionRC(lastbody->m_row, lastbody->m_col-1);break;default:break; } }else {//新节点的方向等于蛇头的方向 bodynode->m_dir=spHead->m_dir;switch(bodynode->m_dir) {caseENUM_DIR::DIR_UP: bodynode->setPositionRC(spHead->m_row-1, spHead->m_col);break;caseENUM_DIR::DIR_DOWN: bodynode->setPositionRC(spHead->m_row+1, spHead->m_col);break;caseENUM_DIR::DIR_LEFT: bodynode->setPositionRC(spHead->m_row, spHead->m_col+1);break;caseENUM_DIR::DIR_RIGHT: bodynode->setPositionRC(spHead->m_row, spHead->m_col-1);break;default:break; } }//添加节点到当前图层this->addChild(bodynode);//添加节点到集合中 allBody.pushBack(bodynode);}voidGame::moveBody()//移动所有的身体节点{if(allBody.size()==0){return;}for(autobodynode:allBody) {switch(bodynode->m_dir) {caseENUM_DIR::DIR_RIGHT: bodynode->runAction(MoveBy::create(0.3, Point(32,0))); bodynode->m_col++;break;caseENUM_DIR::DIR_LEFT: bodynode->runAction(MoveBy::create(0.3, Point(-32,0))); bodynode->m_col--;break;caseENUM_DIR::DIR_DOWN: bodynode->runAction(MoveBy::create(0.3, Point(0,-32))); bodynode->m_row--;break;caseENUM_DIR::DIR_UP: bodynode->runAction(MoveBy::create(0.3, Point(0,32))); bodynode->m_row++;break;default:break; } }//移动完成之后,改变每个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;}
推荐信息