贪吃蛇项目GameStart部分:对游戏的初始化

         接上一篇文章介绍完需要使用到的WIN32API的相关知识,本篇文章让我们来开始使用他们来创建我们的贪吃蛇欢迎界面以及游戏所需要的地图。

准备工作:

         为了后面我们构建贪吃蛇游戏所需要的各项函数便于观察,同时便于我们的函数声明,在这里我们先创建三个文件,分别为1.Snake.h,2.Snake.c,3.test.c。它们分别用来:

         1.用于函数的声明,数值的定义,自定义类型的定义以及头文件的引用。

         2.函数功能的实现。

         3.对Snake.c中的函数进行引用最终实现贪吃蛇游戏。

         同时我们这里分装三个用于整合的函数GameStart(),GameRun(),GameEnd(),分别为游戏的初始化,游戏运行,游戏的善后工作部分,本篇我们来进行初始化工作

一,欢迎与介绍界面的打印

         如上图所示,这便是我们要打印的第一部分欢迎界面,下面是实现步骤:

1.1界面大小的设置及本地环境的切换

         首先我们要对界面大小进行设置,这里我们设置长度为100宽度为30(Windows控制台主机的长宽比约为2  :1)。

system("mode con cols=100 lines=30");

         紧接着我们要对C进行本地化处理,这里我们要介绍一个新函数setlocale,定义如下:
 

char* setlocale (int category, const char* locale);

         setlocale 函数用于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。 setlocale 的第⼀个参数可以是前面说明的类项中的一个,那么每次只会影响⼀个类项,如果第⼀个参 数是LC_ALL,就会影响所有的类项。 C标准给第⼆个参数仅定义了2种可能取值:"C"(正常模式)和 ""(本地模式)。

         setlocale 的返回值是⼀个字符串指针,表示已经设置好的格式。如果调⽤失败,则返回空指针 NULL 。 setlocale() 可以⽤来查询当前地区,这时第⼆个参数设为 NULL 就可以了。

 setlocale(LC_ALL, "");//切换到本地环境

         切换完本地环境后,我们需要进行宽字符的打印,这时候我们就需要用到wprintf函数进行打印宽字符:

wprintf(L"%lc\n", L'P');

         宽字符打印必须加上前缀 L ,否则C语言会把字面量当作窄字符类型处理。前缀 L 在单引号前 面,表示宽字符,宽字符的打印使⽤ wprintf ,对应 wprintf() 的占位符为 %lc ;在双引号前面,表示宽字符串,对应 wprintf() 的占位符为 %ls 。

1.2界面光标的隐藏及光标位置调整打印文字

         首先让我们用上节学的知识来隐藏光标,实现代码如下(注意这里false需要用到头文件stdbool.h):

	HANDLE houtput = NULL;
	houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo = { 25,false };
	SetConsoleCursorInfo(houtput, &CursorInfo);

         接着让我们把输出光标移到控制台的中间位置(这里我们直接创建一个函数以便于我们后面可以随时的移动光标):

void Set_Pos(short a,short b)
{
	HANDLE houtput = NULL;
	houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { a,b };
	SetConsoleCursorPosition(houtput, pos);
}

  1.3打印欢迎界面

void Welcom_Menu()
{
	Set_Pos(35, 10);
	wprintf(L"欢迎来到贪吃蛇小游戏");
	Set_Pos(35, 20);
	system("pause");
	system("cls");
}

1.4打印介绍界面

void Welcom_Menu()
{
	Set_Pos(35, 10);
	wprintf(L"欢迎来到贪吃蛇小游戏");
	Set_Pos(35, 20);
	system("pause");
	system("cls");
	Set_Pos(35, 10);
	wprintf(L"按 ↑ ↓ ← →键操控贪吃蛇移动\n");
	Set_Pos(35, 11);
	wprintf(L"按小键盘‘1’或‘2’键加速或减速\n");
	Set_Pos(35, 12);
	wprintf(L"Tips:加速吃食物有额外分数加成");
	Set_Pos(35, 20);
	system("pause");
	system("cls");
}

二,地图的创建

         本篇文章设置的棋盘27⾏,58列(行和列可以根据自己的情况修改),然后我们先定义墙体所需要用到的特殊字符‘□’:

#define WALL L'□'

接下来我们来打印地图,结果如下:

实现代码如下:

void GameMap()
{
	Set_Pos(0, 0);
	int i = 0;
	for (; i < 58; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	Set_Pos(0, 26);
	for (i = 0; i < 58; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	for (i = 1; i < 26; i++)
	{
		Set_Pos(0, i);
		wprintf(L"%lc", WALL);
	}
	for (i = 1; i < 26; i++)
	{
		Set_Pos(56, i);
		wprintf(L"%lc", WALL);
	}
}

三,贪吃蛇蛇身的初始化

3.1蛇身信息的信息维护

         在之后的代码实现过程中,如果我们的蛇身信息没有包装在一块,而是零散的分开处理,这样无疑会增大我们的工作量,所以我们自定义一个蛇的结构体,我的自定义结构如下:

typedef struct SnakeNode
{
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode, * pSnakeNode;
typedef struct Snake
{
	pSnakeNode _pSnake;//维护整条蛇的指针
	pSnakeNode _pFood;//维护⻝物的指针
	enum DIRECTION _Dir;//蛇头的⽅向,默认是向右
	enum GAME_STATUS _Status;//游戏状态
	int _Socre;//游戏当前获得分数
	int _foodWeight;//默认每个⻝物10分
	int _SleepTime;//每⾛⼀步休眠时间
}Snake, * pSnake;

         当然,这里只是最基础的需要维护的蛇身信息的整理,如果读者想要实现更多功能,可以以此为基础去增添结构体的成员。但我们仔细看图,发现状态和方向我们是可以列举出来的,所以我们这里使用枚举常量来整合它们:

enum DIRECTION
{
	UP = 1,
	DOWN,
	LEFT,
	RIGHT
};

enum GAME_STATUS
{
	OK,//正常运⾏
	KILL_BY_WALL,//撞墙
	KILL_BY_SELF,//咬到⾃⼰
	END_NOMAL//正常结束
};

         我们这个游戏中目前只有一条蛇,所以我们可以直接在最开始将维护蛇身的指针定义出来:
 

Snake snake = { 0 };
GameStart(&snake);

3.2蛇身信息的初始化

         由于控制台的长宽比近似为2 :1,所以我们使用宽字符打印蛇身,这里我们使用头插法以链表的形式初始化一个长度为5的蛇身,同时设置蛇的初始移动方向为右,一个食物的得分为10,总成绩初始化为0,起始状态设置为正常运行状态’OK‘:

void SnakeInit(pSnake ps)
{
	pSnakeNode cur = NULL;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		cur = (pSnakeNode)mallloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("SnakeInit:malloc;cur()");
			return;
		}
		cur->next = NULL;
		cur->x = POS_X + 2 * i;
		cur->y = POS_Y;
		if (ps->_pSnake == NULL)
		{
			ps->_pSnake = cur;
		}
		else
		{
			cur->next = ps->_pSnake;
			ps->_pSnake = cur;
		}
	}
	cur = ps->_pSnake;
	while (cur)
	{
		Set_Pos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}
	ps->_Dir = RIGHT;
	ps->_foodWeight = 10;
	ps->_SleepTime = 300;
	ps->_Socre = 0;
	ps->_Status = OK;
}

3.3食物位置的初始化

         我们都知道,在贪吃蛇的游戏过程中,蛇每吃掉一个食物自身长度就会增加一格,所以既然蛇身的维护我们使用链表,那食物信息的维护我们也使用malloc来开辟空间储存信息。

         除此之外,食物的信息也要在随机位置生成,不能生成在墙体外或墙体上,不能与蛇身位置重叠,同时需要确保x坐标为2的倍数(因为我们用的是宽字符打印的蛇身),以下为我的实现代码(记得在GameStart函数的最前面设置srand使他的随机值随着时间的变化而变化):

	int x = 0;
	int y = 0;
	again:
	do
	{
		x = rand()%53 + 2;
		y = rand()%24 + 1;
	} while (x % 2 != 0);
	pSnakeNode cur = ps->_pSnake;
	while (cur)
	{
		if (cur->x == x && cur->y == y)
		goto again;
		cur = cur->next;
	}
	pSnakeNode cur2 = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (cur2 == NULL)
	{
		perror("malloc():FoofInit:cur2:");
		return;
	}
	cur2->next = NULL;
	cur2->x = x;
	cur2->y = y;
	Set_Pos(x, y);
	wprintf(L"%lc", FOOD);
	ps->_pFood = cur2;
	cur2 = NULL;

         OK,到这里我们的初始化工作就完成了,接下来我们要让这条蛇动起来,我们下篇文章见。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker mysql cpu100% cpu打满排查 mysql cpu爆了 mysql cpu 100%问题排查

1. docker 启动了一个mysql 实例&#xff0c;近期忽然发现cpu100% 如下图所示 命令&#xff1a; top 2.进入容器内排查&#xff1a; docker exec mysql&#xff08;此处可以是docker ps -a 查找出来的image_id&#xff09; -it /bin/bash cd /var/log cat mysqld.log 容器内m…

移远通信发布两款Wi-Fi 6模组新品:率先采用亚马逊ACK SDK for Matter方案实现互联互通

6月26日 &#xff0c;在MWC上海展上&#xff0c;全球领先的物联网整体解决方案供应商移远通信联合亚马逊及上海博通现场宣布&#xff0c;推出支持亚马逊Alexa Connect Kit &#xff08;ACK&#xff09;SDK for Matter方案的MCU Wi-Fi 6模组FLM163D和FLM263D。 后续&#xff0c;…

完美解决ValueError: column index (256) not an int in range(256)的正确解决方法,亲测有效!!!

完美解决ValueError: column index (256) not an int in range(256)的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 亲测有效 完美解决ValueError: column index (256) not an int in range(256)的正确解决方法&#xff0c;亲测有效&#xff01;&…

JavaWeb——MySQL

目录 2. 数据库设计 3. 表的关系 4. 表关系的实现 5. 多表查询 5.1 内连接 &#xff08;1&#xff09;隐式内连接 &#xff08;2&#xff09;显式内连接 ​5.2 外连接 &#xff08;1&#xff09;左外连接 &#xff08;2&#xff09;右外连接 2. 数据库设计 数据库设…

「51媒体」政企活动媒体宣发如何做?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 政企活动媒体宣发是一个系统性的过程&#xff0c;需要明确…

World of Warcraft T2.5

World of Warcraft T2.5 猎人和术士套装需要的材料&#xff0c;好多啊&#xff0c;废墟和神殿打材料 猎人&#xff1a; 术士&#xff1a;

物联网安全:万物互联背景下的隐私保护与数据安全策略

在这个万物互联的时代&#xff0c;物联网&#xff08;IoT&#xff09;技术以其独特的魅力&#xff0c;将无数的设备、传感器和系统连接起来&#xff0c;构建了一个前所未有的智能世界。然而&#xff0c;随着物联网设备的激增和数据的爆炸式增长和流动&#xff0c;隐私泄露和数据…

Python | Leetcode Python题解之第188题买卖股票的最佳时机IV

题目&#xff1a; 题解&#xff1a; class Solution:def maxProfit(self, k: int, prices: List[int]) -> int:if not prices:return 0n len(prices)k min(k, n // 2)buy [0] * (k 1)sell [0] * (k 1)buy[0], sell[0] -prices[0], 0for i in range(1, k 1):buy[i] …

程序员职业发展指南,如何选择适合自己的就业方向?

随着科技的发展和数字化时代的到来&#xff0c;程序员是IT行业中的热门职业。尤其是近几年移动互联网的迅速发展&#xff0c;IT人才更是紧缺&#xff0c;越来越多的人加入程序员这个行列。 从事程序员工作&#xff0c;如何接项目呢&#xff1f;YesPMP是一个专注于互联网外包的平…

由监官要求下架docker hub镜像导致无法正常拉取镜像

问题&#xff1a;下载docker镜像超时 error pulling image configuration: download failed after attempts6: dial tcp 202.160.128.205:443: i/o timeout解决办法&#xff1a;配置daemon.json [rootbogon aihuidi]# cat /etc/docker/daemon.json {"registry-mirrors&qu…

AI绘图软件:设计师的创意加速器

在人工智能的浪潮中&#xff0c;AI绘图软件工具已成为设计师和创意工作者的得力助手&#xff0c;它们不仅加速了复杂绘图任务的完成&#xff0c;还激发了无限创意。本文将为您介绍几款AI绘图软件工具&#xff0c;它如何成为提升工作效率和创意灵感的关键。 1. StartAI&#xf…

深化人才服务改革,优化发展环境,推动创新与创业

在创新驱动的新时代背景下&#xff0c;浙江浦江县正以前所未有的力度&#xff0c;深化人才服务改革&#xff0c;优化人才发展环境。这不仅是一次对人才的深情呼唤&#xff0c;更是一场城市与人才的双向奔赴。在这里&#xff0c;人才的价值被充分认可&#xff0c;创新的力量得到…

企业信息化涉及哪些B端系统?本文给出15个,欢迎补充。

一、什么是企业信息化 企业信息化是指将信息技术应用于企业的各个业务领域&#xff0c;以提高企业的管理效率、业务流程优化和决策支持能力的过程。通过引入和应用信息技术&#xff0c;企业可以实现信息的高效传递和共享&#xff0c;提高工作效率&#xff0c;降低成本&#xf…

代码随想录第36天|动态规划

62. 不同路径 补充: 对二维数组的操作 dp[j][i] 表示到 j,i 有多少种路径递推公式: dp[j][i] dp[j - 1][i] dp[j][i - 1]初始化: dp[0][i] 和 dp[j][0] 都只有1种情况遍历顺序: 由于dp[j][i] 由 上和左的元素推导, 所以采用从左到右、从上到下的遍历顺序 class Solution {…

Linux Static calls机制

文章目录 前言一、简介二、Background: indirect calls, Spectre, and retpolines2.1 Indirect calls2.2 Spectre (v2)2.3 RetpolinesConsequences 2.4 Static callsHow it works 三、其他参考资料 前言 Linux内核5.10内核版本引入新特性&#xff1a;Static calls。 Static c…

Ubuntu20.04安装LibTorch并完成高斯溅射环境搭建

0. 简介 最近受到优刻得的使用邀请&#xff0c;正好解决了我在大模型和自动驾驶行业对GPU的使用需求。UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&#xff0c;并附带200G的免费…

Spring Boot中实现定时任务最常用的方法 @Scheduled 注解和 TaskScheduler 接口【包含详情代码】

Spring Boot中实现定时任务最常用的方法 Scheduled 注解和 TaskScheduler 接口【包含详情代码】 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中………

并发编程理论基础——面向对象与并发编程(十一)

简述 封装共享变量、识别共享变量间的约束条件、制定并发访问策略。 封装共享变量 将共享变量&#xff08;属性和方法&#xff09;作为对象属性封装在内部&#xff0c;对所有公共方法制定并发访问策略&#xff0c;也就是说外界对象只能通过目标对象提供的公共方法来间接访问这些…

《梦醒蝶飞:释放Excel函数与公式的力量》6.4 TODAY函数

第四节&#xff1a;6.4 TODAY函数 1&#xff09;TODAY函数概述 TODAY函数是Excel中一个非常有用的内置函数&#xff0c;它返回当前的日期。与NOW函数不同&#xff0c;TODAY函数仅返回日期部分&#xff0c;时间部分默认为午夜&#xff08;0:00&#xff09;。 2&#xff09;函…

使用 Python 注销、重启、关闭计算机

众所周知&#xff0c;Python 是一种功能强大的脚本语言。在本文中&#xff0c;将编写一个 Python 程序本控制计算机&#xff0c;实现计算机的注销、重启、关闭等操作。 Python 中的 os 模块&#xff0c;提供了一种与操作系统交互的方式&#xff0c;可以使用 os.system() 函数在…