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…