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 #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 by沈shen 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; --------------------------------------------祝你成功----------------------- (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |