【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)

这篇具有很好参考价值的文章主要介绍了【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

写在前面

游戏简介

Easyx 图形库

编写游戏

预编译代码

第一步:初始化棋盘

第二步:绘制棋盘

第三步:用户操作

第四步:封装函数

完整代码

效果展示


写在前面

大家好!本人是一个12岁六年级小学生,今年9月开始学习C++,曾经学过1年Python。

这是我的第一篇博客,决定分享一个游戏给大家!请多指教!


游戏简介

2048 这款游戏相信大家都听说过,编写代码分为以下几个步骤:

----------- 1. 初始化棋盘

----------- 2. 绘制棋盘

----------- 3. 用户操作


Easyx 图形库

官网网址:easyx.cn

官网上有详细的教程,而且可以自动匹配 vs 版本,我不说了。

顺便说一下,我用的是 vs2022。


编写游戏

预编译代码

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#define MAX_SIZE 4 // 格子数量
#define GRID_WIDTH 100 // 格子宽度
#define INTERVAL 15 // 格子距离
#define WIN_SIZE MAX_SIZE * GRID_WIDTH + 5 * INTERVAL // 窗口宽度

第一步:初始化棋盘

首先,我们要定义一个二维数组,来表示棋盘。

int canvas[MAX_SIZE][MAX_SIZE];

接下来,要在其中随机生成数字。

// 生成2或4
int Rand_2_4()
{
	if (rand() % 10 == 0) return 4;
	return 2;
}

 // 随机生成数字
void CreateNum()
{
	while (true)
	{
		int x = rand() % MAX_SIZE;
		int y = rand() % MAX_SIZE;
		if (canvas[x][y] == 0)
		{
			canvas[x][y] = Rand_2_4();
			break;
		}
	}
}

第二步:绘制棋盘

我们要遍历二维数组,在每一个位置绘制圆角矩形,并绘制数字、分数。

在此之前我们要先定义颜色,我用枚举类型来储存颜色,以及数组来储存位置。

// 枚举颜色
enum Color
{
	zero = RGB(205, 193, 180),
	twoto1 = RGB(238, 228, 218),
	twoto2 = RGB(237, 224, 200),
	twoto3 = RGB(242, 177, 121),
	twoto4 = RGB(245, 140, 99),
	twoto5 = RGB(246, 124, 95),
	twoto6 = RGB(246, 94, 59),
	twoto7 = RGB(242, 177, 121),
	twoto8 = RGB(237, 204, 97),
	twoto9 = RGB(255, 0, 128),
	twoto10 = RGB(145, 0, 72),
	twoto11 = RGB(242, 17, 158),
	bk = RGB(187, 173, 160),
};

Color arr[] = { zero, twoto1, twoto2, twoto3, twoto4, twoto5, twoto6, twoto7, twoto8, twoto9, twoto10, twoto11, bk };
int num[] = {0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
POINT pos[MAX_SIZE][MAX_SIZE];
int score = 0;

然后就是绘图。

// 绘制屏幕
void DrawScreen()
{
	// 背景颜色
	setbkcolor(Color::bk);
	cleardevice();
	for (int i = 0; i < MAX_SIZE; i++)
	{
		for (int j = 0; j < MAX_SIZE; j++)
		{
			for (int k = 0; k < 12; k++)
			{
				if (canvas[i][j] == num[k])
				{
					DWORD nowc = arr[k];
					setfillcolor(nowc);
					solidroundrect(pos[i][j].x, pos[i][j].y, pos[i][j].x + GRID_WIDTH, pos[i][j].y + GRID_WIDTH, 5, 5);
					if (num[k] != 0) // 显示数字
					{
						char number[5];
						sprintf_s(number, "%d", num[k]);
						setbkmode(TRANSPARENT);
						if (num[k] <= 4) settextcolor(RGB(119, 110, 101));
						else settextcolor(WHITE);
						settextstyle(50, 0, "黑体");
						int temp = (GRID_WIDTH - textwidth(number)) / 2;
						outtextxy(pos[i][j].x + temp, pos[i][j].y + 25, number);
					}
				}
			}
		}
	}
	settextcolor(WHITE);
	settextstyle(30, 0, "黑体");
	char text[20];
	sprintf_s(text, "Score: %d", score);
	outtextxy(INTERVAL, WIN_SIZE - 10, text);
}

效果预览:

【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)

然后是重头戏——用户操作。

第三步:用户操作

算法比较复杂(至少我真么觉得):

// 移动格子
// 向上移动
void MoveUp()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举列
	{
		int temp = 0; // 此列最上面
		for (int j = 1; j < MAX_SIZE; j++) // 枚举行
		{
			if (canvas[j][i] != 0) // 这个格子有数字
			{
				if (canvas[temp][i] == 0) // 最上面空着 -> 上去
				{
					canvas[temp][i] = canvas[j][i];
					canvas[j][i] = 0;
				}
				else if (canvas[temp][i] == canvas[j][i]) // 上面是同样数字 -> 合并
				{
					canvas[temp][i] += canvas[j][i];
					score += canvas[j][i];
					canvas[j][i] = 0;
					temp++;
				}
				else
				{
					canvas[temp + 1][i] = canvas[j][i]; // 上到前一个格子
					if (temp + 1 != j)
					{
						canvas[j][i] = 0;
					}
					temp++;
				}
			}
		}
	}
}

// 向下移动
void MoveDown()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举列
	{
		int temp = MAX_SIZE - 1; // 此列最下面
		for (int j = MAX_SIZE - 2; j >= 0; j--) // 枚举行
		{
			if (canvas[j][i] != 0) // 这个格子有数字
			{
				if (canvas[temp][i] == 0) // 最下面空着 -> 下去
				{
					canvas[temp][i] = canvas[j][i];
					canvas[j][i] = 0;
				}
				else if (canvas[temp][i] == canvas[j][i]) // 下面是同样数字 -> 合并
				{
					canvas[temp][i] += canvas[j][i];
					score += canvas[j][i];
					canvas[j][i] = 0;
					temp--;
				}
				else
				{
					canvas[temp - 1][i] = canvas[j][i]; // 下到前一个格子
					if (temp - 1 != j)
					{
						canvas[j][i] = 0;
					}
					temp--;
				}
			}
		}
	}
}

// 向右移动
void MoveRight()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举行
	{
		int temp = MAX_SIZE - 1; // 此行最右面
		for (int j = MAX_SIZE - 2; j >= 0; j--) // 枚举列
		{
			if (canvas[i][j] != 0) // 这个格子有数字
			{
				if (canvas[i][temp] == 0) // 最右面空着 -> 右去
				{
					canvas[i][temp] = canvas[i][j];
					canvas[i][j] = 0;
				}
				else if (canvas[i][temp] == canvas[i][j]) // 右面是同样数字 -> 合并
				{
					canvas[i][temp] += canvas[i][j];
					score += canvas[i][j];
					canvas[i][j] = 0;
					temp--;
				}
				else
				{
					canvas[i][temp - 1] = canvas[i][j]; // 到前一个格子
					if (temp - 1 != j)
					{
						canvas[i][j] = 0;
					}
					temp--;
				}
			}
		}
	}
}

// 向左移动
void MoveLeft()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举行
	{
		int temp = 0; // 此行最左面
		for (int j = 1; j < MAX_SIZE; j++) // 枚举列
		{
			if (canvas[i][j] != 0) // 这个格子有数字
			{
				if (canvas[i][temp] == 0) // 最左面空着 -> 左去
				{
					canvas[i][temp] = canvas[i][j];
					canvas[i][j] = 0;
				}
				else if (canvas[i][temp] == canvas[i][j]) // 左面是同样数字 -> 合并
				{
					canvas[i][temp] += canvas[i][j];
					score += canvas[i][j];
					canvas[i][j] = 0;
					temp++;
				}
				else
				{
					canvas[i][temp + 1] = canvas[i][j]; // 到前一个格子
					if (temp + 1 != j)
					{
						canvas[i][j] = 0;
					}
					temp++;
				}
			}
		}
	}
}

// 用户键盘输入
void GetKey()
{
	char input = _getch();
	switch (input)
	{
	case 72:
	case 'w':
	case 'W':
		MoveUp();
		CreateNum();
		break;
	case 80:
	case 's':
	case 'S':
		MoveDown();
		CreateNum();
		break;
	case 75:
	case 'a':
	case 'A':
		MoveLeft();
		CreateNum();
		break;
	case 77:
	case 'd':
	case 'D':
		MoveRight();
		CreateNum();
		break;
	case 'r':
	case 'R':
		Init();
		break;
	}
}

第四步:封装函数

就是把它们都放到 main 函数里去……

int main()
{
	start:
	// 初始化窗口
	initgraph(WIN_SIZE, WIN_SIZE + 30);
	Init();
	while (true)
	{
		DrawScreen();
		GetKey();
	}
	return 0;
}

完整代码

/*****************************
* 项目名称:2048小游戏
* 作者:轩
* 完成时间:2022.12.28
* 用时:2.5 小时
*****************************/

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#define MAX_SIZE 4 // 格子数量
#define GRID_WIDTH 100 // 格子宽度
#define INTERVAL 15 // 格子距离
#define WIN_SIZE MAX_SIZE * GRID_WIDTH + 5 * INTERVAL // 窗口宽度

// 枚举颜色
enum Color
{
	zero = RGB(205, 193, 180),
	twoto1 = RGB(238, 228, 218),
	twoto2 = RGB(237, 224, 200),
	twoto3 = RGB(242, 177, 121),
	twoto4 = RGB(245, 140, 99),
	twoto5 = RGB(246, 124, 95),
	twoto6 = RGB(246, 94, 59),
	twoto7 = RGB(242, 177, 121),
	twoto8 = RGB(237, 204, 97),
	twoto9 = RGB(255, 0, 128),
	twoto10 = RGB(145, 0, 72),
	twoto11 = RGB(242, 17, 158),
	bk = RGB(187, 173, 160),
};

Color arr[] = { zero, twoto1, twoto2, twoto3, twoto4, twoto5, twoto6, twoto7, twoto8, twoto9, twoto10, twoto11, bk };
int num[] = {0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
int canvas[MAX_SIZE][MAX_SIZE];
POINT pos[MAX_SIZE][MAX_SIZE];
int score = 0;

// 生成2或4
int Rand_2_4()
{
	if (rand() % 10 == 0) return 4;
	return 2;
}

 // 随机生成数字
void CreateNum()
{
	while (true)
	{
		int x = rand() % MAX_SIZE;
		int y = rand() % MAX_SIZE;
		if (canvas[x][y] == 0)
		{
			canvas[x][y] = Rand_2_4();
			break;
		}
	}
}

// 初始化格子位置 
void Init()
{
	score = 0;
	srand(GetTickCount());
	for (int i = 0; i < MAX_SIZE; i++)
	{
		for (int j = 0; j < MAX_SIZE; j++)
		{
			canvas[i][j] = 0;
		}
	}
	CreateNum();
	CreateNum();
	// 每个格子坐标
	for (int i = 0; i < MAX_SIZE; i++)
	{
		for (int j = 0; j < MAX_SIZE; j++) 
		{
			pos[i][j].x = j * GRID_WIDTH + (j + 1) * INTERVAL;
			pos[i][j].y = i * GRID_WIDTH + (i + 1) * INTERVAL;
		}
	}
}

// 绘制屏幕
void DrawScreen()
{
	// 背景颜色
	setbkcolor(Color::bk);
	cleardevice();
	for (int i = 0; i < MAX_SIZE; i++)
	{
		for (int j = 0; j < MAX_SIZE; j++)
		{
			for (int k = 0; k < 12; k++)
			{
				if (canvas[i][j] == num[k])
				{
					DWORD nowc = arr[k];
					setfillcolor(nowc);
					solidroundrect(pos[i][j].x, pos[i][j].y, pos[i][j].x + GRID_WIDTH, pos[i][j].y + GRID_WIDTH, 5, 5);
					if (num[k] != 0) // 显示数字
					{
						char number[5];
						sprintf_s(number, "%d", num[k]);
						setbkmode(TRANSPARENT);
						if (num[k] <= 4) settextcolor(RGB(119, 110, 101));
						else settextcolor(WHITE);
						settextstyle(50, 0, "黑体");
						int temp = (GRID_WIDTH - textwidth(number)) / 2;
						outtextxy(pos[i][j].x + temp, pos[i][j].y + 25, number);
					}
				}
			}
		}
	}
	settextcolor(WHITE);
	settextstyle(30, 0, "黑体");
	char text[20];
	sprintf_s(text, "Score: %d", score);
	outtextxy(INTERVAL, WIN_SIZE - 10, text);
}

// 移动格子
// 向上移动
void MoveUp()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举列
	{
		int temp = 0; // 此列最上面
		for (int j = 1; j < MAX_SIZE; j++) // 枚举行
		{
			if (canvas[j][i] != 0) // 这个格子有数字
			{
				if (canvas[temp][i] == 0) // 最上面空着 -> 上去
				{
					canvas[temp][i] = canvas[j][i];
					canvas[j][i] = 0;
				}
				else if (canvas[temp][i] == canvas[j][i]) // 上面是同样数字 -> 合并
				{
					canvas[temp][i] += canvas[j][i];
					score += canvas[j][i];
					canvas[j][i] = 0;
					temp++;
				}
				else
				{
					canvas[temp + 1][i] = canvas[j][i]; // 上到前一个格子
					if (temp + 1 != j)
					{
						canvas[j][i] = 0;
					}
					temp++;
				}
			}
		}
	}
}

// 向下移动
void MoveDown()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举列
	{
		int temp = MAX_SIZE - 1; // 此列最下面
		for (int j = MAX_SIZE - 2; j >= 0; j--) // 枚举行
		{
			if (canvas[j][i] != 0) // 这个格子有数字
			{
				if (canvas[temp][i] == 0) // 最下面空着 -> 下去
				{
					canvas[temp][i] = canvas[j][i];
					canvas[j][i] = 0;
				}
				else if (canvas[temp][i] == canvas[j][i]) // 下面是同样数字 -> 合并
				{
					canvas[temp][i] += canvas[j][i];
					score += canvas[j][i];
					canvas[j][i] = 0;
					temp--;
				}
				else
				{
					canvas[temp - 1][i] = canvas[j][i]; // 下到前一个格子
					if (temp - 1 != j)
					{
						canvas[j][i] = 0;
					}
					temp--;
				}
			}
		}
	}
}

// 向右移动
void MoveRight()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举行
	{
		int temp = MAX_SIZE - 1; // 此行最右面
		for (int j = MAX_SIZE - 2; j >= 0; j--) // 枚举列
		{
			if (canvas[i][j] != 0) // 这个格子有数字
			{
				if (canvas[i][temp] == 0) // 最右面空着 -> 右去
				{
					canvas[i][temp] = canvas[i][j];
					canvas[i][j] = 0;
				}
				else if (canvas[i][temp] == canvas[i][j]) // 右面是同样数字 -> 合并
				{
					canvas[i][temp] += canvas[i][j];
					score += canvas[i][j];
					canvas[i][j] = 0;
					temp--;
				}
				else
				{
					canvas[i][temp - 1] = canvas[i][j]; // 到前一个格子
					if (temp - 1 != j)
					{
						canvas[i][j] = 0;
					}
					temp--;
				}
			}
		}
	}
}

// 向左移动
void MoveLeft()
{
	for (int i = 0; i < MAX_SIZE; i++) // 枚举行
	{
		int temp = 0; // 此行最左面
		for (int j = 1; j < MAX_SIZE; j++) // 枚举列
		{
			if (canvas[i][j] != 0) // 这个格子有数字
			{
				if (canvas[i][temp] == 0) // 最左面空着 -> 左去
				{
					canvas[i][temp] = canvas[i][j];
					canvas[i][j] = 0;
				}
				else if (canvas[i][temp] == canvas[i][j]) // 左面是同样数字 -> 合并
				{
					canvas[i][temp] += canvas[i][j];
					score += canvas[i][j];
					canvas[i][j] = 0;
					temp++;
				}
				else
				{
					canvas[i][temp + 1] = canvas[i][j]; // 到前一个格子
					if (temp + 1 != j)
					{
						canvas[i][j] = 0;
					}
					temp++;
				}
			}
		}
	}
}

// 用户键盘输入
void GetKey()
{
	char input = _getch();
	switch (input)
	{
	case 72:
	case 'w':
	case 'W':
		MoveUp();
		CreateNum();
		break;
	case 80:
	case 's':
	case 'S':
		MoveDown();
		CreateNum();
		break;
	case 75:
	case 'a':
	case 'A':
		MoveLeft();
		CreateNum();
		break;
	case 77:
	case 'd':
	case 'D':
		MoveRight();
		CreateNum();
		break;
	case 'r':
	case 'R':
		Init();
		break;
	}
}

int main()
{
	start:
	// 初始化窗口
	initgraph(WIN_SIZE, WIN_SIZE + 30);
	Init();
	while (true)
	{
		DrawScreen();
		GetKey();
	}
	return 0;
}

效果展示

【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)

【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)

学业繁忙,精力有限,多多见谅!文章来源地址https://www.toymoban.com/news/detail-497591.html

到了这里,关于【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python小游戏 2048小游戏设计与实现

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 2048小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 今天我们用python实现

    2024年02月11日
    浏览(52)
  • python小游戏毕设 2048小游戏设计与实现 (源码)

    🔥 Hi,各位同学好呀,这里是L学长! 🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品 python小游戏毕设 2048小游戏设计与实现 (源码) 🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分) 难度系数:3分 工作量:3分 创新点:4分 项目获取: https://

    2024年02月12日
    浏览(42)
  • 2048小游戏成品源码

    2048小游戏,可以自选背景颜色,方框颜色,音乐播放。 还可以展示当前玩家的排名,动态排名,及历史玩家的排名。 前期需求: 使用pygame加载目录音乐。MP3文件: 看下运行后的效果图: =========参数设置: =========背景设置: =========方块设置: ==========源码分享:

    2024年02月16日
    浏览(41)
  • Qt--2048小游戏

    2048 1.功能 上下左右控制数字格子的移动 WASD 4*4 格子移动操作,加操作 开始游戏的按钮,重新游戏按钮 得分计算 判断游戏是否结束 2.源程序 代码如下(示例): MainWindow.h Main.cpp MainWindow.cpp 5.结果 以上是今天要讲的内容,练习了2048小游戏。

    2024年01月25日
    浏览(44)
  • c++制作小游戏2048

    完整代码来自于爱编程的柚子《【C语言/C++游戏项目】:2048小游戏,超详细教程教会你写这个小游戏。》 这个游戏用到了#include graphics.h,思路比较简单。 首先做出游戏页面,然后画出4*4的格子,利用map二维数组,依据数字{0,2,4,8,16,32,64,128,256,512,1024,2048}找到对应颜色在固定位

    2024年02月13日
    浏览(40)
  • Android期末项目2048小游戏

    Android期末项目2048小游戏。 2048属于益智类小游戏,它做到了娱乐性、趣味性、教育性相统一。益智类的游戏即是需要去开动大脑去思考从而获得游戏的胜利。简单的益智类游戏可以使玩家在娱乐中不断的开发大脑。这样一来就实现了在娱乐中学习。每次可以选择上下左右其中

    2024年02月06日
    浏览(54)
  • python快速实现2048小游戏

    《2048》是一款比较流行的数字游戏,最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。这款游戏是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。 操作指南: 每次可以选择上下左右其中一个方向去滑动,每滑动

    2024年02月11日
    浏览(39)
  • 2048小游戏 java版(代码+注释)

            一个纯纯小白,想写点什么,也想学习一下怎么在这里写东西,就简单的写个2048小游戏。写的不好,大佬就不用看了,希望和大家交流学习,有写的不好或有更好的建议也欢迎提出来。(需要用的可直接粘贴复制)(轻喷) 目录 游戏展示 讲解  代码        

    2024年02月09日
    浏览(46)
  • 【C语言】2048小游戏【附源码】

    欢迎来到英杰社区 https://bbs.csdn.net/topics/617804998         2048是一款数字益智类游戏,玩家需要使用键盘控制数字方块的移动,合并相同数字的方块,最终达到数字方块上出现“2048”的目标。         每次移动操作,所有数字方块会朝着指定方向同时滑动,并在靠近边

    2024年04月15日
    浏览(36)
  • 用Python做一个2048小游戏

    2048的逻辑无非是操作 4 × 4 4times4 4 × 4 的方格,每个方格中有一个数,这些数可以移动,如果两个相同的数字在移动时相撞了,就可以彼此合并。 而这个 4 × 4 4times4 4 × 4 的方格,无非是一个矩阵。只需设计好移动逻辑,再用PyGame将这个方格表现出来就算大功告成。 2048只有

    2024年01月17日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包