#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_NS_CC; //枚举类型DIR_DEF,分别标识贪食蛇的移动方向 typedef enum { UP=1, DOWN, LEFT, RIGHT }DIR_DEF; //蛇每个节点都有自己的移动方向,因此,在节点类SnakeNode的定义中包含了行、列和方向3个成员 class SnakeNode :public cocos2d::Ref { public: int row;//行 int col;//列 int dir;//方向 }; //游戏欢迎画面,这个大家很熟的 class HelloWorld : public cocos2d::Layer { public: static cocos2d::Scene* createScene();//获取欢迎画面的Scene virtual bool init(); virtual void onEnter(); virtual void onExit(); CREATE_FUNC(HelloWorld); }; //游戏帮助画面 class GameHelp :public cocos2d::Layer { public : virtual bool init(); virtual void onEnter(); virtual void onExit(); static cocos2d::Scene * createScene();//获取帮助画面 CREATE_FUNC(GameHelp); }; //游戏画面 class GameLayer :public cocos2d::Layer { public : static cocos2d::Scene * createScene();//获取游戏画面 virtual bool init(); virtual void onEnter(); virtual void onExit(); virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;//实现当前Layer的定义 void onAcceleration(Acceleration* acc, Event* event);//重力事件的回调 void logic01(float t);//update的回调 CREATE_FUNC(GameLayer); protected: SnakeNode *sHead; //贪食蛇px py SnakeNode *sFood; //食物 cocos2d::Vector<Ref*> allBody;//蛇的身体,放到容器Vector中 // cocos2d::Texture2D * chead; }; #endif // __HELLOWORLD_SCENE_H__
//添加项菜单进入游戏游戏、帮助、退出游戏的按钮 auto labelstart = LabelTTF::create("startGame","宋体",24); auto labelhelp = LabelTTF::create("GameHelp","宋体",24); auto labelexit = LabelTTF::create("exitGame","宋体",24); //进入游戏按钮 auto mi01 = MenuItemLabel::create(labelstart,[](Ref* sender) { CCLOG("go to game"); Director::getInstance()->replaceScene(GameLayer::createScene());//跳转到游戏场景 }); mi01->setPosition(Point(100,200)); //帮助按钮 auto mi02 = MenuItemLabel::create(labelhelp,[](Ref* sender) { CCLOG("go to help"); Director::getInstance()->replaceScene(GameHelp::createScene());//跳转到帮助场景 }); mi02->setPosition(Point(100,150)); //结束游戏 auto mi03 = MenuItemLabel::create(labelexit,[](Ref* sender) { CCLOG("exit the game"); Director::getInstance()->end();//退出游戏 }); mi03->setPosition(Point(100,50)); auto pMenu = Menu::create(mi01,mi02,mi03, NULL); pMenu->setPosition(Point::ZERO); this->addChild(pMenu, 1);2、帮助界面其实就一menu,所以我就不啰嗦介绍了,直接看下游戏界面的代码实现:
void GameLayer::onEnter() { Layer::onEnter(); CCLOG("GameLayer onEnter"); Device::setAccelerometerEnabled(true);//打开设备的重力感应 auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(HelloWorld::onAcceleration, this));//创建一个重力监听事件 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);//将listener放到事件委托中 }2)在init()中初始化蛇头和食物的坐标,并开启定时器实时更新蛇的坐标
bool GameLayer::init() { if ( !Layer::init() ) { return false; } auto labhelp = LabelTTF::create("this is game","宋体",15); labhelp->setPosition(Point(0,340)); this->addChild(labhelp); auto labback = LabelTTF::create("MainMenu","宋体",15); auto miback = MenuItemLabel::create(labback,[](Ref* sender) { Director::getInstance()->replaceScene(HelloWorld::createScene()); }); miback->setPosition(Point(360,200)); //chead=::CCTextureCache::sharedTextureCache()->addImage("head.png"); //初始化蛇头坐标和食物的坐标,用下面这种方法随机出来的坐标每次运行时都是一样一样的...... sHead = new SnakeNode(); sHead->row = rand()%10; sHead->col = rand()%10; //初始化食物的坐标 sFood = new SnakeNode(); sFood->row = rand()%10; sFood->col = rand()%10; //执行定时任务 this->schedule(schedule_selector(GameLayer::logic01),0.5); return true; }
//定时器 void GameLayer::logic01(float t) { //移动蛇的身体 for(int i = allBody.size()-1; i>=0; i--) { SnakeNode * sn = (SnakeNode *)allBody.at(i);//获取蛇身体上的某个节点 if(i>0) { //如果该节点不是第一个节点,那么该节点的下一个坐标就是其前一个点的坐标(这里不用多解释,玩过蛇的都懂) SnakeNode * snpre = (SnakeNode *)allBody.at(i-1);//获取前一个节点,把前一个节点的方向,坐标传给当前节点 sn->dir = snpre->dir; sn->row = snpre->row; sn->col = snpre->col; } else if(i==0) { //如果i=0则是第一个节点,蛇头的坐标便是该节点的坐标 sn->dir = sHead->dir; sn->row = sHead->row; sn->col = sHead->col; } } //移动蛇头,根据dir来判断蛇头的移动方向 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; }; //碰撞检测 //如果蛇头的横、列位置一样,说明蛇吃到了这个食物 if(sHead->row == sFood->row && sHead->col == sFood->col) { //食物从当前位置消失,随机出现在下一个坐标 sFood->row = rand()%10; sFood->col = rand()%10; //添加身体到集合 SnakeNode * sn = new SnakeNode();//创建一个新的节点(也就是吃掉的那个食物),将其放到蛇的尾巴上 SnakeNode * lastNode = NULL; //获取蛇的最后一个节点,如果allBody的size()为0,则说明蛇是第一次捕食,那么它的最后一个节点也就是蛇头啦。 if(allBody.size()>0) lastNode = (SnakeNode *)allBody.back(); 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; } this->allBody.pushBack(sn);//将新的节点加入到蛇的身体中。 } }3)通过draw()绘制游戏界面的格子与食物等
void GameLayer::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) { ///绘制形状 ::glLineWidth(2);//设定画线的宽度 for(int i=0;i<11;i++) { DrawPrimitives::drawLine(Point(0,i*32),Point(320,i*32));//绘制条横线 DrawPrimitives::drawLine(Point(i*32,0),Point(i*32,320));//绘制条竖线 } // RGBA //DrawPrimitives::drawColor4B(ccc4(255,0,0,255));//设定画线的颜色 //绘制蛇头 DrawPrimitives::drawSolidRect(Point(sHead->col*32+2,sHead->row*32+2), Point(sHead->col*32+32,sHead->row*32+32), Color4F(Color3B(255,0,0))); //绘制食物 DrawPrimitives::drawSolidRect(Point(sFood->col*32+2,sFood->row*32+2), Point(sFood->col*32+32,sFood->row*32+32), Color4F(Color3B(0,0,255))); //绘制身体 for(int i=0;i<allBody.size();i++) { SnakeNode * node=(SnakeNode *)allBody.at(i); DrawPrimitives::drawSolidRect(Point(node->col*32+2,node->row*32+2), Point(node->col*32+32,node->row*32+32), Color4F(Color3B(0,0,255))); } /*Rect r(340,0,57,57); chead->drawInRect(r); Layer::draw();*/ }4)通过重力的回调函数来更新蛇的移动方向
void GameLayer::onAcceleration(Acceleration* acc, Event* event) { //0.5这东西很微妙的说 if(acc->x<=-0.5) { sHead->dir=DIR_DEF::LEFT; log("LEFT"); } else if(acc->x>=0.5) { sHead->dir=DIR_DEF::RIGHT; log("RIGHT"); } else if(acc->y<=-0.5) { sHead->dir=DIR_DEF::DOWN; log("DOWN"); } else if(acc->y>=0.5) { sHead->dir = DIR_DEF::UP; log("UP"); } else { ; } }
恩,差不都就是这样了。最后附上游戏截图,如果觉得游戏画面您还满意的话,请给我点32个赞!谢谢!~:
看到这里有的人可能要吐槽了,为什么没有写当蛇撞到尾巴会结束游戏的处理。原因很简单,因为我...懒...。就如开头说的那样,该篇的主要目的是通过一个例子来较为系统的介绍cocos2dx2.0与3.0一些不同的地方。
触摸版链接:http://blog.csdn.net/star530/article/details/24287909
尊重原创,转载请注明来源:http://blog.csdn.net/start530/article/details/23707985