现在就是最主要也是较为复杂的界面和逻辑类了。
他实际包含两个类,一个SnakeNode蛇结点类和一个Game界面逻辑类。
绘制10*10的网格,初始化一个食物和一个蛇头,随机的坐标,然后定时移动蛇头,碰到食物则吃掉并产生一个身体结点,碰撞检测,到边界就结束返回主界面。
GameScene.h:
#pragma execution_character_set("utf-8")#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_DIR m_dir; //移动方向 int nodeType; //节点类型: 1蛇头 2 身体 3 食物 int m_row,m_col; //当前节点的行列坐标public: static SnakeNode* create(int type);//!!! virtual bool init(int type); voID setpositionRC(int row,int col);//设置节点的坐标};class Game:public Layer{public: //enum RESolUTION{ // NET_SIZE = 64, // NET_WIDTH = 640 // _WIDTH = 960, // _HEIGHT = 640 //}; SnakeNode * spFood;//食物 SnakeNode * sphead;//蛇头 int m_score; Vector<SnakeNode *> allBody;//身体!!! static Scene * createScene(); CREATE_FUNC(Game); virtual bool init();public: voID menuCallBack(Ref * object); voID gameLogic(float t); voID newBody();//添加一个新的身体节点 voID moveBody();//移动所有的身体节点};#endif /* defined(__snakegame__GameScene__) */
GameScen.cpp:
#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;//向右移动 m_row = 0;//初始化蛇头的位置 m_col = 0; } 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;}enum RESolUTION{ NET_SIZE = 32,NET_WIDTH = 320};voID SnakeNode::setpositionRC(int row,int col)//设置节点的坐标{ this->m_row = row; this->m_col = col; setposition(Point(col * NET_SIZE,row * NET_SIZE));}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,NET_SIZE * i),Point(NET_WIDTH,1,color4F(1,1)); draw->drawSegment(Point(NET_SIZE * i,0),Point(NET_SIZE * i,NET_WIDTH),1)); } //添加蛇头 sphead = SnakeNode::create(1); this->addChild(sphead); //添加身体 //添加食物 spFood = SnakeNode::create(3); //float i = CCRANDOM_0_1()*(end - start + 1) + start; 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::createWithSystemFont("分数: 0","宋体",25); //auto labelscore = Label::createWithSystemFont("score: 0","AdobeHeitiStd-Regular",25); labelscore->setTag(110); labelscore->setposition(Point(size.wIDth - 80,size.height - 50)); this->addChild(labelscore); //返回按钮 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.5f); //加入用户触摸事件侦听 auto Listener = EventListenertouchOneByOne::create(); Listener->setSwallowtouches(true); Listener->ontouchBegan = [&](touch * t,Event * e){ //改变贪食蛇移动的方向 int col = t->getLocation().x / NET_SIZE; int row = t->getLocation().y / NET_SIZE; int spheadCol = sphead->getpositionX() / NET_SIZE; int spheadRow = sphead->getpositionY() / NET_SIZE; 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.3f,Point(NET_SIZE,0))); sphead->m_coL++; break; case ENUM_DIR::DIR_left: sphead->runAction(MoveBy::create(0.3f,Point(-NET_SIZE,0))); sphead->m_col--; break; case ENUM_DIR::DIR_DOWN: sphead->runAction(MoveBy::create(0.3f,Point(0,-NET_SIZE))); sphead->m_row--; break; case ENUM_DIR::DIR_UP: sphead->runAction(MoveBy::create(0.3f,NET_SIZE))); sphead->m_row++; break; default: break; } //add Todo if (sphead->m_row < 0 || sphead->m_col < 0 || sphead->m_row > 9 || sphead->m_col > 9) { auto scene = MainMenu::createScene(); Director::getInstance()->replaceScene(scene); } //碰撞检测 if (sphead->m_row == spFood->m_row&& sphead->m_col == spFood->m_col) { //音效的播放 SimpleAudioEngine::getInstance()->playEffect("eat.wav"); //分数增加 this->m_score += 100; auto label = (Label *)this->getChildByTag(110); char strscore[20]; sprintf(strscore,"分数: %d",m_score); label->setString(strscore); //食物产生新的位置 int row = rand() % 10;//0-9 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.3f,0))); bodynode->m_coL++; break; case ENUM_DIR::DIR_left: bodynode->runAction(MoveBy::create(0.3f,0))); bodynode->m_col--; break; case ENUM_DIR::DIR_DOWN: bodynode->runAction(MoveBy::create(0.3f,-NET_SIZE))); bodynode->m_row--; break; case ENUM_DIR::DIR_UP: bodynode->runAction(MoveBy::create(0.3f,NET_SIZE))); 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;}
源码和资源下载地址:
http://download.csdn.net/detail/a379039233/8968853
以上是内存溢出为你收集整理的Cocos2d-x 3.6 项目实战---贪吃蛇(4)全部内容,希望文章能够帮你解决Cocos2d-x 3.6 项目实战---贪吃蛇(4)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)