最近週末看了下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