news 2026/4/30 17:19:28

C语言版2048小游戏

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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、棋盘制作
用二维数组来存储数字,制作与显示棋盘

/* by 01022.hk - online tools website : 01022.hk/zh/quchong.html */ //用整型数组表示矩阵方格 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、控制数字的移动与合成

/* by 01022.hk - online tools website : 01022.hk/zh/quchong.html */ //向左边移动 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、判断是否可以合成

//是否可以合成 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、判断棋盘是否已满

//是否已经满了 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、初始化游戏数据

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

二、界面渲染

1、创建游戏窗口

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

2、显示矩阵棋盘

//图片数组 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、游戏结束界面渲染

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

三、主函数编写

//头文件调用 #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小游戏的源码和图片资源可在项目源码处获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 6:26:35

Telegram APP技术架构分析报告

Telegram APP技术架构分析报告 目录 一、核心结论二、应用格式与模块结构三、原生架构分析四、网络层与MTProto五、媒体处理技术栈六、安全与加密七、业务逻辑与UI架构八、数据存储九、第三方与外部依赖十、技术架构总结十一、总结 一、核心结论 Telegram Android 采用纯原生…

作者头像 李华
网站建设 2026/5/1 6:25:28

32岁,代码还没写完,人没了

文章目录 「管理者要陪团队一起扛压力」心电图正常≠没事工伤认定&#xff1f;写给还在卷的兄弟们最后说两句 前几天刷到这条新闻的时候&#xff0c;我正在公司改一个线上bug&#xff0c;改着改着手就停了。 广州&#xff0c;32岁&#xff0c;程序员&#xff0c;猝死。 这几个…

作者头像 李华
网站建设 2026/5/1 6:16:08

SCI写作避坑|从大纲到查重全流程干货,新手也能快速上手✨

作为常年和SCI打交道的科研人&#xff0c;今天不聊虚的&#xff0c;纯纯干货分享——毕竟谁没在SCI写作里踩过坑呢&#xff1f; 说真的&#xff0c;写SCI最磨人的不是实验数据不够&#xff0c;而是从一开始的大纲搭建就卡壳&#xff0c;好不容易搭完大纲&#xff0c;绘图制表、…

作者头像 李华
网站建设 2026/4/29 0:17:15

【开题答辩过程】以《基于Spring Boot的疗养院理疗管理系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看

个人简介慕婉学姐精通Java、PHP、微信小程序、Python、Golang和安卓开发等语言&#xff0c;擅长开发大数据、深度学习、网站、小程序、安卓应用和算法项目。平时从事项目定制开发、代码讲解、答辩教学和文档编写&#xff0c;也掌握一些降重技巧。感谢大家的持续关注&#xff01…

作者头像 李华
网站建设 2026/4/25 9:43:16

学术“降重革命”:书匠策AI如何用“语义显微镜”重塑论文查重新范式

在学术写作的江湖里&#xff0c;“查重”二字如同一把悬在头顶的达摩克利斯之剑。无论是本科生为毕业论文焦头烂额&#xff0c;还是硕博生为期刊投稿殚精竭虑&#xff0c;查重率始终是绕不开的“生死线”。传统查重工具像一台笨重的“文字扫描仪”&#xff0c;只能机械比对字符…

作者头像 李华
网站建设 2026/4/23 19:23:43

2026年期货数据接口盘点_主流工具的数据服务体验

声明&#xff1a;本文为个人学习笔记&#xff0c;仅供技术交流&#xff0c;不构成任何投资建议。文中提及的工具请自行评估。 一、数据是量化的基石 二十年的期货交易生涯&#xff0c;让我对市面上的量化工具了如指掌。但不管工具怎么变&#xff0c;有一点始终不变&#xff1a…

作者头像 李华