win32+gdi实现2048

最近周末看了下windows SDK编程,用GDI画了个2048练练手。

1.  是方块配置类


#include "framework.h"
//宏定义set.get
#define ATTRIBUTE_MEMBER_FUNC(argType, arg)\
	public:\
	void set_##arg(const argType& v) {\
	arg = v;\
	}\
	argType get_##arg() {\
	return arg;\
	}

class  DigitalConfig
{
public:
	 DigitalConfig();
	~ DigitalConfig();
	ATTRIBUTE_MEMBER_FUNC(int, digital);
	ATTRIBUTE_MEMBER_FUNC(int, digitalSize);
	ATTRIBUTE_MEMBER_FUNC(int, digitalColor);
	ATTRIBUTE_MEMBER_FUNC(HBRUSH, digitalBk);
	
private:
	int digital;  //方块数字
	int digitalSize; //方块字体大小
	int digitalColor; //方块字体颜色
	HBRUSH digitalBk; // 方块背景画刷


};

2  数字操作类

#pragma once
#include <iostream>
#include <vector>
#define PIECE_LENGTH 4
#include <functional>
class Checkerboard
{
public:
	Checkerboard();
	~Checkerboard();
	void left(int*);
	void right(int*);
	void up(int*);
	void down(int*);
	void hanleNum(bool); //产生随机2或4
	bool thanNewAndOld(); //判断数组是否改变
	void changeTemp(); //改变temp
	bool IsGameOver();
	void restart(); //重新开始
	void drawArray(std::function<void(int**)> drawCallBabck); //画数组回调
private:
	int** pieceArray;
	int** tempArray;
	std::vector<int> temp; //存在数组为0的下标
};

2.1数组产生2或4

void Checkerboard:: hanleNum(bool init)
{
	bool flag = false;
	//比较在按完方向键后数组是否发生变化
	if (!init) {

		if (thanNewAndOld())
		{

			return;
		}
	}
	//在剩余为0的座标中产生随机数
	int xy = rand() % (temp.size() == 0 ? 16 : temp.size());


	int data = rand() % 5; // 2和4出现概率为1:4
	if (data != 4) {
		data = 2;
	}
   //init 是用来开始时只能产生2
	if (init)
	{
		this->pieceArray[xy / PIECE_LENGTH][xy % PIECE_LENGTH] = 2;
	}
	else {
		this->pieceArray[temp[xy] / PIECE_LENGTH][temp[xy] % PIECE_LENGTH] = data;
	}
	
	for (size_t i = 0; i < PIECE_LENGTH; i++)
	{
		for (size_t j = 0; j < PIECE_LENGTH; j++)
		{
			this->tempArray[i][j] = pieceArray[i][j];

		}
	}
//将数组还为0下标的存入temp可以更好的随机出座标
	changeTemp();


}
//记录为0的座标
void Checkerboard::changeTemp()

{
	temp.clear();
	for (size_t i = 0; i < PIECE_LENGTH; i++)
	{
		for (size_t j = 0; j < PIECE_LENGTH; j++)
		{
			if (pieceArray[i][j] == 0)
			{
                //i*4+i用1维记录二维的下标
				temp.push_back(i * PIECE_LENGTH + j);

			}

		}
	}
}

2.2 移动算法

void Checkerboard::left(int* fraction)
{
	for (int i = 0; i < PIECE_LENGTH; i++)
	{
		int tempLeft[] = { 0,0,0,0 };
		int k = 0;
		for (int j = 0; j < PIECE_LENGTH; j++)
		{
                
			if (j < PIECE_LENGTH - 1 && pieceArray[i][j] != 0)
			{
                //
				for (int l = j + 1; l < PIECE_LENGTH; l++) {
                     //不为0不相等
					if (pieceArray[i][l] != 0 && pieceArray[i][j] != pieceArray[i][l]) {
						break;
					}
                    //不为0相等相等
					if (pieceArray[i][l] != 0 && pieceArray[i][j] == pieceArray[i][l]) {
						pieceArray[i][j] = pieceArray[i][j] * 2;
						*fraction += pieceArray[i][j];
						pieceArray[i][l] = 0;
						break;
					}
				}


			}
           //记录不为0的数,这样为0的数字都到了右边
			if (pieceArray[i][j] != 0)
			{
				tempLeft[k] = pieceArray[i][j];
				k++;
			}

		}
		for (int j = 0; j < PIECE_LENGTH; j++)
		{
			pieceArray[i][j] = tempLeft[j];
		}

	}

}

3. 绘图 

checkerboard->drawArray([=](int** arr) {
	
	
	int y = 205;
	
	//循环画每个方块
	for (size_t i = 0; i < PIECE_LENGTH; i++)
	{
		
		int x = 35;
		for (size_t j = 0; j < PIECE_LENGTH; j++)
		{
              
			
			HFONT hFont = CreateFont(mapColor[arr[i][j]]->get_digitalSize(), 0, 0, 0, 1000, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, L"等线");
			SelectObject(hBitmapDC, hFont);
			SelectObject(hBitmapDC, mapColor[arr[i][j]]->get_digitalBk());
			SetTextColor(hBitmapDC, mapColor[arr[i][j]]->get_digitalColor());
			RECT rect;
			rect.left = x;
			rect.top = y+(100- mapColor[arr[i][j]]->get_digitalSize())/2;
			rect.right = x + 100;
			rect.bottom = y + 100;
			char text1[10];
            //画带圆角的方块
			RoundRect(hBitmapDC, x, y, x + 100, y + 100,5,5);
             //画数为0画空格
			if (arr[i][j] == 0) {
				DrawText(hBitmapDC, L" ", 1, &rect, DT_CENTER);
				
			}
			else {
				snprintf(text1, 9, "%d", arr[i][j]);
				
				wchar_t* text = char2wchar(text1);
				
				DrawText(hBitmapDC, (LPCWSTR)text, wcslen(text), &rect, DT_CENTER);
				//delete text;
			}
			
			DeleteObject(hFont);
			
			

			
			x += 115;
		}
		y += 115;
	}
		});

以上时主要实现

游戏界面:

下载地址:(没积分留言)https://download.csdn.net/download/mengxiangsun/11981736

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章