Recently, cocos2dx forums have witnessed a wave of coathile snake production trends. I am also planning to join in. However, the main purpose is to write a series of blogs in the 3.0 transition articles, which talk about theories and lacks practice. This time we will use the example of a greedy snake to systematically introduce some differences between 3.0 and 2.0. (Of course, some people will say that I am a book from teacher Shen Dahai. This kind of thing cannot be tolerated !, I want to explain with caution: My shipping address is ...)
------------------
Everyone knows about the snake. It's a long, thin, scalable, and elastic snake.
First, we will introduce the following game production process:
1. There are three scenarios in the game: HelloWorld, GameHelp, and GameLayer ).
2. events to be handled in game scenarios include:
A. Enable gravity sensing and use the onAcceleration () callback function to determine the direction in which the snake should move;
B. Use the draw () method to customize the layer display content, such as the grid, Snake Head, body, and food on the interface;
C. update the snake location in real time through the update timer.
3. Continue reading .......
The code is implemented as follows:
First look at the. h header file:
# Ifndef _ HELLOWORLD_SCENE_H __# define _ HELLOWORLD_SCENE_H __# include "cocos2d. h "USING_NS_CC; // Enumeration type DIR_DEF, which respectively identifies the movement direction of the snake typedef enum {UP = 1, DOWN, LEFT, RIGHT} DIR_DEF; // each node of the snake has its own direction of movement. Therefore, the definition of the node-class snkenode contains the row, column, and direction members class snakkenode: public cocos2d :: ref {public: int row; // row int col; // column int dir; // direction}; // welcome to the game. This is a well-known class HelloWorld: public cocos2d:: Layer {public: static cocos2d: Scene * createScene (); // obtain the Scene virtual bool init (); virtual void onEnter (); virtual void onExit (); CREATE_FUNC (HelloWorld) ;}; // game help image class GameHelp: public cocos2d: Layer {public: virtual bool init (); virtual void onEnter (); virtual void onExit (); static cocos2d: Scene * createScene (); // get the help image CREATE_FUNC (GameHelp) ;}; // Game Image class GameLayer: public cocos2d :: layer {public: static cocos2d: Scene * createScene (); // obtain the virtual bool init (); virtual void onEnter (); virtual void onExit (); virtual void draw (Renderer * renderer, const kmMat4 & transform, bool transformUpdated) override; // implement the definition of the current Layer void onAcceleration (Acceleration * acc, Event * event ); // gravity Event Callback void logic01 (float t); // update callback CREATE_FUNC (GameLayer); protected: snkenode * sHead; // greedy snake px pysnkenode * sFood; // cocos2d: Vector
AllBody; // put the snake's body in the Vector container // cocos2d: Texture2D * chead;}; # endif/_ HELLOWORLD_SCENE_H __
The comment on the header file is still clear, so after reading it, you should have a certain concept on the game process and continue.
1. The main code for creating the main menu interface is as follows:
// Add the item menu to enter the game, help, and exit buttons auto labelstart = LabelTTF: create ("startGame", "", 24); auto labelhelp = LabelTTF :: create ("GameHelp", "", 24); auto labelexit = LabelTTF: create ("exitGame", "", 24 ); // enter the game button auto mi01 = MenuItemLabel: create (labelstart, [] (Ref * sender) {CCLOG ("go to game"); Director: getInstance () -> replaceScene (GameLayer: createScene (); // jump to game scenario}); mi01-> setPosition (Point (100,200); // HELP button auto mi02 = MenuItemLabel:: create (labelhelp, [] (Ref * sender) {CCLOG ("go to help"); ctor: getInstance ()-> replaceScene (GameHelp: createScene ()); // jump to the help scenario}); mi02-> setPosition (Point (100,150); // end game auto mi03 = MenuItemLabel: create (labelexit, [] (Ref * sender) {CCLOG ("exit the game"); Director: getInstance ()-> end (); // exit the game}); mi03-> setPosition (Point )); auto pMenu = Menu: create (mi01, mi02, mi03, NULL); pMenu-> setPosition (Point: ZERO); this-> addChild (pMenu, 1 );
2. The help interface is actually a menu, so I will not explain it. Let's look at the code implementation of the game interface:
1) enable gravity sensing in onEnter ().
Void GameLayer: onEnter () {Layer: onEnter (); CCLOG ("GameLayer onEnter"); Device: setAccelerometerEnabled (true ); // enable the device's gravity sensing auto listener = EventListenerAcceleration: create (CC_CALLBACK_2 (HelloWorld: onAcceleration, this )); // create a gravity listener Event _ eventDispatcher-> addEventListenerWithSceneGraphPriority (listener, this); // put the listener in the event Delegate}
2) initialize the coordinates of the Snake Head and food in init (), and enable the timer to update the coordinates of the snake in real time.
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 "); // initialize the coordinates of the Snake Head and the food. The coordinates randomly generated in the following method are the same during each operation ...... sHead = new snail kenode (); sHead-> row = rand () % 10; sHead-> col = rand () % 10; // initialize the coordinates of the food. sFood = new snail kenode (); sFood-> row = rand () % 10; sFood-> col = rand () % 10; // execute the scheduled task this-> schedule (schedule_selector (GameLayer: logic01), 0.5); return true ;}
// Timer void GameLayer: logic01 (float t) {// the body of the mobile snake for (int I = allBody. size ()-1; I> = 0; I --) {SnakeNode * sn = (SnakeNode *) allBody. at (I); // obtain a node in the snake body if (I> 0) {// if the node is not the first node, the next coordinate of the node is the coordinate of the previous vertex (you don't need to explain it here, but you can understand it if you have ever played it). The snkenode * snpre = (snkenode *) allBody. at (I-1); // obtain the direction and coordinates of the previous node to the current node sn-> dir = snpre-> dir; sn-> row = snpre-> row; sn-> col = snpre-> col;} else if (I = 0) {// If I = 0, it is the first node, and the coordinates of the snake header are the coordinates of the node sn-> dir = SHead-> dir; sn-> row = sHead-> row; sn-> col = sHead-> col ;}// move the snake header, determine the direction of the Snake Head Based on the dir switch (sHead-> dir) {case DIR_DEF: UP: sHead-> row ++; // move up if (sHead-> row >=10) {sHead-> row = 0; // after the top boundary is exceeded, it will come out from the bottom} 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;} brea K ;}; // collision detection // If the horizontal and column positions of the snake header are the same, it indicates that the snake has eaten this food. if (sHead-> row = sFood-> row & sHead-> col = sFood-> col) {// The food disappears from the current position, randomly appear in the Next coordinate sFood-> row = rand () % 10; sFood-> col = rand () % 10; // Add the body to the collection. * sn = new nskenode (); // create a new node (that is, the food you eat ), put it on the tail of the Snake. The snake * lastNode = NULL; // gets the last node of the Snake. If the size () of the allBody is 0, it indicates that the snake is the first prey on the snake, then its last node is the snake head. If (allBody. size ()> 0) lastNode = (snail kenode *) allBody. back (); elselastNode = sHead; // The Last node is the snake header // initialize the horizontal and column coordinate switch (lastNode-> dir) for a new node in the direction of the last Node) {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); // Add a new node to the body of the Snake .}}
3) draw the grid and food on the game interface through draw ().
Void GameLayer: draw (Renderer * renderer, const kmMat4 & transform, bool transformUpdated) {// draw shape: glLineWidth (2 ); // set the width of the draw line for (int I = 0; I <11; I ++) {DrawPrimitives: drawLine (Point (0, I * 32), Point (320, I * 32); // draw the DrawPrimitives: drawLine (Point (I * 32, 0), Point (I * 32,320 )); // draw a vertical bar} // RGBA // DrawPrimitives: drawColor4B (ccc4 (0,255,); // set the color of the draw line // draw the snake header 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); // draw the food DrawPrimitives :: drawSolidRect (Point (sFood-> col * 32 + 2, sFood-> row * 32 + 2), Point (sFood-> col * 32 + 32, sFood-> row * 32 + 32), Color4F (Color3B (255,); // draw the body for (int I = 0; icol * 32 + 2, node-> row * 32 + 2), Point (node-> col * 32 + 32, node-> row * 32 + 32), Color4F (Color3B (0, 0, 255);}/* Rect r (, 0,); chead-> drawInRect (r); Layer: draw ();*/}
4) Update the direction of snake movement through the gravity callback function
Void GameLayer: onAcceleration (Acceleration * acc, Event * event) {// 0.5 This is a subtle saying that 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 {;}}
Well, that's all about it. The game is attached. If you are satisfied with the game screen, please give me 32 likes! Thank you !~ :
We can see that some people may have to speak out, why didn't we write that when a snake hits its tail, it will end the game's processing. The reason is simple, because I am... lazy .... As mentioned at the beginning, the main purpose of this article is to systematically introduce cocos2dx2.0 and 3.0 through an example.
Respect Original, reprinted please indicate Source: http://blog.csdn.net/start530/article/details/23707985
Respect Original, reprinted please indicate Source: http://blog.csdn.net/start530/article/details/23707985