VS2013环境利用C++ 、Easy-X开发2048游戏


2048 游戏的玩法就不多说了,大家都知道。这次我需要使用Easy-X库来绘制界面,同时Easy-X也提供了一个获取鼠标状态的方法, 将这个方法简单的封装一下就可以实现鼠标点击并拖动的事件的响应。

注意使用本代码,请先安装Easy-X 类库,我使用的是2015冬至版。效果图如下:

VS2013环境利用C++ 、Easy-X开发2048游戏_第1张图片

直接附上代码:

下面是每一个数字所在方格的图形绘制的头文件,以及cpp文件。

#ifndef __UI_H_
#define __UI_H_
#include 
#include 
class Ui
{
private:
	int x;
	int y;
	int width;
	COLORREF color;
public:	
	int value;
	Ui();
	Ui(int x, int y, int value = 0, int color = BLUE, int witdh = 50);
	void setX(int n);
	void setY(int n);
	void setValue(int n);
	void setWidth(int n);
	void setColor(COLORREF n);
	int getX();
	int getY();
	int getValue();
	int getWidth();
	COLORREF setColor();
	void draw();
	void settinng();
};
#endif


#include "ui.h"

Ui::Ui()
{
	settinng();
	x = 10;
	y = 10;
	width = 50;
	value = 0;
	color = BLUE;
}


Ui::Ui(int x, int y, int value, int color,int witdh)
{
	settinng();
	this->x = x;
	this->y = y;
	this->width = width;
	this->value = value;
	this->color = color;
}


void Ui::setX(int n)
{
	x = n;
}


void Ui::setY(int n)
{
	y = n;
}


void Ui::setValue(int n)
{
	value = n;
}


void Ui::setWidth(int n)
{
	width = n;
}
int Ui::getX()
{
	return x;
}
int Ui::getY()
{
	return y;
}


int Ui::getValue()
{
	return value;
}


int Ui::getWidth()
{
	return width;
}


void Ui::draw()
{
	int tempcolor = color;
	//设置填充颜色
	if (value != 0)
	{
		tempcolor = RGB(color + 20 * value, color - 20 * value, color + 10 * value);
	}
	setfillcolor(tempcolor);
	setlinecolor(GREEN);
	fillrectangle(x, y, x + width, y + width);
	//设置文字颜色
	if (value != 0)
	{
		settextcolor(WHITE);
	}
	else
	{
		settextcolor(color);
	}
	
	TCHAR s[5];
	_stprintf_s(s, _T("%d"), value);        
	settextstyle(20, 15, _T("宋体"));
	setbkmode(TRANSPARENT);
	outtextxy(x + width / 3, y + width / 3, s);
}


void Ui::settinng()
{


    //设置背景色
	setbkcolor(WHITE);
}


void Ui::setColor(COLORREF n)
{
	color = n;
}


COLORREF Ui::setColor()
{
	return color;

}

接下来是鼠标的事件的封装和对应的函数的实现:

#ifndef __MOUSE_H_
#define __MUUSE_H_
class Mouse
{
	int x;
	int y;
public:
	Mouse();
	Mouse(int x , int y);
	void setX(int n);
	void setY(int n);
	int getX();
	int getY();
};
#endif

#include "mouse.h"


Mouse::Mouse()
{
	x = 0;
	y = 0;
}
Mouse::Mouse(int x, int y)
{
	this->x = x;
	this->y = y;
}
void Mouse::setX(int n)
{
	this->x = n;
}
void Mouse::setY(int n)
{
	this->y = n;
}
int Mouse::getX()
{
	return x;
}
int Mouse::getY()
{
	return y;

}

游戏类的相关函数及实现:

#ifndef __GEME_H_
#define __GEME_H_
#include "ui.h"
#include "mouse.h"


class Game
{	
	int WIDTH;
	int HEIGHT;
	int score;
	int steps;
	Mouse mouse[2];
	Ui ui[16];


public:
	Game();
	Game(int w, int h);
	void initUI();
	void updateUI();
	int getRandValue();
	int get2or4();
	int add(char ch);
	void start();
	int MouseAction();
	void together(int &a, int &b, int &c, int &d);
	int addTwo(int &a, int &b, int &c, int &d);
	void isGameOver();
};

#endif


#include "game.h"
#include 
#include 
#include 


#define LEFT 0
#define RIGHT 1
#define DOWN 2
#define UP 3


Game::Game()
{
	srand(time(NULL)); // 设置随机数的种子
	WIDTH  = 640;
	HEIGHT = 480;
	score = 0;
	steps = 0;
}
Game::Game(int w, int h)
{
	srand(time(NULL)); // 设置随机数的种子
	WIDTH = w;
	HEIGHT = h;
	score = 0;
	steps = 0;
}


void Game::updateUI()
{
	static TCHAR s[50];
	_stprintf_s(s, _T("得分:%d"), score);
	settextstyle(20, 15, _T("宋体"));
	settextcolor(BLACK);
	outtextxy(20, 0, s);
	int score = 0;
	
	for (int i = 0; i < 16; i++)
	{
		ui[i].draw();
		score += ui[i].value;
	}
	this->score = score;  // 保存本次得分


	_stprintf_s(s, _T("得分:%d"), score);
	settextstyle(20, 15, _T("宋体"));
	settextcolor(WHITE);
	setbkmode(TRANSPARENT);
	outtextxy(20,0, s);


}


void Game::start()
{
	initUI(); // 设置计算得到界面的相关数据, 并进行初步的绘制工作
    int ch = 0;
	while (1)
	{
		int i = getRandValue();      // 得到了可以设置value 方框的下标
		if (i != -1)
		{
			ui[i].setValue(get2or4());
			ui[i].draw();
		}
		ch = MouseAction();  // 获得一个鼠标事件
		add(ch);  
		updateUI();
		//isGameOver();
	}
}
int Game::add(char ch)
{
	int res = 0;


	if (ch == LEFT)
	{
		for (int i = 0; i < 4; i++)
		{
			//0//第一排 i+0  i+1, i+2; i+3       4i + 1  +2 +3  i%4 
			//1//第二排 i+3  i+4;  i+5; i+6
			//2//第三排 i+6  i+7;  i+8; i+9
			//3//第四排 i+9  i+10;  i+11; i+12
			//让数据靠拢在一起
			together(ui[4 * i + 0].value, ui[4 * i + 1].value, ui[4 * i + 2].value, ui[4 * i + 3].value);  
			//置合并一个相同的数据
			res = addTwo(ui[4 * i + 0].value, ui[4 * i + 1].value, ui[4 * i + 2].value, ui[4 * i + 3].value);
		}
	}
	else if (ch == RIGHT)
	{
		for (int i = 0; i < 4; i++)
		{
			//让数据靠拢在一起
			together(ui[4 * i + 3].value, ui[4 * i + 2].value, ui[4 * i + 1].value, ui[4 * i + 0].value);
			//置合并一个相同的数据
			res = addTwo(ui[4 * i + 3].value, ui[4 * i + 2].value, ui[4 * i + 1].value, ui[4 * i + 0].value);
		}
	}
	else if (ch == UP)
	{
		for (int i = 0; i < 4; i++)
		{
			    //  0       1       2      3
			    //第一列  第二列  第三列  第四列
			   //   i+0     i+1, i+2;     i+3      i + 0 4  8  12
			   //   i+4     i+4;  i+4;     i+4
			   //   i+8     i+8;  i+8;     i+8
			   //   i+12    i+12;  i+12;   i+12
			//让数据靠拢在一起
			together(ui[i + 0].value, ui[i + 4].value, ui[ i + 8].value, ui[ i + 12].value);
			//置合并一个相同的数据
			res = addTwo(ui[i + 0].value, ui[i + 4].value, ui[ i + 8].value, ui[ i + 12].value);
		}
	}
	else if (ch == DOWN)
	{
		for (int i = 0; i < 4; i++)
		{
			//让数据靠拢在一起
			together(ui[i + 12].value, ui[i + 8].value, ui[i + 4].value, ui[i + 0].value);
			//置合并一个相同的数据
			res = addTwo(ui[i + 12].value, ui[i + 8].value, ui[i + 4].value, ui[i + 0].value);
		}
	}
	return res;
}
int Game::addTwo(int &a, int &b, int &c, int &d)
{
	if (a == b)
	{
		a = a + b;
		b = c;
		c = d;
		d = 0;
		return 0;
	}
	if (b == c)
	{
		b = b + c;
		c = d;
		d = 0;
		return 0;
	}
	if (c == d)
	{
		c = c + d;
		d = 0;
		return 0;
	}
	return -1;
}
void Game::together(int &a, int &b, int &c, int &d)
{
	//让数据靠在一起
	if (c == 0)
	{
		c = d;
		d = 0;
	}
	if (b == 0)
	{
		b = c;
		c = d;
		d = 0;
	}
	if (a == 0)
	{
		a = b; 
		b = c;
		c = d;
		d = 0;
	}
}


void Game::initUI()
{
	int w;
	int sX, sY;


	w = WIDTH < HEIGHT ? (WIDTH - 2 * WIDTH / 20) / 4 : (HEIGHT - 2 * HEIGHT / 20) / 4;
	sX = WIDTH < HEIGHT ? (1* WIDTH / 20) : ( 1* HEIGHT / 20);
	sY = sX;
	for (int i = 0; i < 16; i++)
	{
	    ui[i].setX(sX + i % 4 * w);
		ui[i].setY(sY + i / 4 * w);
		ui[i].setWidth(w);
		ui[i].draw();
	}
}


int Game::getRandValue()
{
	int i;
	for (i = 0; i < 16; i++)
	{
		if (ui[i].value == 0)
		{
			break;
		}
	}
	if (i == 16)  // 没有空位置可以填随机数
	{
		return -1;
	}
	while (1)
	{
		int r = rand() % 16;  // 产生0 -- 15的随机数
		if (ui[r].getValue() == 0)
		{
			return r; // 返回可以作为新产生块的下标
		}
	}
}


int Game::get2or4()
{
	int res = rand() % 10 + 1;  // 产生一个 1 - 10 的随机数 
	if (res % 2 == 0)
	{
		return 2;
	}
	else
	{
		return 4;
	}
}


int Game::MouseAction()
{
	MOUSEMSG m;		// 定义鼠标消息
	int x0, x1;
	int y0, y1;
	int x, y;


	while (1)
	{
		m = GetMouseMsg();
		switch (m.uMsg)
		{
		case WM_LBUTTONDOWN:  // 鼠标左键按下
			mouse[0].setX(m.x);
			mouse[0].setY(m.y);
			break;
		case WM_LBUTTONUP:    // 鼠标左键抬起
			mouse[1].setX(m.x);
			mouse[1].setY(m.y);
			// 左:  x 大
			// 右:  x 小
			// 下:   y 大
			// 上:  y 小
			x0 = mouse[0].getX();
			y0 = mouse[0].getY();
			x1 = mouse[1].getX();
			y1 = mouse[1].getY();
			x = x0 > x1 ? x0 - x1 : x1 - x0;
			y = y0 > y1 ? y0 - y1 : y1 - y0;


			 // 判断哪个方向的移动更加明显, 鼠标灵活度为 40 pix
			if (x > y && x > 40)
			{
				if (x0 > x1)
				{
					printf("left\n");
					return LEFT;
				}
				else
				{
					printf("right\n");
					return RIGHT;
				}
			}
			else if ( y > x && y > 40)
			{
				if (y0 > y1)
				{
					printf("up\n");
					return UP;
				}
				else
				{
					printf("down\n");
					return DOWN;
				}
			}
			break;
		}
	}
}




void Game::isGameOver()
{
	
	int score = 0;
	for (int i = 0; i < 16; i++)
	{
		if (ui[i].value == 0)
		{
			return;
		}
		score += ui[i].value;
	}
	if (score == this->score)
	{
		printf("游戏结束");
	}



}

最后是主函数:

#include 
#include "ui.h"
#include "game.h"


using namespace std;


int main()
{
	initgraph(600, 600, SHOWCONSOLE);
	Game game(600, 600);
	game.start();
	_getch();
	closegraph();
	return 0;
}
ccccccccccc   工程代码: 工程代码下载请点击

你可能感兴趣的:(小游戏)