MFC学习之2048小游戏程序源码

news2024/11/25 2:30:22

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小游戏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/754181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PostgreSQL的进程架构和内存架构

文章首发地址 PostgreSQL的进程架构 PostgreSQL的进程架构是由多个进程组成的&#xff0c;每个进程都有不同的作用和职责。下面是PostgreSQL的进程架构的详细说明&#xff1a; 后台进程(Postmaster) 后台进程是PostgreSQL启动时创建的第一个进程&#xff0c;它负责管理和控…

Android oom_adj 详细解读

源码基于&#xff1a;Android R 0. 前言 在博文《oom_adj 内存水位算法剖析》一文中详细的分析了lmkd 中针对 oom_adj 内存水位的计算、使用方法&#xff0c;在博文《oom_adj 更新原理(1)》、《oom_adj 更新原理(2)》中对Android 系统中 oom_adj 的更新原理进行了详细的剖析。…

STM32定义变量到指定内存位置

rt thread&#xff0c; 怎么定义变量到指定内存位置&#xff1f; OpenCat是由未来可编程机器人宠物制造商Petoi开发的基于Arduino和Raspberry Pi的开源四足机器人宠物框架。 非 gcc 版 定义一个宏 #ifndef __MEMORY_AT #if (defined (__CC_ARM)) #define _…

来电屏蔽号码分析

场测反馈77号码开头的电话号码屏蔽后&#xff0c;来电可以屏蔽&#xff0c;但是短信无法屏蔽 //Blocker is close 行 2689: 05-19 12:12:36.477096 2348 2348 I TelecomFramework: TelephonyConnectionService: onCallFilteringCompleted(TC3_1, CallFilteringCompletionInf…

leetcode:1184. 公交站间的距离(python3解法)

难度&#xff1a;简单 环形公交路线上有 n 个站&#xff0c;按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离&#xff0c;distance[i] 表示编号为 i 的车站和编号为 (i 1) % n 的车站之间的距离。 环线上的公交车都可以按顺时针和逆时针的方向行驶。 返回乘…

ECharts笔记-------柱状图与折线图

这幅图表由title、legend、series、xAxis、yAxis和tooltip这六个组件组成&#xff0c;每个组件都有对应的属性来调节参数&#xff0c;title和legend的代码跟上一篇一样&#xff0c;这里就不多讲了。 tooltip组件 tooltip: {trigger: axis,axisPointer: { type: cross } }, t…

系统组网图

接收路由器发送的数据信息并解析&#xff0c;做出相应的指示&#xff0c;点击按键表示完成拣货。 标签ID码正面显示无线通信868M&#xff0c;跳频通信通信速率200K/50K覆盖通信半径30米以上多色LED高亮指示灯自定义双向通信协议&#xff0c;安全可靠 电子标签拣货系统就是通过…

诺康达将再次上会接受审核:曾遭暂缓审议,业绩可持续性值得商榷

撰稿|行星 来源|贝多财经 近日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;北京诺康达医药科技股份有限公司&#xff08;下称“诺康达”&#xff09;将于2023年7月20日接受上市委的审议&#xff0c;并于7月13日更新了招股书&#xff08;上会稿&#xff09;。 据招股…

总部V批恩没有发送到分支流量,只有接收分支流量,分支无法访问总部内网资源

环境&#xff1a; 分支设备&#xff1a; AF8.0.48 联想笔记本 总部设备&#xff1a; SSL V批恩 V7.0 AF8.0.75 RUIJIE NBS5710-24GT4SFP-E 问题描述&#xff1a; 总部V批恩没有发送到分支流量&#xff0c;只有接收分支流量&#xff0c;分支无法访问总部内网资源&#…

H3C-Cloud Lab实验-单臂路由实验

实验拓扑图&#xff1a; 实验需求&#xff1a; 1. 按照图示为 PC3 和 PC4 配置 IP 地址和网关 2. PC3 属于 Vlan10&#xff0c;PC4 属于 Vlan20&#xff0c;配置单臂路由实现 Vlan10 和 Vlan20 三层互通 3. PC3 和 PC4 可以互通 实验步骤&#xff1a; 1. 连接所有设备 2. …

Unity游戏源码分享-卡通填色游戏Drawing Coloring Extra Edition 1.09

Unity游戏源码分享-卡通填色游戏Drawing Coloring Extra Edition 1.09 非常适合小朋友玩的小游戏 功能很齐全完善 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88050261

KuiperInfer深度学习推理框架环境配置-Ubuntu 22.04

KuiperInfer项目地址 Github项目地址 B站课程地址 安装Armadillo 官网&#xff1a;Armadillo官网 介绍&#xff1a;Armadillo C Library是一种C的线性代数库&#xff0c;包含一些矩阵和向量的运算&#xff0c;可以选用高效的LAPACK和BLAS进行加速。 矩阵相关计算的文档&…

Arthas和常量池

一、Arthas 快速入门 | arthas 1、Arthas使用 运行arthas提供的应用程序 curl -O https://arthas.aliyun.com/math-game.jar java -jar math-game.jar 运行arthas工具jar包 curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar 启动界面如下图&…

Google Play针对恶意软件采取最新反制措施!

近日&#xff0c;谷歌开始针对Google Play上不断入侵的恶意软件采取反制措施&#xff0c;要求所有以机构名义注册的新开发者账户在提交应用程序之前提供一个有效的D-U-N-S号码。 这项新措施能有效提高平台的安全性和可信度&#xff0c;同时也能够有效遏制新账户提交恶意软件的…

kubernetes中特定域名使用自定义DNS服务器出现的解析异常

故障发生背景&#xff1a; 租户反馈生产业务服务连接到中间件的时候&#xff0c;偶尔会有连接失败的情况&#xff0c;然后我们查看对应组件服务正常&#xff0c;手动请求组件服务也显示正常&#xff0c;让租户查看业务服务日志发现报错无法解析对应的域名&#xff0c;我们手动是…

数据库的分片策略

数据库的分片策略 1、范围分片2、hash 取模分片3、一致性hash 分片 1.分片策略 数据库的分片策略是指将数据库中的数据按照一定的规则和方式进行分割&#xff08;分片&#xff09;存储在不同的物理节点或服务器上的策略。分片策略旨在实现水平扩展&#xff0c;提高数据库的性…

暑假第九天打卡

英语&#xff1a; 新东方六级一单元单词刷题复习 离散&#xff1a; 例12 使用消解算法判断下述公式是否是可满足的: 公式 S p∧(p∨q)∧(p∨q)∧(q∨r)∧(q∨r) 解&#xff1a; S p∧(p∨q)∧(p∨q)∧(q∨r)∧(q∨r) //化为主合取式 循环1&#xff1a; S0 S1 {p…

Windows 进程和作业

Windows 进程和作业 创建进程CreateProcess 函数的参数CreateProcess 的流程 创建Windows“现代化”进程创建其他类型的进程 进程的内部构造EPROCESSKPROCESSPEBCSR_PROCESSW32PROCESS 受保护进程最小进程和 Pico 进程最小进程Pico进程 Trustlet 安全进程进程的终止作业作业的限…

合并完之后,进行回退

我是将分支合并到了uat_v3上&#xff0c;现在又要求将uat_v3上的代码回退到合并以前&#xff1b; 我是将origin/uat_v3 checkout 除一份本地uat_v3,然后选中合并以前的commit记录&#xff0c;新建分支 temp/reverse 分支&#xff1b; 这样我本地的temp/reverse分支就已经是合…

[Java进阶] Swing两万字大总结一(超详细教程,这不得收藏一波)

&#x1f525;一个人走得远了&#xff0c;就会忘记自己为了什么而出发&#xff0c;希望你可以不忘初心&#xff0c;不要随波逐流&#xff0c;一直走下去&#x1f3b6; &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; &#x1f984; …