【实战项目】使用C语言和easyX,一起完成数字拼图游戏吧!快来挑战一下吧~

news2024/10/6 4:08:29

这款简易的拼图游戏包含了15个数字方块,你需要将它们按照顺序排列成1~15的数字,就能完成游戏。

在游戏中会记录你完成拼图所用的时间。我想强调的是,一个精彩的游戏并不一定需要使用图片。只要功能和手感都做得出色,游戏同样能够带来乐趣。因此,我开发了这个拼图游戏作为一个例子来说明这一点。

 

让我们先简单了解游戏,然后尝试一下吧!我会直接分享源码,并附有注释供大家参考。

#include <graphics.h>
#include <time.h>
#include <conio.h>
 
 
IMAGE	g_Block[16];		// 拼图碎片
byte	g_Map[4][4];		// 游戏地图(存储了每个碎片的下标)
byte	g_EmptyX, g_EmptyY;	// 当前空格的位置
long	g_timeStart;		// 游戏开始时间
 
 
// 初始化拼图
void InitBlock()
{
	// 初始化拼图碎片
	wchar_t s[3];
	for (int i = 0; i < 16; i++)
	{
		g_Block[i].Resize(100, 100);
		SetWorkingImage(&g_Block[i]);
 
		// 背景
		setbkcolor(BLACK);
		cleardevice();
		setfillcolor(HSVtoRGB(360.0 * i / 16, 1, 0.5));
		solidrectangle(2, 2, 98, 98);
		// 文字
		settextstyle(64, 0, _T("Arial"), 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);
		setbkmode(TRANSPARENT);
		settextcolor(WHITE);
		_itow_s(i + 1, s, 10);
		outtextxy((100 - textwidth(s)) / 2, 18, s);
	}
	// 恢复绘图目标
	SetWorkingImage(NULL);
}
 
 
// 显示游戏界面
void Draw()
{
	for (int y = 0; y < 4; y++)
		for (int x = 0; x < 4; x++)
		{
			if (g_Map[x][y] != 15)
				putimage(x * 100 + 40, y * 100 + 40, &g_Block[g_Map[x][y]]);
			else
			{
				// 最后一片拼图暂时不显示
				setfillcolor(BLACK);
				solidrectangle(x * 100 + 40, y * 100 + 40, x * 100 + 139, y * 100 + 139);
			}
		}
 
	// 输出游戏时间
	settextstyle(36, 0, L"微软雅黑", 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);
	settextcolor(WHITE);
	long curtime = clock();
	wchar_t s[20];
	swprintf_s(s, L"%.2f 秒  ", (curtime - g_timeStart) / (double)CLOCKS_PER_SEC);
	outtextxy(480, 40, L"游戏用时");
	outtextxy(480, 90, s);
}
 
 
// 移动拼图
void MoveTo(int newx, int newy)
{
	g_Map[g_EmptyX][g_EmptyY] = g_Map[newx][newy];
	g_Map[newx][newy] = 15;
	g_EmptyX = newx;
	g_EmptyY = newy;
}
 
 
// 将拼图随机打乱
void RandMap()
{
	// 初始化目标拼图
	for (int i = 0; i < 16; i++)
		g_Map[i % 4][i / 4] = i;
	g_EmptyX = 3;
	g_EmptyY = 3;
 
	// 打乱拼图顺序。注:只能相邻交换,否则可能无解
	for (int i = 0; i < 1000; i++)
	{
		// 产生随机方向
		int n = (rand() % 4) * 2 + 1;
		int dx = n / 3 - 1;
		int dy = n % 3 - 1;
		// 移动空位
		if (g_EmptyX + dx >= 0 && g_EmptyX + dx < 4 && g_EmptyY + dy >= 0 && g_EmptyY + dy < 4)
			MoveTo(g_EmptyX + dx, g_EmptyY + dy);
	}
}
 
 
// 判断拼图是否成功
bool IsWin()
{
	for (int i = 0; i < 16; i++)
		if (g_Map[i % 4][i / 4] != i)
			return false;
	return true;
}
 
 
// 进行游戏
void Play()
{
	ExMessage msg;
	while (!IsWin())	// 游戏主循环
	{
		// 处理鼠标和键盘控制
		while (peekmessage(&msg, EM_MOUSE | EM_KEY))
		{
			switch (msg.message)
			{
				case WM_LBUTTONDOWN:
					if (msg.x >= 40 && msg.x < 440 && msg.y >= 40 && msg.y < 440)
					{
						int newx = (msg.x - 40) / 100;
						int newy = (msg.y - 40) / 100;
 
						if (abs(g_EmptyX - newx) + abs(g_EmptyY - newy) == 1)
							MoveTo(newx, newy);
					}
					break;
					
				case WM_KEYDOWN:
					switch(msg.vkcode)
					{
						case VK_LEFT:
						case 'A':
							if (g_EmptyX > 0) MoveTo(g_EmptyX - 1, g_EmptyY);	// 左
							break;
 
						case VK_UP:
						case 'W':
							if (g_EmptyY > 0) MoveTo(g_EmptyX, g_EmptyY - 1);	// 上
							break;
 
						case VK_RIGHT:
						case 'D':
							if (g_EmptyX < 3) MoveTo(g_EmptyX + 1, g_EmptyY);	// 右
							break;
 
						case VK_DOWN:
						case 'S':
							if (g_EmptyY < 3) MoveTo(g_EmptyX, g_EmptyY + 1);	// 下
							break;
					}
					break;
			}
		}
 
		// 显示游戏界面
		Draw();
		Sleep(20);
	}
}
 
 
// 游戏胜利
void Win()
{
	putimage(g_EmptyX * 100 + 40, g_EmptyY * 100 + 40, &g_Block[15]);
}
 
 
// 主函数
int main()
{
	srand(clock());							// 生成随机种子
	HWND wnd = initgraph(640, 480);			// 创建绘图窗口
	InitBlock();							// 初始化拼图
 
	do
	{
		RandMap();							// 随机打乱地图
		flushmessage(EM_MOUSE | EM_KEY);	// 清空鼠标和键盘缓冲区
		g_timeStart = clock();				// 获取游戏开始时间
		Play();								// 开始游戏
		Win();								// 游戏胜利
	} while (MessageBox(wnd, L"恭喜您成功啦。\n重来一局吗?", L"胜利", MB_YESNO | MB_ICONQUESTION) == IDYES);
 
	closegraph();
	return 0;
}

快点尝试一下!

我还有其他资源可以分享给大家,包括从零开始的教程和C语言C++项目案例。这些资源将帮助大家克服学习C语言的困难。

 

 

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

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

相关文章

从0到1,深刻理解Linux权限

[Linux]深刻理解Linux权限 从0到1&#xff0c;深刻理解Linux权限Linux权限的概念Linux权限管理Linux文件访问者文件类型和访问权限文件类型访问权限 文件访问权限设置修改文件权限修改文件拥有者修改所属组 umask掩码目录权限目录权限问题粘滞位 权限总结&#xff1a; 从0到1&a…

1688商品详细信息价格SKU接口

随着新零售时代的到来&#xff0c;越来越多的企业开始关注电商平台&#xff0c;其中1688平台作为国内重要的B2B电商平台之一&#xff0c;对于企业发展、产品销售等方面有着重要的价值。在使用1688平台出售商品时&#xff0c;如何优化商品详情页、提高搜索排名、增加商品曝光度&…

PG15.3.0源码编译安装日志插件pgbadger(上)

一、开启相关日志 修改后alter一定要重启&#xff0c;才会修改 pg_ctl restart -D /usr/local/pgsql/data -l logfile按照下面的方法一个个修改。 log_destination csvlog # 可选 logging_collector on log_min_duration_statement 0 log_line_prefix %t [%p]: us…

(转载)MATLAB智能算法30个案例分析(2)——基于遗传算法和非线性规划的函数寻优算法

以下内容大部分来源于《MATLAB智能算法30个案例分析》&#xff0c;仅为学习交流所用。 1 理论基础 1.1 非线性规划 非线性规划是20世纪50年代形成的一门新兴学科。1951年库恩和塔克发表的关于最优性条件(后来称为库恩塔克条件)的论文是非线性规划诞生的标志。非线性规划研究…

聚会游戏玩什么?UMO轻松炒热气氛

UMO是一款有趣的多人益智桌游&#xff0c;考验玩家耐力和技巧的比拼&#xff01;玩家将在游戏中通过特定的规则来出牌&#xff0c;谁先出完所有牌谁就赢&#xff0c;游戏非常讲究策略和运气哦~ 当玩家手上只剩一张牌时&#xff0c;必须喊出UMO&#xff01;游戏因此得名。【数字…

自学网络安全,最应该先学的五大技能树是什么?(附学习路线图)

前言&#xff1a; 近几年网络安全事件频发&#xff0c;国家对于互联网信息安全和互联网舆情的重视程度不断提升有关&#xff0c;全球网络安全岗位缺口达500万&#xff0c;中国约100万&#xff0c;产业人才需求逐年增加&#xff0c;网络安全行业的相关岗位成为炙手可热的职业。…

COMSOL光电案列应用实操教学:

COMSOL多物理场仿真软件以高效的计算性能和杰出的多场耦合分析能力实现了精确的数值仿真&#xff0c;已被广泛应用于各个领域的科学研究以及工程计算&#xff0c;为工程界和科学界解决了复杂的多物理场建模问题。光电作为物理类专业课程中极为重要的一部分&#xff0c;其教学内…

如何做到设备维护事半功倍?

在工业生产过程中&#xff0c;设备故障可能导致生产停机、成本增加和安全风险。因此&#xff0c;及时监测设备的健康状况&#xff0c;预测潜在故障&#xff0c;并采取相应的维护措施至关重要。 振动在线监测系统是一种有效的工具&#xff0c;可以实时监测设备振动&#xff0c;并…

3. Linux下实现统计文件单词个数和出现次数

本文介绍的是在Linux下实现统计文件单词个数和出现次数&#xff0c;以及实践过程中遇到的gcc编译器不匹配问题 一、实现文件单词个数统计 #include <stdio.h>#define IN_Word 1 #define OUT_Word 0 #define INIT OUT_Wordint splite(char c){if ((c ) || (c\n) || (c\t…

ChatGPT ?、AI 和机器人,是为人类打工还是将取代人类?

随着ChatGPT引起全球热潮&#xff0c;我们看到这类AI大模型技术比较热门的落地领域聚焦在办公平台、家庭、电商营销、社交文娱等多个方向&#xff0c;又进一步向下渗透到生产和生活的各个环节。这些场景大多数聚焦于线上&#xff0c;涉及内容创作和交互方式变革两个方向&#x…

【全网首发】华秋CAM:免费Gerber查看器,离线版!

自华秋DFM可制造性和组装性分析软件上线以来&#xff0c;已为众多硬件工程师、PCB工程师、CAM工程师、电子爱好者、PCBA采购、SMT工厂等众多行业用户&#xff0c;解决了各种PCB设计隐患和规避各类生产风险等问题&#xff0c;并获得了30万用户的一致好评&#xff01; 现在&…

双非渣本测试,3个月逆袭字节,入职那天“泪目”了

个人背景情况 2017 年毕业于一所不知名双非本科大学&#xff0c;毕业时就有着一颗想进大厂的心&#xff0c;但又想留在成都&#xff0c;不愿意去北上广&#xff0c;现在其实相当后悔。当年在成都的大厂少之又少&#xff0c;再加上校招时非常努力地玩耍&#xff0c;导致投的几个…

全网独一份微服务架构深度解析,连京东师哥都熬夜也要看完

什么是微服务&#xff0c;为什么需要用微服务&#xff1f; 一、微服务是什么&#xff1f; 定义&#xff1a;微服务是一些协同工作的小而自治的服务&#xff0c;这个服务是高凝聚力和松散耦合的。 微服务有以下特征&#xff1a; 1.一组小的服务&#xff08;大写没有特别的标…

Linux之firewalld防火墙基础

目录 一、firewalld的简介 二、iptables与firewalld的联系与区别 1&#xff09;iptables与firewalld的联系 netfilter Firewalld/iptables 2&#xff09;iptables与firewalld的区别 区别一&#xff1a; 区别二&#xff1a; 区别三&#xff1a; 三、firewalld区域 1…

meta标签 http-equiv常用配置记录

meta标签 元素可提供有关页面的元信息&#xff08;meta-information&#xff09;&#xff0c;比如针对搜索引擎和更新频度的描述和关键词。 标签位于文档的头部&#xff0c;不包含任何内容。 标签的属性定义了与文档相关联的名称/值对。 属性 使用实例 禁止浏览器从本地机的缓…

涨姿势了,分享一个简单好用的源码调试方法

之前发了一篇文章&#xff0c;文章中有这样的一段描述&#xff1a; 然后有个读者来问我&#xff1a; 是怎么把 JDK 源码中的一行代码给注释掉的&#xff1f; 这个问题确实不错&#xff0c;属于一个偶尔用一下能起到奇效的源码调试技巧。所以我决定写个文章来说明一下这个问题。…

Mysql-存储过程简单入门

定义&#xff1a; 存储过程的英文是 Stored Procedure 。它的思想很简单&#xff0c;就是一组经过 预先编译 的 SQL 语句 的封装。 执行过程&#xff1a;存储过程预先存储在 MySQL 服务器上&#xff0c;需要执行的时候&#xff0c;客户端只需要向服务器端发出调用 存储过程的命…

管中窥豹!从冠德石油看数字化对加油站的影响力

从上个世纪90年代起&#xff0c;至2010年前后&#xff0c;是国内信息化建设的高速发展期。这段时间无论是应用软件、企业网站还是商业咨询&#xff0c;无不呈现井喷式发展。大多数企业和政府机关均完成了或多或少的信息化建设。IT带来了标准化、科学化的管理和运作模式&#xf…

keil5 #include“头文件”前面有红叉X,但编译不报错

问题 如图 编译不报错 解决办法 keil软件界面&#xff0c;第一行图标栏的最后有个扳手&#x1f527;符号&#xff0c;点开&#xff0c;点击“text completion ”标签页&#xff0c; 右侧“text template”栏选中#define&#xff0c;左边“dynamic syntax checking”栏里取…

软件测试面试题自动化面经分享——这才是高薪的秘诀!

Hello&#xff0c;你们的好朋友来了&#xff01;今天猜猜我给大家带来点啥干货呢&#xff1f;最近很多小伙伴出去面试的时候经常会被问到跟自动化测试相关的面试题。所以&#xff0c;今天特意给大家整理了一些经常被公司问到的自动化测试相关的面试题。停&#xff0c;咱先收藏起…