cocos2d-x开发日志10 ——贪食蛇源码
2015-08-18 20:01
525 查看
简单的游戏开发,比较适合和我一样的小白练手,除了游戏结束场景,全部包含在了HelloWorldScene中,先上源码,注释已经比较全面,但是具体细节会陆续更新。
HelloWorldScene.h
HelloWorldScene.cpp
GameOverScene.h
GameOverScene.cpp
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "GameOverScene.h" #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> using namespace cocos2d; using namespace std; //贪食蛇移动方向 typedef enum{ UP=1, DOWN, LEFT, RIGHT }DIR_DEF; //蛇的头 身体 食物 共用这个node class SnakeNode:public Node{ public: int row; //行 int col; //列 int dir; //方向 DrawNode *pic;//要加载的图片 }; //欢迎场景 class HelloWorld : public Layer{ public: virtual bool init();//初始化函数 static Scene * createScene();//获取欢迎画面的scene void menuCloseCallback(Ref * pSender); CREATE_FUNC(HelloWorld); }; //帮助画面 class GameHelp: public Layer{ public: virtual bool init(); static Scene * createScene(); CREATE_FUNC(GameHelp); void menuBackToMain(Ref * pSender); }; //游戏画面 class GameLayer : public Layer{ protected: bool pause_resume=0;//是否暂停 0为继续,1为暂停 SnakeNode *sHead;//贪食蛇的头部 SnakeNode *sFood;//食物 Vector <SnakeNode*> allbody;//身体 //暂存起点坐标 网格单位长度 int ox = 50; int oy = 60; int unit =20; //获得分数 int score = 0; public: //初始化 virtual bool init(); static Scene * createScene(); CREATE_FUNC(GameLayer); //游戏逻辑 void logic01(float t); void menuBackToMain( Ref * pSender);//返回主菜单 }; #endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp
#include "HelloWorldScene.h" #define START_TAG 10 #define HELP_TAG 11 #define EXIT_TAG 12 #define MAINMENU_TAG 13 #define UP_TAG 14 #define DOWN_TAG 15 #define LEFT_TAG 16 #define RIGHT_TAG 17 #define PAUSE_TAG 18 #define SCORE_TAG 19 #define MENU_TAG 20 USING_NS_CC; using namespace cocos2d; //************************************************************************// //** **// //** 欢迎界面 **// //** **// //************************************************************************// //欢迎界面方法 Scene * HelloWorld::createScene(){ Scene * scene = Scene::create(); HelloWorld * layer = HelloWorld::create(); scene-> addChild(layer); return scene; } //欢迎界面初始化方法 bool HelloWorld::init(){ if (!Layer::init()) return false; //游戏名称标签 auto label = Label::createWithTTF("SNAKE", "fonts/Marker Felt.ttf", 50); label->setColor(Color3B(0,120,100)); label->setPosition(Director::getInstance()->getWinSize().width/2, Director::getInstance()->getWinSize().height/2+ label->getContentSize().height*1.5); this->addChild(label); //开始 按钮 auto start = Label::createWithTTF("Start Game", "fonts/Marker Felt.ttf", 24); start->setColor(Color3B(0,255,0)); auto start_button = MenuItemLabel::create(start,CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); start_button->setPositionY(start->getPositionY()+start_button->getContentSize().height*1.5); start_button->setTag(START_TAG); //帮助 按钮 auto help = Label::createWithTTF("Help", "fonts/Marker Felt.ttf", 24); help->setColor(Color3B(0,0,255)); auto help_button = MenuItemLabel::create(help,CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); help_button->setTag(HELP_TAG); //退出 按钮 auto exit = Label::createWithTTF("Exit", "fonts/Marker Felt.ttf", 24); exit->setColor(Color3B(200,0,200)); auto exit_button = MenuItemLabel::create(exit,CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); exit_button->setPositionY(start->getPositionY()-exit_button->getContentSize().height*1.5); exit_button->setTag(EXIT_TAG); //新建菜单 auto menu = Menu::create(start_button,help_button,exit_button,NULL); this->addChild(menu); return true; } //欢迎界面菜单回调函数 void HelloWorld::menuCloseCallback(Ref * pSender){ switch (((MenuItemLabel*)pSender)->getTag()) { case START_TAG:{ auto scene = GameLayer::createScene(); Director::getInstance()->replaceScene(scene); break; } case HELP_TAG:{ auto scene = GameHelp::createScene(); Director::getInstance()->replaceScene(scene); break; } case EXIT_TAG: Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif break; default: break; } } //************************************************************************// //** **// //** 帮助界面 **// //** **// //************************************************************************// //帮助画面方法 Scene * GameHelp::createScene(){ auto scene = Scene::create(); auto layer = GameHelp::create(); scene-> addChild(layer); return scene; } //帮助画面初始化方法 bool GameHelp::init(){ if (!Layer::init()) return false; //帮助文字 auto label = Label::createWithTTF("DO NOT TELL ME YOU CAN'T DO THIS ,YOU FOOL!", "fonts/Marker Felt.ttf", 24); label->setColor(Color3B(200,70,200)); label->setPosition(Director::getInstance()->getWinSize().width/2, Director::getInstance()->getWinSize().height/2+50); this->addChild(label); //返回主菜单 按钮 auto MainMenu = Label::createWithTTF("Main Menu", "fonts/Marker Felt.ttf", 24); MainMenu->setColor(Color3B(0,200,200)); auto MainMenu_button = MenuItemLabel::create(MainMenu,CC_CALLBACK_1(GameHelp::menuBackToMain, this)); MainMenu_button->setPositionY(MainMenu_button->getPositionY()-50); MainMenu_button->setTag(EXIT_TAG); //新建菜单 auto menu = Menu::create(MainMenu_button,NULL); this->addChild(menu); return true; } //帮助画面菜单回调方法 void GameHelp::menuBackToMain(Ref * pSender){ auto scene = HelloWorld::createScene(); Director::getInstance()->replaceScene(scene); } //************************************************************************// //** **// //** 游戏界面 **// //** **// //************************************************************************// //游戏界面方法 Scene * GameLayer:: createScene(){ auto scene = Scene::create(); auto layer = GameLayer::create(); scene->addChild(layer); return scene; } bool GameLayer::init(){ if (!Layer::init()) return false; //返回主菜单 按键 auto MainMenu = Label::createWithTTF("Main Menu", "fonts/Marker Felt.ttf", 24); MainMenu->setColor(Color3B(0,200,200)); auto MainMenu_button = MenuItemLabel::create(MainMenu,CC_CALLBACK_1(GameLayer::menuBackToMain, this)); MainMenu_button->setTag(0); MainMenu_button->setPosition(Director::getInstance()->getWinSize().width*0.3, -Director::getInstance()->getWinSize().height*0.3); //暂停 按键 auto pause = Label::createWithTTF("PAUSE", "fonts/Marker Felt.ttf", 24); pause->setColor(Color3B(255,100,100)); auto pause_button = MenuItemLabel::create(pause,CC_CALLBACK_1(GameLayer::menuBackToMain, this)); pause_button->setTag(PAUSE_TAG); pause_button->setPosition(Director::getInstance()->getWinSize().width*0.3, -Director::getInstance()->getWinSize().height*0.3+140); //向上 按键 auto up = Label::createWithTTF("UP", "fonts/Marker Felt.ttf", 24); up->setColor(Color3B(0,255,0)); auto up_button = MenuItemLabel::create(up,CC_CALLBACK_1(GameLayer::menuBackToMain, this)); up_button->setTag(UP_TAG); up_button->setPosition(Director::getInstance()->getWinSize().width*0.3, -Director::getInstance()->getWinSize().height*0.3+100); //向下 按键 auto down = Label::createWithTTF("DOWN", "fonts/Marker Felt.ttf", 24); down->setColor(Color3B(0,255,0)); auto down_button = MenuItemLabel::create(down,CC_CALLBACK_1(GameLayer::menuBackToMain, this)); down_button->setTag(DOWN_TAG); down_button->setPosition(Director::getInstance()->getWinSize().width*0.3, -Director::getInstance()->getWinSize().height*0.3+40); //向左 按键 auto left = Label::createWithTTF("LEFT", "fonts/Marker Felt.ttf", 24); left->setColor(Color3B(0,255,0)); auto left_button = MenuItemLabel::create(left,CC_CALLBACK_1(GameLayer::menuBackToMain, this)); left_button->setTag(LEFT_TAG); left_button->setPosition(Director::getInstance()->getWinSize().width*0.3-30, -Director::getInstance()->getWinSize().height*0.3+70); //向右 按键 auto right = Label::createWithTTF("RIGHT", "fonts/Marker Felt.ttf", 24); right->setColor(Color3B(0,255,0)); auto right_button = MenuItemLabel::create(right,CC_CALLBACK_1(GameLayer::menuBackToMain, this)); right_button->setTag(RIGHT_TAG); right_button->setPosition(Director::getInstance()->getWinSize().width*0.3+30, -Director::getInstance()->getWinSize().height*0.3+70); //新建菜单 auto menu = Menu::create(MainMenu_button,up_button,left_button,down_button,right_button,pause_button,NULL); this->addChild(menu); menu->setTag(MENU_TAG); //显示分数 char a[3] ; stringstream stream; stream << score; stream >> a; auto score_label = Label::createWithTTF (a, "fonts/Marker Felt.ttf", 40); score_label->setPosition(Director::getInstance()->getWinSize().width*0.8, Director::getInstance()->getWinSize().height*0.8); score_label->setTag(SCORE_TAG); this->addChild(score_label); //设置网格 for(int i=0; i<11; i++){ for(int j=0; j<11 ;j++){ auto head1 = DrawNode::create(); head1->drawDot(Point(0,0), 1, Color4F(1, 1, 1, 0.5)); head1->setPosition(Vec2(ox+unit*i, oy+unit*j)); this->addChild(head1,4); } } //初始化蛇头 sHead = new SnakeNode(); sHead->row = arc4random()%10; sHead->col = arc4random()%10; sHead->dir = arc4random()%4+1; CCLOG("%d %d",sHead->row,sHead->col); sHead->pic = DrawNode::create(); sHead->pic->drawSolidRect(Point(0,0),Point(unit,unit),Color4F(1, 0, 0, 0.8)); sHead->pic->setPosition(Vec2(ox+sHead->col*unit,oy+sHead->row*unit)); this->addChild(sHead->pic,2); //初始化食物 sFood = new SnakeNode; sFood->row = arc4random()%10; sFood->col = arc4random()%10; sFood->pic = DrawNode::create(); sFood->pic->drawSolidRect(Point(0,0),Point(unit,unit), Color4F(1,1,1,1)); sFood->pic->setPosition(Vec2(ox+sFood->col*unit,oy+sFood->row*unit)); this->addChild(sFood->pic,2); //初始化身体 //allbody.reserve(1); //执行计划任务 this->schedule(schedule_selector(GameLayer::logic01), 0.8); return true; } //游戏界面菜单回调方法 void GameLayer::menuBackToMain( Ref * pSender){ auto p = (MenuItemLabel*)pSender; switch (p->getTag()) { case 0:{ auto scene = HelloWorld::createScene(); Director::getInstance()->replaceScene(scene); break; } case UP_TAG:{ if(sHead->dir!=DIR_DEF::DOWN) sHead->dir = DIR_DEF::UP; break; } case DOWN_TAG:{ if(sHead->dir!=DIR_DEF::UP) sHead->dir = DIR_DEF::DOWN; break; } case LEFT_TAG:{ if(sHead->dir!=DIR_DEF::RIGHT) sHead->dir = DIR_DEF::LEFT; break; } case RIGHT_TAG:{ if(sHead->dir!=DIR_DEF::LEFT) sHead->dir = DIR_DEF::RIGHT; break; } case PAUSE_TAG:{ if(pause_resume == 0){ pause_resume = 1; unschedule(schedule_selector(GameLayer::logic01)); MenuItemLabel* l = (MenuItemLabel*)this->getChildByTag(MENU_TAG)-> getChildByTag(PAUSE_TAG); l->setString("RESUME"); } else{ //Director::getInstance()->resume(); pause_resume = 0; schedule(schedule_selector(GameLayer::logic01), 0.8); MenuItemLabel * l = (MenuItemLabel*)this->getChildByTag(MENU_TAG)->getChildByTag(PAUSE_TAG); l->setString("PAUSE"); } break; } default: break; } } //计划任务 void GameLayer::logic01(float t){ //移动身体 for (int i = allbody.size()-1; i>=0; i--) { SnakeNode * sn = allbody.at(i); if (i>0) { auto snpre = allbody.at(i-1); sn->dir = snpre->dir; sn->row = snpre->row; sn->col = snpre->col; } //移动第一个节点 else if (i==0) { sn->dir = sHead->dir; sn->row = sHead->row; sn->col = sHead->col; } } //移动蛇头 switch (sHead->dir) { case DIR_DEF::UP:{ sHead->row++; if(sHead->row >= 10) sHead->row = 0; break; } case DIR_DEF::DOWN:{ sHead->row--; if(sHead->row < 0) sHead->row = 9; break; } case DIR_DEF::LEFT:{ sHead->col--; if(sHead->col < 0) sHead->col = 9; break; } case DIR_DEF::RIGHT:{ sHead->col++; if(sHead->col >= 10) sHead->col = 0; break; } } //头结点重置图像位置 sHead->pic->setPosition(Vec2(ox+sHead->col*unit,oy+sHead->row*unit)); //碰撞检测 if(sHead->row==sFood->row && sHead->col==sFood->col){ score ++; char a[3] ; stringstream stream; stream << score; stream >> a; auto l =(Label *)this->getChildByTag(SCORE_TAG); l->setString(a); //食物消失 while(1){ bool flag = true; sFood->row = rand()%10; sFood->col = rand()%10; for (int i=0; i<allbody.size(); i++) { if(allbody.at(i)->row==sFood->row && allbody.at(i)->col==sFood->col) flag = false; } if(flag == true) break; } sFood->pic->setPosition(Vec2(ox+sFood->col*unit,oy+sFood->row*unit)); //添加身体到集合 SnakeNode * sn; sn = new SnakeNode; SnakeNode *lastNode; if (allbody.size()>0) lastNode = allbody.at(allbody.size()-1); else lastNode = sHead; switch (lastNode->dir) { case DIR_DEF::UP: sn->row = lastNode->row-1; sn->col = lastNode->col; break; case DIR_DEF::DOWN: sn->row = lastNode->row+1; sn->col = lastNode->col; break; case DIR_DEF::LEFT: sn->row = lastNode->row; sn->col = lastNode->col+1; break; case DIR_DEF::RIGHT: sn->row = lastNode->row; sn->col = lastNode->col-1; break; } sn->dir = lastNode->dir; this->allbody.pushBack(sn); sn->pic = DrawNode::create(); sn->pic->drawSolidRect(Point(0,0),Point(unit,unit),Color4F(0, 1, 0, 0.8)); sn->pic->setPosition(Vec2(ox+sn->col*unit,oy+sn->row*unit)); this->addChild(sn->pic); } //重置身体位置 for (int i = 0; i<allbody.size(); i++) { allbody.at(i)->pic->setPosition(Vec2(ox+allbody.at(i)->col*unit,oy+allbody.at(i)->row*unit)); } //game over 判定 for (int i=0; i<allbody.size(); i++) if(allbody.at(i)->row==sHead->row && allbody.at(i)->col==sHead->col){ auto scene = GameOver::createScene(); Director::getInstance()->replaceScene(scene); } }
GameOverScene.h
// // GameOverScene.h // snakegame // // Created by jiumiao on 15/8/9. // // #ifndef __snakegame__GameOverScene__ #define __snakegame__GameOverScene__ #include <stdio.h> #include "cocos2d.h" #include "HelloWorldScene.h" USING_NS_CC; class GameOver : public Layer{ public: bool init();//初始化函数 static Scene * createScene();//获取欢迎画面的scene void menuCloseCallback(Ref * pSender); CREATE_FUNC(GameOver); }; #endif /* defined(__snakegame__GameOverScene__) */
GameOverScene.cpp
// // GameOverScene.cpp // snakegame // // Created by jiumiao on 15/8/9. // // #include "GameOverScene.h" //初始化函数 bool GameOver:: init(){ if(!Layer::init()) return false; //Game Over auto label = Label::createWithTTF("Game Over", "fonts/Marker Felt.ttf", 50); label->setColor(Color3B(255,120,100)); label->setPosition(Director::getInstance()->getWinSize().width/2, Director::getInstance()->getWinSize().height/2+ label->getContentSize().height*1.5); this->addChild(label); //返回游戏 按钮 auto tryagain = Label::createWithTTF("Try Again", "fonts/Marker Felt.ttf", 24); tryagain->setColor(Color3B(0,200,200)); auto tryagain_button = MenuItemLabel::create(tryagain,CC_CALLBACK_1(GameOver::menuCloseCallback, this)); tryagain_button->setPositionY(tryagain_button->getPositionY()-50); tryagain_button->setTag(20); auto menu = Menu::create(tryagain_button,NULL); this->addChild(menu); return true; } //获取结束画面 Scene * GameOver::createScene(){ auto scene = Scene::create(); auto layer = GameOver::create(); scene-> addChild(layer); return scene; } void GameOver::menuCloseCallback(Ref * pSender){ auto scene = GameLayer::createScene(); Director::getInstance()->replaceScene(scene); }
相关文章推荐
- cocos2d-x开发日志09 —— Vector
- cocos2d-x开发日志08 —— 绘图工具
- 【Cocos2dx】Windows平台下Cocos2dx 2.x的下载、安装、配置,打造自己的Helloworld
- cocos-2dx 渲染(2)
- cocos2dx android mac
- Cocos2d-x之简单数据存储 — Userdefault
- Cocos2d-x3.2 UserDefault用户数据
- cocos2d-x3.0中图片分辨率自动适配设置以及源码,原理分析。
- Cocos2d-x 屏幕适配新解
- cocos2d-x 屏幕分辨率适配方法
- COCOS2D-X 多分辨率适配完全解析
- Cocos2dx-Android 之Makefile通用高级写法
- cocoside报Failed to load the JNI shared library
- cocos js 代码修改button背景图等,调用cocos studio 界面(斗地主)
- 在 cocos2d-x 中使用 libcurl 实现上传文件功能(附quick-cocos2d-x封装)
- cocos2dx接入微信分享!
- quick-cocos2d-x endToLua 退出会卡住
- Cocos3d-x 发布第一版
- cocos 给绑定类加一个命名空间
- cocos2d-js添加百通广告(通过jsb反射机制)