2048游戏的开发原理相对简单,它基于一个4x4的方格,通过控制数字方块的移动来合成相同的数字方块,并生成新的数字方块。
具体实现过程如下:
确定需求:首先需要明确游戏的功能需求,如产生随机数字方块、控制数字方块的移动、检测碰撞等。
界面设计:设计游戏的界面,包括数字方块、移动方向、分数等元素。
逻辑实现:实现游戏的逻辑部分,包括数字方块的生成、移动和碰撞检测,以及分数的记录和更新等。
这里说下需要手动添加一个“PreTranslateMessage”消息处理函数,用于识别键盘按键动作。
在Windows编程中,消息处理函数(Message Handling Function)是用于处理Windows操作系统发送给应用程序的消息的函数。其中,"PreTranslateMessage"是一种消息处理函数,它用于在将消息传递给窗口过程之前,对消息进行预处理。
要添加一个"PreTranslateMessage"消息处理函数,需要进行以下步骤:
打开你的窗口类的定义文件(通常是一个名为"窗口类名.rc"的文件),在资源编辑器中打开。
在资源编辑器中,找到窗口,右键选择“类向导”,然后从虚函数中找到“PreTranslateMessage”。
在新的消息处理函数中,编写你的代码以处理消息。这个函数的原型如下:
BOOL PreTranslateMessage(MSG* pMsg)
其中,pMsg是一个指向MSG结构的指针,该结构包含了消息的相关信息,如消息的类型、参数等。
在"PreTranslateMessage"函数中,你可以根据需要编写代码来处理消息。例如,你可以通过检查消息的类型,拦截或修改特定的消息。
保存并关闭窗口类的定义文件。
"PreTranslateMessage"消息处理函数的主要作用是允许你在窗口过程(Window Procedure)之前对消息进行修改或拦截。通过这个函数,你可以对消息进行一些预处理操作,例如修改消息的参数,或者根据需要将消息传递给其他函数进行处理。
主函数源代码:
void CMy2048MFCDlg::Show()
{
//所有方块的种类,封装到一个Node数组中
const static Node color[]={
0, RGB(204,192,179), RGB(204,192,179),
2, RGB(238,230,210), RGB(119,110,100),
4, RGB(237,224,200), RGB(119,110,100),
8, RGB(242,177,121), RGB(249,242,242),
16, RGB(245,148,100), RGB(249,242,242),
32, RGB(246,124,95), RGB(249,242,242),
64, RGB(246,94,59), RGB(249,242,242),
128, RGB(237,207,114), RGB(249,242,242),
256, RGB(237,204,97), RGB(249,242,242),
512, RGB(237,200,80), RGB(249,242,242),
1024, RGB(237,197,63), RGB(249,242,242),
2048, RGB(43,132,98), RGB(249,242,242),
4096, RGB(250,56,108), RGB(249,242,242),
8192, RGB(129,148,200), RGB(249,242,242),
16384, RGB(255,0,0), RGB(249,242,242),
32768, RGB(0,255,0), RGB(249,242,242),
65536, RGB(128,128,0), RGB(249,242,242),
};
static const int n_block_size = 120; //方块大小
static const int n_pos_x = 14; //显示位置
static const int n_pos_y = 14;
static const int n_gap_size = 10; //间隙大小
RECT rect;
GetClientRect(&rect);
m_dc.FillSolidRect(&rect,RGB(255,255,255)); //把整个客户区填充为白色背景
m_dc.SelectObject(&m_font);
CBrush bkBrush(RGB(187,173,160));
m_dc.SelectObject(&bkBrush);
//qrt:4*4的棋盘背景矩形大小
RECT back_square;
back_square.top = n_pos_x-n_gap_size;
back_square.left = n_pos_y-n_gap_size;
back_square.bottom = n_pos_x+4*n_gap_size+4*n_block_size;
back_square.right = n_pos_y+4*n_gap_size+4*n_block_size;
//使用当前笔绘制圆角矩形,用当前画刷填充 ,8*8的point是圆角的宽度
m_dc.RoundRect(&back_square,CPoint(8,8));
//重绘整个棋盘中16个块的矩形
for(int i=0;i<4;i++)
{
for(int k=0;k<4;k++)
{
//取出棋盘中的数
int num = m_nChessBoard[i][k];
//得到棋盘数字对应的Node位置
int n = GetNodePos(num);
//定义数字所对应的画刷的颜色
CBrush brush(color[n].m_BackColor);
m_dc.SelectObject(&brush);
//显示字体
m_dc.SetTextColor(color[n].m_FontColor);
//每个方块rt的矩形大小
RECT rt;
rt.left = n_pos_x+i*(n_block_size+n_gap_size);
rt.top = n_pos_y+k*(n_block_size+n_gap_size);
rt.right = rt.left+n_block_size;
rt.bottom = rt.top+n_block_size;
//放大步骤
if(i*4+k == m_nNewPos)
{
const static int b[]={
-24,-20,-16,-12,-8,-4,0,
};
rt.left -= b[m_nCount];
rt.right += b[m_nCount];
rt.top -= b[m_nCount];
rt.bottom+= b[m_nCount];
m_nCount++;
if(m_nCount > sizeof(b)/sizeof(int))
{
m_nNewPos=-1;
}
}
m_dc.RoundRect(&rt,CPoint(16,16));
if(num>0)
{
//1.将棋盘中的数字转换为字符串
//2.存入到str中,并画在矩形框rt中
CString str;
char temp[10] = {0};
_itoa_s(num,temp,10);
str = temp;
//单行 - 居中显示 - 垂直居中显示
m_dc.DrawText(str,&rt,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
}
}
//分数
CBrush brush(RGB(187,173,160));
m_dc.SelectObject(&brush);
m_dc.SetTextColor(RGB(238,235,232));
RECT rt={580,170,760,300};
m_dc.RoundRect(rt.left,rt.top,rt.right,rt.bottom,8,8);
CString str;
str="score";
rt.bottom = (rt.bottom - rt.top)/2 + rt.top;
rt.top += 10;
rt.bottom += 10;
//显示“score”
m_dc.DrawText(str,&rt,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
char tempScore[10] = {0};
_itoa_s(m_nScore,tempScore,10);
str = tempScore;
rt.top += 50;
rt.bottom += 50;
//显示分数
m_dc.DrawText(str,&rt,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
//判断游戏是否结束
if(m_nOver)
{
CFont Over;
//初始化字体:字体高度,字体宽度,夹角,夹角,字体磅数200,斜体,下划线,突出,字体的字符集
//输出精度,剪贴精度,输出质量,字体的间距,字体类型
Over.CreateFont(80,32,0,0,FW_EXTRABOLD,false,false,false,ANSI_CHARSET,
OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,FF_MODERN,L"Arial");
m_dc.SelectObject(&Over);
m_dc.SetTextColor(RGB(250,0,0));
str="游戏结束";
m_dc.DrawText(str,&back_square,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
CDC *dc=GetDC();
dc->BitBlt(0,0,rect.right,rect.bottom,&m_dc,0,0,SRCCOPY);
ReleaseDC(dc);
}
完整程序代码:MFC/C++小游戏源代码2048小游戏