Cocos2d-x 3.2-2048-Article 4★Core★
Have you ever been swollen ~
My current situation is: every three pounds of fat during the festive season, three pounds of fat .. O (Clerk □clerk) o ..
Okay, continue to do 2048,
This is the fourth article ~
This article is about how to handle the touch ~
That is, you move up, down, left, right, and right ~
We first create an enumerated direction variable in the macro definition class of the game:
GameDefine. h:
enum class MOVE_DIR{UP,DOWN,LEFT,RIGHT};
Then, we can touch the screen on the game interface:
GameScene. h:
int m_x,m_y;bool m_startMove;
void moveAllTiled( MOVE_DIR dir );
M_x and m_y are used to record the coordinates when the screen starts to touch,
M_startMove: determines whether to start to touch, and the touch cannot be obtained again before a sliding ends.
The moveAllTiled function is used to merge or move numeric blocks in the corresponding direction based on the sliding direction.
GameScene. cpp -- init function:
// Screen Touch processing // create a Touch event auto event = EventListenerTouchOneByOne: create (); Event-> onTouchBegan = [&] (Touch * tou, event * eve) {// record the touch position m_x = tou-> getLocation (). x; m_y = tou-> getLocation (). y; m_startMove = true; return true;}; event-> onTouchMoved = [&] (Touch * tou, Event * eve) {// record the position where the touch ends int x = tou-> getLocation (). x; int y = tou-> getLocation (). y; // if the touch event starts and the touch position difference is 10 pixels, move and merge if (m_startMove = true & (abs (m_x-x)> 10 | abs (m_y-y)> 10) {m_startMove = false; MOVE_DIR; // based on the last coordinate position, determine to which direction to move if (abs (m_x-x)> abs (m_y-y) {if (m_x <x) dir = MOVE_DIR: RIGHT; elsedir = MOVE_DIR :: LEFT;} else {if (m_y <y) dir = MOVE_DIR: UP; elsedir = MOVE_DIR: DOWN;} moveAllTiled (dir );}}; // Add a listener to the current scenario, that is, you can get the touch event ctor: getInstance ()-> getEventDispatcher ()-> addEventListenerWithSceneGraphPriority (event, this) of the current scenario );
The specific explanations are provided in the Code,
Then set the moveAllTiled function:
Void GameScene: moveAllTiled (MOVE_DIR dir) {// move switch (dir) {case MOVE_DIR: UP: moveUp (); break according to the specific direction; case MOVE_DIR: DOWN: moveDown (); break; case MOVE_DIR: LEFT: moveLeft (); break; case MOVE_DIR: RIGHT: moveRight (); break; default: break;} // The movement is completed. A newNumberTiled () is randomly generated ();}
This function will add many things in the future,
For example, determine whether the game is over and whether the game can be moved in a certain direction,
And sound effects ..
In the moveAllTiled function
MoveUp, moveDown, moveLeft, and moveRight functions are defined,
Of course, first declare in GameScene. h:
void moveUp();void moveDown();void moveLeft();void moveRight();
Then, define moveUp first:
Void GameScene: moveUp () {// move all the blocks up for (int col = 0; col <GAME_COLS; ++ col) {for (int row = GAME_ROWS-1; row> = 0; -- row) {if (map [row] [col]> 0) {for (int row1 = row; row1 <GAME_ROWS-1; ++ row1) {// if it is null above, it will be moved if (map [row1 + 1] [col] = 0) {map [row1 + 1] [col] = map [row1] [col]; map [row1] [col] = 0; m_allTiled.at (map [row1 + 1] [col]-1)-> moveTo (row1 + 1, col);} else {// judgment, whether the number int numObj = m_allTiled.at (map [row1 + 1] [col]-1)-> m_number can be eliminated; // obtain the number int numNow = m_allTiled.at (map [row1] [col]-1)-> m_number; // The two lattice numbers are the same if (numNow = numObj) {// The above row of numbers X2m_allTiled.at (map [row1 + 1] [col]-1)-> doubleNumber (); // remove the current numeric block m_allTiled.at (map [row1] [col]-1)-> removeFromParent (); // obtain the current digit block number int index = map [row1] [col]; m_allTiled.erase (map [row1] [col]-1 ); // correct all numbers larger than index numbers for (int r = 0; r <GAME_ROWS; ++ r) {for (int c = 0; c <GAME_COLS; ++ c) {if (map [r] [c]> index) {-- map [r] [c] ;}} // set the current block number to 0map [row1] [col] = 0;} break ;}}}}}}
For more information, see comments in the code.
But let's talk about this principle: (it should belong to the core part of 2048 ~ )
Is to traverse from the leftmost side of the bottom row to the rightmost side of the penultimate row above,
Each part must be compared with the number block in the corresponding column of the above row,
-- If the map value of the row is 0
-- If the map value of the row is not 0, the corresponding columns from the corresponding column of the row are traversed to the corresponding column of the last row.
---- If the map value of the row above is 0, the row will be swapped with the row above (in fact, the row above is 0, and the row above is replaced with the row above)
---- Otherwise, because both rows are not 0, judge whether the values of the two rows are equal.
-------- If they are equal, the value of the above row doubles, the number block of this row is removed, and other corresponding numbers in the map are changed.
-------- If not, break
The logical block is jointly controlled by map and Vector,
Map Stores numbers, which are the blocks generated by the first generation in the figure. The map value is 1 and the second is 2,
Vector is the class that stores the number block, including the position of the Number Block and the value of the Number Block.
The advantage of using these two controls instead of simply using a Vector is that we do not need to make any judgment, we need to find them through the Vector,
Instead, you can use map to determine whether there are any number blocks at the current position,
In addition, it is much more convenient to generate randomly, and the program efficiency will be improved.
Now that we have finished the core principles, we can set up to double the corresponding number blocks:
Before setting this function, you need to process the previous number blocks,
In the function, we need to obtain the background color layer and digital display layer of the digital block,
Therefore, we need to set a Tag for the two:
bk -> setTag( 101 );label -> setTag( 102 );
Don't forget to declare the doubleNumber function in the header file (I won't play it)
Void NumberTiled: doubleNumber () {// this-> m_number = this-> m_number * 2; // get the background layer and number Layer auto bk = this-> getChildByTag (101); Label * label = (Label *) bk-> getChildByTag (102 ); // re-draw the label-> setString (StringUtils: format (% d, m_number) for the number at the digit layer; // depending on the value, color switch (this-> m_number) {case 2: bk-> setColor (Color3B (230,220,210); break; case 4: bk-> setColor (Color3B (230,210,190); break; case 8: bk-> setColor (Color3B (230,150,100); label-> setColor (Color3B (255,255,255); break; case 16: bk-> setColor (Color3B (230,120, 80); label-> setColor (Color3B (255,255,255); break; case 32: bk-> setColor (Color3B (230,100, 90); label-> setColor (Color3B (255,255,255); break; case 64: bk-> setColor (Color3B (230,70, 60); label-> setColor (Color3B (255,255,255); break; case 128: label-> setScale (0.7f); bk-> setColor (Color3B (230,190, 60); label-> setColor (Color3B (255,255,255); break; case 256: label-> setScale (0.7f); bk-> setColor (Color3B (230,190, 60); label-> setColor (Color3B (255,255,255); break; case 512: label-> setScale (0.7f); bk-> setColor (Color3B (230,190, 60); label-> setColor (Color3B (255,255,255); break; case 1024: case 2048: label-> setScale (0.5f); bk-> setColor (Color3B (210,180, 30); label-> setColor (Color3B (255,255,255); break; default: break ;}}
OK, run it to see the effect:
How about it ~
Next, define the function in the following three directions: Bottom, left, and right:
Void GameScene: moveDown () {// move all blocks down for (int col = 0; col <GAME_COLS; ++ col) {for (int row = 0; row <GAME_ROWS; ++ row) {if (map [row] [col]> 0) {for (int row1 = row; row1> 0; -- row1) {if (map [row1-1] [col] = 0) {map [row1-1] [col] = map [row1] [col]; map [row1] [col] = 0; m_allTiled.at (map [row1-1] [col]-1)-> moveTo (row1-1, col );} else {int numObj = m_allTiled.at (map [row1-1] [col]-1)-> m_number; int numNow = m_allTiled.at (map [row1] [col]-1)-> m_number; if (numNow = numObj) {m_allTiled.at (map [row1-1] [col]-1)-> doubleNumber (); m_allTiled.at (map [row1] [col]-1) -> removeFromParent (); int index = map [row1] [col]; m_allTiled.erase (map [row1] [col]-1 ); // correct the block number for (int r = 0; r <GAME_ROWS; ++ r) {for (int c = 0; c <GAME_COLS; ++ c) {if (map [r] [c]> index) {-- map [r] [c] ;}} map [row1] [col] = 0 ;} break ;}}}} void GameScene: moveLeft () {// move all blocks to the left for (int row = 0; row <GAME_ROWS; ++ row) {for (int col = 0; col <GAME_COLS; ++ col) {if (map [row] [col]> 0) {for (int col1 = col; col1> 0; -- col1) {if (map [row] [col1-1] = 0) {map [row] [col1-1] = map [row] [col1]; map [row] [col1] = 0; m_allTiled.at (map [row] [col1-1]-1)-> moveTo (row, col1-1 );} else {int numObj = m_allTiled.at (map [row] [col1-1]-1)-> m_number; int numNow = m_allTiled.at (map [row] [col1]-1)-> m_number; if (numNow = numObj) {m_allTiled.at (map [row] [col1-1]-1)-> doubleNumber (); m_allTiled.at (map [row] [col1]-1) -> removeFromParent (); int index = map [row] [col1]; m_allTiled.erase (map [row] [col1]-1 ); // correct the block number for (int r = 0; r <GAME_ROWS; ++ r) {for (int c = 0; c <GAME_COLS; ++ c) {if (map [r] [c]> index) {-- map [r] [c] ;}} map [row] [col1] = 0 ;} break ;}}}} void GameScene: moveRight () {// move all blocks to the right for (int row = 0; row <GAME_ROWS; ++ row) {for (int col = GAME_COLS-1; col> = 0; -- col) {if (map [row] [col]> 0) {for (int col1 = col; col1 <GAME_COLS-1; ++ col1) {if (map [row] [col1 + 1] = 0) {map [row] [col1 + 1] = map [row] [col1]; map [row] [col1] = 0; m_allTiled.at (map [row] [col1 + 1]-1)-> moveTo (row, col1 + 1 );} else {int numObj = m_allTiled.at (map [row] [col1 + 1]-1)-> m_number; int numNow = m_allTiled.at (map [row] [col1]-1) -> m_number; if (numNow = numObj) {m_allTiled.at (map [row] [col1 + 1]-1)-> doubleNumber (); m_allTiled.at (map [row] [col1]-1)-> removeFromParent (); int index = map [row] [col1]; m_allTiled.erase (map [row] [col1]-1); for (int r = 0; r <GAME_ROWS; ++ r) {for (int c = 0; c <GAME_COLS; ++ c) {if (map [r] [c]> index) {-- map [r] [c] ;}} map [row] [col1] = 0;} break ;}}}}}}
OK, complete. This is the time to complete,
Next time, we need to improve the game-related functions,
For example:
-- Failed to judge
-- Add an animation
-- Add sound effects
Unconsciously, this 2048 is about to end ~.~ Hey
See you later ~