Projects show
Game ideas
Actually 2048 the most important place of this game is the amalgamation of numbers, the same number can be merged into larger numbers. We are definitely going to create a two-dimensional array first, but in reality we are going to operate on a one-dimensional array every time we merge, for example:
2 2 0 0
0 2 0 2
4 2 0 2
4 0 2 0
// If you merge from up, then
2 0 4 4 -> 2 8 0 0
2 2 2 0 -> 4 2 0 0
0 0 0 2 -> 2 0 0 0
0 2 2 0 -> 4 0 0 0
Copy the code
We need to get the data from, and then the access to the data form a one dimensional array, then the one-dimensional array to 0, first is to move in front of the non-zero figures, the adjacent and the same number again to merge (after will accumulate to one element before an element, an element after the qing 0), again after the merger to 0 operation, Finally, the one-dimensional array is restored to its original row or column. Here’s the general idea, and then attach the code.
The game code
Number.h
#pragma once
#include "cocos2d.h"
class Number : public cocos2d::Sprite{
public :
static Number* create(int number);
bool init(int number);
void setImage(int number);
};
Copy the code
Number.cpp
#include "Number.h"
Number* Number::create(int number) {
Number* ret = new (std::nothrow)Number(a);if (ret && ret->init(number)) {
ret->autorelease(a); }else {
delete ret;
ret = nullptr;
}
return ret;
}
bool Number::init(int number) {
char filename[40];
sprintf_s(filename, "image/%d.png", number);
if(! Sprite::initWithFile(filename)) {
return false;
}
return true;
}
void Number::setImage(int number) {
char filename[40];
sprintf_s(filename, "image/%d.png", number);
this->setTexture(filename);
}
Copy the code
The Number class encapsulates the creation of a digital Sprite and makes it easier to use, followed by the game scene class Gamelayer.h
#ifndef __GAMELAYER_SCENE_H__
#define __GAMELAYER_SCENE_H__
#include "cocos2d.h"
#include "Number.h"
// Define an enumerated direction class
enum Dir {
left,
right,
up,
down
};
class GameLayer : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene(a);
virtual bool init(a);
// Initializes the board and numbers
void initNumber(a);
// The default scheduler
void update(float dt);
/ / to zero
void removeZero(bool inverted, bool again);
// Get data from the original row or column
void getDataForColORRow(int arr[][4].int getNum);
/ / merge
void merge(bool inverted);
// Restore a one-dimensional array to its original row or column
void reduction(int arr[][4].int reductionNum);
// Set whether to enable keyboard listening
void setKeyboardEnable(bool enable);
// The callback function
void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event*);
// Empty the array
void arrClearr(a);
// Create a random number
void randomCreateNum(a);
GameLayer(a); ~GameLayer(a);CREATE_FUNC(GameLayer);
private:
// Used to store digital sprites
Number *number[4] [4];
Dir dir;
int map[4] [4] = {{0.0.0.0 },
{ 0.0.0.0 },
{ 0.0.0.0 },
{ 0.0.0.0}};int temp[4] {0 };
// Check whether the arrow keys are heard from the keyboard
bool isInput = false;
};
#endif // __GAMELAYER_SCENE_H__
Copy the code
GameLayer.cpp
#include "GameLayer.h"
#include <cstdlib>
#include <ctime>
using namespace cocos2d;
USING_NS_CC;
static const int ArrSize = 4;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * 2048 the core algorithm of * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* * 1. Define the zeroing method (for one-dimensional arrays) : move the 0 element to the end * 2. Merge data method (for one-dimensional arrays) * -- zero: move 0 element to end * -- merge if adjacent elements are the same (add the latter element to the previous element, the latter element is clear 0) * -- zero: move 0 element to end * 3. Move up * -- get the column data from top to bottom to form a one-dimensional array * -- call the merge data method * -- restore the one-dimensional array elements to the original column * 4. Move up * -- get the column data from bottom to top to form a one-dimensional array * -- call the merge data method * -- restore the one-dimensional array elements to the original column *...... * /
GameLayer::GameLayer() :dir(up) {
}
GameLayer::~GameLayer() {}Scene* GameLayer::createScene(a) {
auto scene = Scene::create(a);auto layer = GameLayer::create(a); scene->addChild(layer);
return scene;
}
bool GameLayer::init(a) {
if(! Layer::init()) {
return false;
}
// Generate a random number seed
srand((int)time(0));
Size size = Director::getInstance() - >getVisibleSize(a);// Create background
Sprite* bg = Sprite::create("image/map.png");
bg->setPosition(Vec2(size.width / 2, size.height / 2));
this->addChild(bg, - 1);
// Initialize the number
initNumber(a);// Enable the default scheduler
scheduleUpdate(a);// Enable keyboard listening
setKeyboardEnable(true);
return true;
}
/* Default scheduler */
void GameLayer::update(float dt) {
// Determine if the arrow keys are received from the keyboard
if (isInput) {
// Whether to obtain data forward or backward
bool inverted;
switch (dir) {
case left:
case up:
inverted = true;
break;
case down:
case right:
inverted = false;
break;
}
for (int i = 0; i < ArrSize; i++) {
// Get data
getDataForColORRow(map, i);
/ / merge
merge(inverted);
/ / reduction
reduction(map, i);
/ / to empty
arrClearr(a); }// Create a random number
randomCreateNum(a);for (size_t i = 0; i < ArrSize; i++) {
for (size_t j = 0; j < ArrSize; j++) {
// Set the image of the digital Sprite
number[i][j]->setImage(map[i][j]);
// Set the digital Sprite position
number[i][j]->setPosition(Vec2(113 * j + 7.113 * (ArrSize - i - 1) + 7));
}
}
isInput = false; }}/* Initializes the board number */
void GameLayer::initNumber(a) {
// Start with two random numbers
randomCreateNum(a);randomCreateNum(a);// Initializes the checkerboard number and prints it
for (size_t i = 0; i < ArrSize; i++) {
for (size_t j = 0; j < ArrSize; j++) {
number[i][j] = Number::create(map[i][j]);
number[i][j]->setAnchorPoint(Vec2(0.0));
number[i][j]->setPosition(Vec2(113 * j + 7.113 * (ArrSize - i - 1) + 7));
this->addChild(number[i][j], 1); }}}/* Get the original row or column data */
void GameLayer::getDataForColORRow(int arr[][ArrSize], int getNum) {
for (int i = 0; i < ArrSize; i++) {
switch (dir) {
case left:
temp[i] = arr[getNum][i];
break;
case right:
temp[i] = arr[getNum][ArrSize - i - 1];
break;
case down:
temp[i] = arr[ArrSize - i - 1][getNum];
break;
case up:
temp[i] = arr[i][getNum];
break; }}}/* Merge method */
void GameLayer::merge(bool inverted) {
// Go to zero for the first time
removeZero(inverted, false);
// merge and set the latter number to 0
for (int i = 0; i < ArrSize - 1; i++) {
if (temp[i] == temp[i + 1]) {
temp[i] += temp[i + 1];
temp[i + 1] = 0; }}// Go to zero the second time
removeZero(inverted, true);
}
/* to 0 method */
void GameLayer::removeZero(bool inverted, bool again) {
int arr[ArrSize]{ 0 };
int j = 0;
// Extract the non-zero digits and place them in a new array
for (int i = 0; i < ArrSize; i++) {
if(temp[i] ! =0) {
arr[j++] = temp[i];
temp[i] = 0; }}for (int i = 0; i < j; i++) {
if (inverted) {
// If the array is retrieved in the forward direction, it will be restored in the forward direction
temp[i] = arr[i];
} else {
if(! again) {// If it is reversed and goes to 0 the second time, there is no need to invert the array
temp[i] = arr[i];
} else {
// If the array is retrieved in the reverse direction, it will be restored in the reverse direction
temp[ArrSize - i - 1] = arr[i]; }}}}/* Restore a one-dimensional array to its original column or row */
void GameLayer::reduction(int arr[][ArrSize], int reductionNum) {
for (int i = 0; i < ArrSize; i++) {
switch (dir) {
case left:
case right:
arr[reductionNum][i] = temp[i];
break;
case down:
case up:
arr[i][reductionNum] = temp[i];
break; }}}// Whether to enable keyboard listening
void GameLayer::setKeyboardEnable(bool enable) {
if (enable) {/ / open
auto listener = EventListenerKeyboard::create(a); listener->onKeyPressed =CC_CALLBACK_2(GameLayer::onKeyPressed, this);
// Event distribution
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
} else {/ / close
_eventDispatcher->removeEventListenersForTarget(this); }}/* Keyboard monitor */
void GameLayer::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event*) {
switch (keyCode) {
case EventKeyboard::KeyCode::KEY_UP_ARROW:
dir = up;
isInput = true;
break;
case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
dir = down;
isInput = true;
break;
case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
dir = left;
isInput = true;
break;
case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
dir = right;
isInput = true;
break; }}/* Array empty */
void GameLayer::arrClearr(a) {
for (size_t i = 0; i < ArrSize; i++) {
temp[i] = 0; }}/* Create a random number */
void GameLayer::randomCreateNum(a) {
int x = rand() % ArrSize;
int y = rand() % ArrSize;
while(map[x][y] ! =0) {
// Determine if this element of map[x][y] is 0, if not 0, continue to randomly obtain coordinates
x = rand() % ArrSize;
y = rand() % ArrSize;
}
![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/4/24/171ab6d72edb2f43~tplv-t2oaga2asx-image.image)
map[x][y] = rand() % 2= =0 ? 2 : 4;
}
Copy the code
Finally, attach my github address for your reference source gitee.com/WolfDa/HXD2…