Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例(全)
快过节了。谢谢了屈原,我们爱你。
应该多几个向屈大人一样跳江的,这样我们就能够放假纪念啦。
---------------------------------快过节了。弄个案例,大家最好还是假期做做,
执行效果展示:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2Roam9i/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
所有代码和资源:
http://download.csdn.net/detail/sdhjob/7424329
1.准备资源
背景图片menuback.png:
节点图片
greenstar.png
redstar.png
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2Roam9i/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
yellowstar.png
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2Roam9i/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
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 : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();
virtual bool applicationDidFinishLaunching();
virtual void applicationDidEnterBackground();
virtual void applicationWillEnterForeground();
};
#endif // _APP_DELEGATE_H_
AppDelegate.cpp
#include "AppDelegate.h"
#include "MainMenu.h"
#include "SimpleAudioEngine.h"
USING_NS_CC;
using namespace CocosDenshion;
AppDelegate::AppDelegate() {
}
AppDelegate::~AppDelegate()
{
}
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = 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
auto scene = MainMenu::createScene();
// run
director->runWithScene(scene);
//開始播放背景音乐
SimpleAudioEngine::getInstance()->playBackgroundMusic("background.mp3");
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::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
void AppDelegate::applicationWillEnterForeground() {
Director::getInstance()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
说明: 在入口类中增加了背景音乐的播放,而且入口场景设计为MainMenu,往下看
MainMenu.h
#ifndef __snakegame__MainMenu__
#define __snakegame__MainMenu__
#include "cocos2d.h"
USING_NS_CC;
class MainMenu:public
Layer{
public:
static Scene * createScene();
CREATE_FUNC(MainMenu);
virtual bool init();
void menuCallBack(Ref * object);
};
#endif
MainMenu.cpp
#include "MainMenu.h"
#include "GameScene.h"
#include "HelpScene.h"
Scene * MainMenu::createScene()
{ auto scene=Scene::create();
auto layer=MainMenu::create();
scene->addChild(layer);
return scene;
}
bool MainMenu::init(){
if(!Layer::init())
{
return false;
}
auto size=Director::getInstance()->getWinSize();
//加入背景
auto spriteBK=Sprite::create("menuback.png");
spriteBK->setPosition(Point(size.width/2,size.height/2));
this->addChild(spriteBK);
//加入2个菜单栏目
auto menuItemStart=MenuItemFont::create("Start",
CC_CALLBACK_1(MainMenu::menuCallBack,this));
menuItemStart->setTag(1);
auto menuItemHelp=MenuItemFont::create("Help",
CC_CALLBACK_1(MainMenu::menuCallBack,this));
menuItemHelp->setTag(2);
auto menu=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);
return true;
}
void MainMenu::menuCallBack(Ref * object){
auto target=(Node *)object;
Scene * scene;
switch (target->getTag()) {
case
1://startgame
scene=Game::createScene();
break;
case 2://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;
class Help:public Layer{
public:
static Scene * createScene();
CREATE_FUNC(Help);
virtual bool init();
void menuCallBack(Ref * object);
};
#endif
HelpScene.cpp
#include "HelpScene.h"
#include "MainMenu.h"
Scene * Help::createScene(){
auto scene=Scene::create();
auto layer=Help::create();
scene->addChild(layer);
return scene;
}
bool Help::init(){
if(!Layer::init())
{
return false;
}
auto size=Director::getInstance()->getWinSize();
//加入背景
auto spriteBK=Sprite::create("menuback.png");
spriteBK->setPosition(Point(size.width/2,size.height/2));
spriteBK->setOpacity(75);
this->addChild(spriteBK);
//帮助信息
auto labelScore=Label::create("帮助信息",
"宋体",
25);
labelScore->setPosition(Point(size.width-80,size.height-50));
this->addChild(labelScore);
//返回button
auto menuItemBack=MenuItemFont::create("Back",
CC_CALLBACK_1(Help::menuCallBack,this));
auto menu=Menu::create(menuItemBack,NULL);
menu->setPosition(Point::ZERO);
menuItemBack->setPosition(Point(size.width-menuItemBack->getContentSize().width-100,menuItemBack->getContentSize().height+10));
this->addChild(menu);
return true;
}
void Help::menuCallBack(Ref * object){
auto scene=MainMenu::createScene();
Director::getInstance()->replaceScene(scene);
}
说明:这里仅仅是实现了一个帮助信息显示。能够返回到菜单。以下看游戏场景
GameScene.h
#ifndef __snakegame__GameScene__
#define __snakegame__GameScene__
#include "cocos2d.h"
USING_NS_CC;
enum class ENUM_DIR{
DIR_UP,
DIR_DOWN,
DIR_LEFT,
DIR_RIGHT,
DIR_STOP
};
class SnakeNode:public
Sprite
{
public :
enum ENUM_DIR m_dir;//移动方向
int nodeType; //节点类型1蛇头 2
身体 3 食物
int m_row,m_col; //当前节点的行列坐标
static SnakeNode* create(int type);
virtual bool init(int type);
void setPositionRC(int row,int col);//设置节点的坐标
};
class Game:public Layer{
public:
SnakeNode * spFood;//食物
SnakeNode * spHead;//蛇头
int m_score;
Vector<SnakeNode *> allBody;//身体
static Scene * createScene();
CREATE_FUNC(Game);
virtual bool init();
void menuCallBack(Ref * object);
void gameLogic(float t);
void newBody();//加入一个新的身体节点
void moveBody();//移动全部的身体节点
};
#endif
GameScene.cpp
//
// GameScene.cpp
// Created by 沈 shen on 14-5-27.
//
#include "GameScene.h"
#include "MainMenu.h"
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
Scene * Game::createScene(){
auto scene=Scene::create();
auto layer=Game::create();
scene->addChild(layer);
return scene;
}
SnakeNode* SnakeNode::create(int type)
{
SnakeNode *pRet = new SnakeNode();
if (pRet && pRet->init(type))
{
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = NULL;
return NULL;
}
}
bool SnakeNode::init(int type){
if(!Sprite::init())
{
return false;
}
///依据类型不同初始化不同的纹理
switch (type) {
case 1://蛇头
{auto sprite=Sprite::create("redstar.png");
sprite->setAnchorPoint(Point::ZERO);
this->addChild(sprite);
m_dir=ENUM_DIR::DIR_RIGHT;//向右移动
}
break;
case 2://身体
{auto sprite=Sprite::create("greenstar.png");
sprite->setAnchorPoint(Point::ZERO);
this->addChild(sprite);
}
m_dir=ENUM_DIR::DIR_STOP;//
break;
case 3://食物
{auto sprite=Sprite::create("yellowstar.png");
sprite->setAnchorPoint(Point::ZERO);
this->addChild(sprite);
}
m_dir=ENUM_DIR::DIR_STOP;//
break;
default:
break;
}
return true;
}
void SnakeNode::setPositionRC(int row,int col)//设置节点的坐标
{ this->m_row=row;
this->m_col=col;
setPosition(Point(col*32,row*32));
}
bool Game::init(){
if(!Layer::init())
{
return false;
}
//加入地图
auto draw=DrawNode::create();
draw->setAnchorPoint(Point::ZERO);
draw->setPosition(Point::ZERO);
this->addChild(draw);
for(int i=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);
int row=rand()%10;
int col=rand()%10;
spFood->setPositionRC(row,col);
this->addChild(spFood);
auto size=Director::getInstance()->getWinSize();
//加入背景
auto spriteBK=Sprite::create("menuback.png");
spriteBK->setPosition(Point(size.width/2,size.height/2));
spriteBK->setOpacity(75);
this->addChild(spriteBK);
//分数显示
m_score=0;
auto labelScore=Label::create("分数:0",
"宋体",
25);
labelScore->setTag(110);
labelScore->setPosition(Point(size.width-80,size.height-50));
this->addChild(labelScore);
//返回button
auto menuItemBack=MenuItemFont::create("Back", CC_CALLBACK_1(Game::menuCallBack,this));
auto menu=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);
//增加用户触摸事件侦听
auto listener=EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan=[&](Touch * t,Event * e){
//改变贪食蛇移动的方向
int col=t->getLocation().x/32;
int row=t->getLocation().y/32;
int spHeadCol=spHead->getPositionX()/32;
int spHeadRow=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;
}
}
return true;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,
this);
return true;
}
void Game::menuCallBack(Ref * object){
auto scene=MainMenu::createScene();
Director::getInstance()->replaceScene(scene);
}
void Game::gameLogic(float t)
{ moveBody();//移动全部身体节点
//蛇头移动
switch (spHead->m_dir) {
case ENUM_DIR::DIR_RIGHT:
spHead->runAction(MoveBy::create(0.3, Point(32,0)));
spHead->m_col++;
break;
case ENUM_DIR::DIR_LEFT:
spHead->runAction(MoveBy::create(0.3, Point(-32,0)));
spHead->m_col--;
break;
case ENUM_DIR::DIR_DOWN:
spHead->runAction(MoveBy::create(0.3, Point(0,-32)));
spHead->m_row--;
break;
case ENUM_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);
char strscore[20];
sprintf(strscore, "分数:%d",m_score);
label->setString(strscore);
//食物产生新的位置
int row=rand()%10;
int col=rand()%10;
spFood->setPositionRC(row,col);
//加入节点
newBody();
}
}
void Game::newBody()//加入一个新的身体节点
{
auto bodynode=SnakeNode::create(2);
//设置这个节点的方向和坐标
if(allBody.size()>0)//有身体节点
{ //最后一个身体的节点
auto lastbody=allBody.at(allBody.size()-1);
bodynode->m_dir=lastbody->m_dir;
switch (bodynode->m_dir) {
case ENUM_DIR::DIR_UP:
bodynode->setPositionRC(lastbody->m_row-1, lastbody->m_col);
break;
case ENUM_DIR::DIR_DOWN:
bodynode->setPositionRC(lastbody->m_row+1, lastbody->m_col);
break;
case ENUM_DIR::DIR_LEFT:
bodynode->setPositionRC(lastbody->m_row, lastbody->m_col+1);
break;
case ENUM_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) {
case ENUM_DIR::DIR_UP:
bodynode->setPositionRC(spHead->m_row-1, spHead->m_col);
break;
case ENUM_DIR::DIR_DOWN:
bodynode->setPositionRC(spHead->m_row+1, spHead->m_col);
break;
case ENUM_DIR::DIR_LEFT:
bodynode->setPositionRC(spHead->m_row, spHead->m_col+1);
break;
case ENUM_DIR::DIR_RIGHT:
bodynode->setPositionRC(spHead->m_row, spHead->m_col-1);
break;
default:
break;
}
}
//加入节点到当前图层
this->addChild(bodynode);
//加入节点到集合中
allBody.pushBack(bodynode);
}
void Game::moveBody()//移动全部的身体节点
{
if(allBody.size()==0){return;}
for(auto bodynode:allBody)
{
switch (bodynode->m_dir) {
case ENUM_DIR::DIR_RIGHT:
bodynode->runAction(MoveBy::create(0.3, Point(32,0)));
bodynode->m_col++;
break;
case ENUM_DIR::DIR_LEFT:
bodynode->runAction(MoveBy::create(0.3, Point(-32,0)));
bodynode->m_col--;
break;
case ENUM_DIR::DIR_DOWN:
bodynode->runAction(MoveBy::create(0.3, Point(0,-32)));
bodynode->m_row--;
break;
case ENUM_DIR::DIR_UP:
bodynode->runAction(MoveBy::create(0.3, Point(0,32)));
bodynode->m_row++;
break;
default:
break;
}
}
//移动完毕之后,改变每一个body的方向
for(int i=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;
}
--------------------------------------------祝你成功-----------------------
Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例(全)的更多相关文章
- Cocos2d-x 3.0final 终结者系列教程16-《微信飞机大战》实现
看到cocos2d-x推出了3.1版本号,真是每月一次新版本号,速度. 另一个好消息就是http://cn.cocos2d-x.org/上线了,祝贺!啥时候把我的视频和教程放上去呢?!! . 视频下载 ...
- Cocos2d-x 3.0final 终结者系列教程01-无论是从cocos2d-x2.x升级到版本cocos2d-x3.x
诡谲的江湖,易变. 花花世界,车来人往. 最终确定.安家,将Cocos2d-x3.0final相关技术精加工的版本.并推出了博客文章, 不为他人,只为自己. 学习交流QQ群:301954471 --- ...
- Cocos2d-x 3.0final 终结者系列教程04-引擎架构分析
从前,有一个跟我来Android学生,总是问我: 沉老师,为什么Android的形式被称为Activity,为什么要onCreate方法写setContentView(R.layout.main)? ...
- Cocos2d-x 3.0final 终结者系列教程03-源代码文件夹说明
话说今天从霍营到回龙观,走到天鑫家园东路.我肋哥去,堵死我啦.7:30出门,9:10还没到回龙观. 北京这交通真是坑爹.回过头想想.怪自己走小路,有时候确实快.可有时候真堵. 堵了35分钟后果断掉头, ...
- Cocos2d-x 3.0final 终结者系列教程15-win7+vs2012+adt+ndk环境搭建(无Cygwin)
最终不用Cygwin 了.非常高兴 为什么要用Win7? 由于VS2012要求Win7以上系统才干安装! 为什么要用vs2012? 由于VS2012才支持C++11! 为什么要支持C++11? 由于C ...
- Cocos2d-x 3.0final 终结者系列教程02-开发环境的搭建
本文主要以Mac平台和XCode5为基本系统环境和C++编程工具来介绍Cocos2d-x3.0final版的安装. 一.系统准备(预计要花掉半个月工资) MacBook Pro一台(本人的比較老.11 ...
- Cocos2d-x 3.0final 终结者系列教程05-AppDelegate入口类
下面是Cocos2d-x的程序入口: class AppDelegate : private cocos2d::Application { public: AppDelegate(); virtua ...
- Cocos2d-x 3.0final 终结者系列教程14-L新abel-Cocos2d-x公文
目 录 新文本标签类Label 其它文本标签 字体制作工具使用介绍 小结 https://github.com/chukong/cocos-docs/blob/master/manual/framew ...
- Cocos2d-x 3.0final 终结者系列教程12-Vector&map&value
北京时间昨天下午,温40度.中午12:16我来到了篮球场点.思维1分钟决定开站 转球: 我和另一个3队友半开始, 我手中的球的那一刻我突然火爆球不稳,突然问,淡淡的味道橡胶和烧烤的味道混合. 个腾空跳 ...
随机推荐
- mysql 年龄计算(根据生日字段)
mysql 年龄计算(根据生日字段) year( from_days( datediff( now( ), birthdate))) //获取年龄 now() 当前时间,精确到秒 datediff(b ...
- java中强制类型转换时,高位数截取成低位数的方法
/** * 强制类型转换中的补码.反码.原码一搞清楚 */ int b=233;//正整数强转 System.out.println((byte)b); //负数:原码的绝对值取反再加一 符号为不变 ...
- 认识JDK、JRE、JVM
JDK.JRE.JVM之间的关系: 首先看看JDK与JRE的区别与联系,如下图所示: 由图可知: JDK = JRE + Tools&Tool APIs JDK的核心是Java SE API. ...
- invoke与call
“调用一个委托实例” 中的 “调用” 对应的是invoke,理解为 “唤出” 更恰当.它和后面的 “在一个对象上调用方法” 中的 “调用” 稍有不同,后则对应的是call.在英语的语境中,invoke ...
- EntityFramewok 插入Mysql数据库 中文产生乱码解决
首先Mysql表,建表的时候,有没有选择UTF8,如果是默认的编码latin1,就会产生乱码 这里修改后,还是乱码,那就要检查发生乱码的列是不是UTF8格式 然后修改App.Config或者Web.C ...
- buf.readInt32LE函数详解
offset {Number} 0 noAssert {Boolean} 默认:false 返回:{Number} 从该 Buffer 指定的带有特定尾数格式(readInt32BE() 返回一个较大 ...
- 易企CMS仿站标签说明
头部标签: 每个页面都必须加的三大标签(将标签放入header.tpl里面,这样只需在每个模板中调用header.tpl即可): <title>{$seotitle}_{$sitename ...
- 省市区县的sql语句——城市
/*SQLyog v10.2 MySQL - 5.5.48 : Database - 省市县****************************************************** ...
- 装X数学:高雅的数学表示
采用高雅的数学描述 转自于:研究生之路怎么走? 高雅的数学描述会提高你论文的等级和加强评审人对你基础功底的认可.例如泛函分析.集合.测度.度量空间和拓扑空间.现代代数.微分几何等数学方面的 ...
- OpenCV视频进度播放控制
本来打算把进度条嵌入MFC的PIC空间里面,结果显示进度条消失,看来还是不要这个样子了. 全局变量区域: //2.初始化进度条的位置 int G_slider_position = 0; CvCapt ...