簡單的遊戲開發,比較適合和我一樣的小白練手,除了遊戲結束情境,全部包含在了HelloWorldScene中,先上源碼,注釋已經比較全面,但是具體細節會陸續更新。
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;//蛇的頭 身體 食物 共用這個nodeclass 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 20USING_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);}