C语言版2048小游戏

一、游戏特点

2048是一款数字益智类游戏,玩家需要使用键盘控制数字方块的移动,合并相同数字的方块,最终达到数字方块上出现"2048"的目标。

为用C语言实现2048的小游戏项目,我们需先观察2048小游戏的特点和我们需要实现的一些功能:

1.需要一个棋盘来储存数字,用什么来表示棋盘?

2.需要控制数字的移动,怎样控制数字的移动?

3.需要在数字移动的过程中产生新的随机数,怎么生成新的随机数?

4.需要控制数字是否需要合成,怎么判断数字是否需要合成和怎么合成?

5.需要判断判定游戏是否成功,怎么判断游戏是否结束?

6.需要丰富游戏的界面,怎样使游戏界面好看一点?

二、游戏运行示意图

三、工具准备

1.代码运行平台:Visual Studio 2022

官网地址:https://visualstudio.microsoft.com/zh-hans/

2.图形库:Easyx

官网地址:https://easyx.cn/

四、代码实现流程

一、核心逻辑

1、棋盘制作

用二维数组来存储数字,制作与显示棋盘

C 复制代码
//用整型数组表示矩阵方格
int arr[4][4] = { 0 };
//打印矩阵方格的数据
void PrintArr()
{
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
			printf("%d\t", arr[row][column]);
		}
		printf("\n");
	}
}

2、控制数字的移动与合成

C 复制代码
//向左边移动
void Left()
{
	//遍历行
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
            //如果当前格子为空,则向右移动
			if (arr[row][column] == 0)
			{
				//从后面找一个不为空的格子,如果找到,则交换位置
				for (int i = column + 1; i < 4; i++)
				{
					if (arr[row][i]!= 0)
					{
						arr[row][column] = arr[row][i];
						arr[row][i] = 0;
						//处理一个非空位置后,条件不成立,不能往后走了
						break;
					}
				}
			}
			//如果不为0,表示要合并
			if (arr[row][column] != 0)
			{
				//从后面找一个和当前数据相同的数据,遇到0就跳过,遇到不同的,退出
				for (int i = column + 1; i < 4; i++)
				{
					if (arr[row][i] == arr[row][column])
					{
						//数据合并
						arr[row][column] *= 2;
						arr[row][i] = 0;
						//合并完成就结束查找
						break;
					}
					else if (arr[row][i] == 0)
						continue;

					else
						break;
				}
			}
		}
	}
	CreateRandData(1);
}
//向右边移动
void Right()
{
	for (int row = 0; row < 4; row++)
	{
		for (int column = 3; column >= 0; column--)
		{
			//如果当前格子为空,则向左移动
			if (arr[row][column] == 0)
			{
				//从后面找一个不为空的格子,如果找到,则交换位置
				for (int i = column - 1; i >= 0; i--)
				{
					if (arr[row][i] != 0)
					{
						arr[row][column] = arr[row][i];
						arr[row][i] = 0;
						//处理一个非空位置后,条件不成立,不能往后走了
						break;
					}
				}
			}
			//如果不为0,表示要合并
			if (arr[row][column] != 0)
			{
				//从后面找一个和当前数据相同的数据,遇到0就跳过,遇到不同的,退出
				for (int i = column - 1; i >=0; i--)
				{
					if (arr[row][i] == arr[row][column])
					{
						//数据合并
						arr[row][column] *= 2;
						arr[row][i] = 0;
						//合并完成就结束查找
						break;
					}
					else if (arr[row][i] == 0)
						continue;

					else
						break;
				}
			}
		}
	}
	CreateRandData(1);
}
//向上边移动
void Up()
{
	for (int column = 0; column < 4; column++)
	{
		for (int row = 0; row < 4; row++)
		{
			//如果当前格子为空,则向下移动
			if (arr[row][column] == 0)
			{
				//从后面找一个不为空的格子,如果找到,则交换位置
				for (int i = row + 1; i < 4; i++)
				{
					if (arr[i][column] != 0)
					{
						arr[row][column] = arr[i][column];
						arr[i][column] = 0;
						//处理一个非空位置后,条件不成立,不能往后走了
						break;
					}
				}
			}
			//如果不为0,表示要合并
			if (arr[row][column] != 0)
			{
				//从后面找一个和当前数据相同的数据,遇到0就跳过,遇到不同的,退出
				for (int i = row + 1; i < 4; i++)
				{
					if (arr[i][column] == arr[row][column])
					{
						//数据合并
						arr[row][column] *= 2;
						arr[i][column] = 0;
						//合并完成就结束查找
						break;
					}
					else if (arr[i][column] == 0)
						continue;

					else
						break;
				}
			}
		}
	}
	CreateRandData(1);
}
//向下边移动
void Down()
{
	for (int column = 0; column < 4; column++)
	{
		for (int row = 3; row >= 0; row--)
		{
			//如果当前格子为空,则向上移动
			if (arr[row][column] == 0)
			{
				//从后面找一个不为空的格子,如果找到,则交换位置
				for (int i = row - 1; i >= 0; i--)
				{
					if (arr[i][column] != 0)
					{
						arr[row][column] = arr[i][column];
						arr[i][column] = 0;
						//处理一个非空位置后,条件不成立,不能往后走了
						break;
					}
				}
			}
			//如果不为0,表示要合并
			if (arr[row][column] != 0)
			{
				//从后面找一个和当前数据相同的数据,遇到0就跳过,遇到不同的,退出
				for (int i = row - 1; i >= 0; i--)
				{
					if (arr[i][column] == arr[row][column])
					{
						//数据合并
						arr[row][column] *= 2;
						arr[i][column] = 0;
						//合并完成就结束查找
						break;
					}
					else if (arr[i][column] == 0)
						continue;

					else
						break;
				}
			}
		}
	}
	CreateRandData(1);
}

3、判断是否可以合成

C 复制代码
//是否可以合成
int CamMerge()
{
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
			if (column+1<4&&(arr[row][column] == arr[row][column+1])|| row+1<4&&(arr[row][column] == arr[row+1][column ]))
			{
				//可以合并
				return 1;
			}
		}
	}
	//没有可以合并的数据
	return 0;
}

4、判断棋盘是否已满

C 复制代码
//是否已经满了
int IsFull()
{
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
			if (arr[row][column] == 0)
			{
				//没有满
				return 1;
			}
		}
	}
	//整个循环结束没有返回1,已经满了
	return 0;
}
···
5、在空位生成随机数
```C
//调用头文件
#include<stdlib.h>
#include<time.h>
//空位数组
int nullCount = 0;//记录空位的数量
int nullPos[2][16] = { 0 };//记录空位的行列数据
//获取空位数据
int GetNullPos()
{
	//把空位数量归零
	nullCount = 0;
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
			if (arr[row][column] == 0)
			{
				//记录下来,行和列
				nullPos[0][nullCount] = row;//nullPos[0]记录行
				nullPos[1][nullCount] = column;//nullPos[1]记录列
				//更新空位个数
				nullCount++;
			}
		}
	}
	return nullCount;
}
//生成随机数据
void CreateRandData(int count)
{
	srand(time(0));
	//判断是否有空位,同时更新空位的数据
	for (int c = 0; c < count; c++)
	{
		if (GetNullPos() == 0)
			return;
		//随机:随机一个数表示在nullPos的位置
		int pos = rand() % nullCount;//0到nullCount-1

		//生成2/4
		int row = nullPos[0][pos];
		int column = nullPos[1][pos];
		arr[row][column] = (rand() % 2 + 1) * 2;
	}
}

6、初始化游戏数据

C 复制代码
// 初始化游戏数据
void InitData()
{
	// 初始化数据
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
			arr[row][column] = 0;
		}
	}
	// 生成 2 个随机数
	CreateRandData(2);
}

二、界面渲染

1、创建游戏窗口

C 复制代码
//调用图形库
#include<easyx.h>
void InitWindow()
{
	//创建一个窗口
	window=initgraph(700, 750);
	//设置标题
	settextcolor(WHITE);//确定颜色
	settextstyle(60, 0, _T("黑体"));//设置字体
	outtextxy(250, 0, _T("2048"));//标题位置
}

2、显示矩阵棋盘

C 复制代码
//图片数组
const TCHAR* Lpicture[] = { _T("Image/0.png"),_T("Image/2.png"), _T("Image/4.png"), _T("Image/8.png"), _T("Image/16.png"), _T("Image/32.png"), _T("Image/64.png"), _T("Image/128.png"), _T("Image/256.png"), _T("Image/512.png"), _T("Image/1024.png"), _T("Image/1024.png") };
//控制图片输出
int log(int n)
{
	if (n <= 1)
		return 0;
	int count = 0;
	while (n>1)
	{
		count++;
		n /= 2;
	}
	return count;
}
//生成游戏界面
void updata()
{
	//生成矩阵格子
	for (int row = 0; row < 4; row++)
	{
		for (int column = 0; column < 4; column++)
		{
			int pos = log(arr[row][column]);
			//加载图片
			IMAGE	img;
			loadimage(&img, Lpicture[pos]);
			//显示图片
			putimage(20+(150+10)*column, 70+(150+10)*row, &img);
		}
	}
}

3、游戏结束界面渲染

C 复制代码
void DrawGameOver()
{
	cleardevice();
	settextstyle(60, 0, _T("黑体"));
	outtextxy(250, 250, _T("Game Over"));
}

三、主函数编写

C 复制代码
//头文件调用
#include <windows.h>
//窗口句柄
HWND window = nullptr;
int main()
{

	// 初始化数据
	InitData();
	// 初始化窗口
	InitWindow();

	// 游戏的主逻辑
	while (IsWindow(window))
	{
		// 每帧更新并处理事件
		updata();

		// 如果游戏结束,绘制一次并进入等待逻辑
		if (GetNullPos() == 0 && CamMerge() == 0)
		{
			DrawGameOver();

			// 等待玩家操作:Enter 重启,Esc 退出
			while (IsWindow(window))
			{
				ExMessage msg;
				if (peekmessage(&msg))
				{
					if (msg.message == WM_KEYDOWN)
					{
						if (msg.vkcode == VK_RETURN) // 回车重启
						{
							InitData();
							cleardevice();
							break; // 退出等待,回到主循环
						}
						else if (msg.vkcode == VK_ESCAPE) // Esc 退出
						{
							closegraph();
							return 0;
						}
					}
				}
				Sleep(50); // 降低 CPU 占用,避免高频重绘
			}
		}

		// 处理输入并移动(保持原有逻辑)
		ExMessage msg;
		if (peekmessage(&msg))
		{
			if (msg.message == WM_KEYDOWN)
			{
				switch (msg.vkcode)
				{
				case VK_UP:
					Up();
					break;
				case VK_DOWN:
					Down();
					break;
				case VK_LEFT:
					Left();
					break;
				case VK_RIGHT:
					Right();
					break;
				default:
					break;
				}
			}
		}
		// 小睡一会儿,避免空循环耗尽 CPU
		Sleep(10);
	}

	closegraph();
}

需要注意的事项

1、图片资源必须与代码在同一目录下,方便调用。

最后的话

那么关于用C语言来实现游戏2048就讲解到这里啦~如果有说的不够充分或者有错误的地方,还希望各位能在评论区积极指出,我也会积极学习的!完整2048小游戏的源码和图片资源可在项目源码处获取

相关推荐
梵刹古音2 小时前
【C语言】 循环结构
c语言·开发语言·算法
皮皮哎哟2 小时前
冒泡排序与数组传递全解析 一维二维指针数组及二级指针应用指南
c语言·算法·冒泡排序·二维数组·指针数组·传参·二级指针
蒸蒸yyyyzwd2 小时前
c网络编程学习笔记
c语言·网络·学习
烟花落o2 小时前
贪吃蛇及相关知识点讲解
c语言·前端·游戏开发·贪吃蛇·编程学习
头发还没掉光光2 小时前
Linux 高级 IO 深度解析:从 IO 本质到 epoll全面讲解
linux·服务器·c语言·c++
No0d1es3 小时前
电子学会青少年软件编程(C语言)等级考试试卷(一级)2025年12月
c语言·青少年编程·等级考试·电子学会·一级
爱编码的小八嘎3 小时前
C语言对话-18.我为你准备一切
c语言
请注意这个女生叫小美3 小时前
C语言 实例20 25
c语言·开发语言·算法
枫叶丹43 小时前
【Qt开发】Qt系统(十一)-> Qt 音频
c语言·开发语言·c++·qt·音视频