基于 C++ 与 EasyX 图形库的 2048 桌面小游戏

📅 2026/7/23 20:18:06 👁️ 阅读次数 📝 编程学习
基于 C++ 与 EasyX 图形库的 2048 桌面小游戏

开发环境:Visual Studio 2022、C/C++、EasyX 图形库

使其进行左右上下移动

左移动的主要代码

void Left() { //遍历行数据 for (int row = 0;row < 4;row++) { //遍历列数据 for (int column = 0;column < 4;column++) { //在row行的最开始找空位置,找0 if (array[row][column] == 0)//如果row行。column列是0 { //从后面找一个不为0的数据拿到这个空位置 for (int t = column + 1;t < 4;t++) { //判断我在后面找到的这个位置是不是空位置。如果不是就搬到空位上 if (array[row][t] != 0) { //交换位置 array[row][column] = array[row][t]; array[row][t] = 0; //找到一个之后,这个位置就不为空了,就不能往后找了 break; } } } //如果不为0,表示要合并 if (array[row][column] != 0) { //从后面找一个和当前相同的数据 for (int t = column + 1; t < 4;t++) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[row][t] == array[row][column]) { //数据合并 array[row][column] *= 2; array[row][t] = 0; //合并完成就结束查找 break; } else if (array[row][t] == 0) continue; else//遇到即不为0也不相同 break; } } } } CreatRandData(1); }

右移动的主要代码

void Right() { //遍历行 for (int row = 0;row < 4;row++) { //遍历列 for (int column = 3;column >= 0;column--) { //在row行的最开始找空位置,找0 if (array[row][column] == 0)//如果row行。column列是0 { //从前面找一个不为0的数据拿到这个空位置 for (int t = column - 1;t >= 0;t--) { //找到一个不为0的位置 if (array[row][t] != 0) { //进行交换 array[row][column] = array[row][t]; array[row][t] = 0; //交换完成结束查找 break; } } } //如果不为0 if (array[row][column] != 0) { for (int t = column - 1;t >= 0;t--) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[row][t] == array[row][column]) { //数据合并 array[row][column] *= 2; array[row][t] = 0; //合并完成就结束查找 break; } else if (array[row][t] == 0) continue; else//遇到即不为0也不相同 break; } } } } CreatRandData(1); }

上移动的主要代码

void Up() { //遍历列 for (int column = 0;column < 4;column++) { //遍历行 for (int row = 0;row < 4;row++) { //找到一个空位置 if (array[row][column] == 0) { //从当前空位置往下查找,找一个不为0的数据 for (int t = row + 1;t < 4;t++) { //找到一个不为0 if (array[t][column] != 0) { //数据交换 array[row][column] = array[t][column]; array[t][column] = 0; //结束查找 break; } } } if (array[row][column] != 0) { //从后面找一个和当前相同的数据 for (int t = row + 1; t < 4;t++) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[t][column] == array[row][column]) { //数据合并 array[row][column] *= 2; array[t][column] = 0; //合并完成就结束查找 break; } else if (array[t][column] == 0) continue; else//遇到即不为0也不相同 break; } } } } CreatRandData(1); }

下移动的主要代码

void Down() { // 遍历列 for (int column = 0;column < 4;column++) { //遍历行 for (int row = 3;row >= 0;row--) { //找到一个空位置 if (array[row][column] == 0) { //从当前空位置往下查找,找一个不为0的数据 for (int t = row - 1;t >=0;t--) { //找到一个不为0 if (array[t][column] != 0) { //数据交换 array[row][column] = array[t][column]; array[t][column] = 0; //结束查找 break; } } } if (array[row][column] != 0) { //从后面找一个和当前相同的数据 for (int t = row - 1; t >= 0;t--) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[t][column] == array[row][column]) { //数据合并 array[row][column] *= 2; array[t][column] = 0; //合并完成就结束查找 break; } else if (array[t][column] == 0) continue; else//遇到即不为0也不相同,就直接结束 break; } } } } CreatRandData(1); }

主代码

int main() { //初始化数据 InitData(); //初始化窗口 InitWindows(); //游戏的主逻辑 while (IsWindow(window) && GameOver() == 0) { updata(); //接受用户键盘操作 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: continue; } Success(); } } } system("pause"); closegraph(); return 0; }

运行结果

随机生成两个

格子满后

源代码:

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <easyx.h> //整型数组 int array[4][4] = { 0 }; //空位数组 int nullCount = 0;//记录空位的数量 int nullPos[2][16] = { 0 };//记录空位的行列数据 //窗口句柄 HWND window = nullptr; //图片数组 const char* picture[] = { "Image/0.png", "Image/2.png", "Image/4.png", "Image/8.png", "Image/16.png", "Image/32.png", "Image/64.png", "Image/128.png", "Image/256.png", "Image/512.png", "Image/1024.png", "Image/2048.png", "Image/4096.png" }; //打印矩阵方格的数据 void PrintArray() { for (int row = 0;row < 4;row++) { for (int column = 0; column < 4;column++) { printf("%d\t", array[row][column]); } printf("\n"); } } //判断是不是已经满了 int IsFull() { //实际就是判断是否存在0,空位 for (int row = 0;row < 4;row++) { for (int column = 0;column < 4;column++) { if (array[row][column] == 0) { //没有满 return 1; } } } //整个循环都结束了,都没返回1,说明已经满了 return 0; } //是否能合并 int CanMerge() { //实际就是判断是否存在0,空位 for (int row = 0;row < 4;row++) { for (int column = 0;column < 4;column++) { if (column + 1 < 4 && (array[row][column] == array[row][column + 1]) || row + 1 < 4 && (array[row][column] == array[row + 1][column])) { //可以合并 return 1; } } } //循环都结束了,都没有返回1,表示没有可以合并的 return 0; } //获取空位置 int GetNullPos() { //把空位个数归零 nullCount = 0; for (int row = 0; row < 4;row++) { for (int column = 0;column < 4;column++) { if (array[row][column] == 0) { //记录下来,行和列 nullPos[0][nullCount] = row;//nullPos[0]用来记录行 nullPos[1][nullCount] = column;//nullPos[1]用来记录列 //更新空位的个数 nullCount++; } } } return nullCount; } //随机位置的数据的生成 void CreatRandData(int count) { //设置时间种子 srand(time(0)); //有可能随机到了有数据的位置 /*int row = rand() % 4; int column = rand() % 4; */ //判断是否还存在空位,同时还更新空位的数据 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]; array[row][column] = (rand() % 2 + 1) * 2; } } //向左边合并移动 void Left() { //遍历行数据 for (int row = 0;row < 4;row++) { //遍历列数据 for (int column = 0;column < 4;column++) { //在row行的最开始找空位置,找0 if (array[row][column] == 0)//如果row行。column列是0 { //从后面找一个不为0的数据拿到这个空位置 for (int t = column + 1;t < 4;t++) { //判断我在后面找到的这个位置是不是空位置。如果不是就搬到空位上 if (array[row][t] != 0) { //交换位置 array[row][column] = array[row][t]; array[row][t] = 0; //找到一个之后,这个位置就不为空了,就不能往后找了 break; } } } //如果不为0,表示要合并 if (array[row][column] != 0) { //从后面找一个和当前相同的数据 for (int t = column + 1; t < 4;t++) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[row][t] == array[row][column]) { //数据合并 array[row][column] *= 2; array[row][t] = 0; //合并完成就结束查找 break; } else if (array[row][t] == 0) continue; else//遇到即不为0也不相同 break; } } } } CreatRandData(1); } //向右移动 void Right() { //遍历行 for (int row = 0;row < 4;row++) { //遍历列 for (int column = 3;column >= 0;column--) { //在row行的最开始找空位置,找0 if (array[row][column] == 0)//如果row行。column列是0 { //从前面找一个不为0的数据拿到这个空位置 for (int t = column - 1;t >= 0;t--) { //找到一个不为0的位置 if (array[row][t] != 0) { //进行交换 array[row][column] = array[row][t]; array[row][t] = 0; //交换完成结束查找 break; } } } //如果不为0 if (array[row][column] != 0) { for (int t = column - 1;t >= 0;t--) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[row][t] == array[row][column]) { //数据合并 array[row][column] *= 2; array[row][t] = 0; //合并完成就结束查找 break; } else if (array[row][t] == 0) continue; else//遇到即不为0也不相同 break; } } } } CreatRandData(1); } //向上移动 void Up() { //遍历列 for (int column = 0;column < 4;column++) { //遍历行 for (int row = 0;row < 4;row++) { //找到一个空位置 if (array[row][column] == 0) { //从当前空位置往下查找,找一个不为0的数据 for (int t = row + 1;t < 4;t++) { //找到一个不为0 if (array[t][column] != 0) { //数据交换 array[row][column] = array[t][column]; array[t][column] = 0; //结束查找 break; } } } if (array[row][column] != 0) { //从后面找一个和当前相同的数据 for (int t = row + 1; t < 4;t++) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[t][column] == array[row][column]) { //数据合并 array[row][column] *= 2; array[t][column] = 0; //合并完成就结束查找 break; } else if (array[t][column] == 0) continue; else//遇到即不为0也不相同 break; } } } } CreatRandData(1); } //向下查找 void Down() { // 遍历列 for (int column = 0;column < 4;column++) { //遍历行 for (int row = 3;row >= 0;row--) { //找到一个空位置 if (array[row][column] == 0) { //从当前空位置往下查找,找一个不为0的数据 for (int t = row - 1;t >=0;t--) { //找到一个不为0 if (array[t][column] != 0) { //数据交换 array[row][column] = array[t][column]; array[t][column] = 0; //结束查找 break; } } } if (array[row][column] != 0) { //从后面找一个和当前相同的数据 for (int t = row - 1; t >= 0;t--) { //遇到相同的就合并,遇到0跳过.遇到不同的 if (array[t][column] == array[row][column]) { //数据合并 array[row][column] *= 2; array[t][column] = 0; //合并完成就结束查找 break; } else if (array[t][column] == 0) continue; else//遇到即不为0也不相同,就直接结束 break; } } } } CreatRandData(1); } //初始化游戏数据 void InitData() { //初始化格子矩阵 for (int row = 0;row < 4;row++) { for (int column = 0; column < 4;column++) { array[row][column] = 0; } } //生成两个随机数 CreatRandData(2); } //-----------------------界面--------------------------- int log(int n) { if (n <= 1) return 0; int count = 0; while (n>1) { count++; n /= 2; } return count; } void InitWindows() { //创建一个窗口 window=initgraph(450, 550); //生成游戏标题 settextcolor(WHITE);//确定颜色 settextstyle(60, 0,"黑体");//确定样式 outtextxy(170, 0, "2048"); } void updata() { //生成矩阵格子 for (int row = 0;row < 4;row++) { for (int column = 0;column < 4;column++) { int pos = log(array[row][column]); //加载图片 IMAGE img; loadimage(&img,picture[pos]); //显示图片 putimage(10 + (100 + 10) * column, 70+(100+10)*row, &img); } } } int GameOver() { if (IsFull() == 0 && CanMerge() == 0) { //清空屏幕 cleardevice(); //显示最后的状态 updata(); //生成游戏结束标题 settextcolor(WHITE);//确定颜色 settextstyle(80, 0, _T("黑体"));//确定样式 outtextxy(80, 200, _T("GameOver")); return 1; } return 0; } void Success() { for (int row = 0;row < 4;row++) { for (int column = 0;column < 4;column++) { if (array[row][column] == 2048) { //显示最后的状态 updata(); //生成游戏结束标题 settextcolor(WHITE);//确定颜色 settextstyle(80, 0, "黑体");//确定样式 outtextxy(170, 200, "You Win!"); } } } } int main() { //初始化数据 InitData(); //初始化窗口 InitWindows(); //游戏的主逻辑 while (IsWindow(window) && GameOver() == 0) { updata(); //接受用户键盘操作 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: continue; } Success(); } } } system("pause"); closegraph(); return 0; }