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

news2024/11/19 7:25:56

         接上一篇文章介绍完需要使用到的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,到这里我们的初始化工作就完成了,接下来我们要让这条蛇动起来,我们下篇文章见。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

反射及动态代理

反射 定义&#xff1a; 反射允许对封装类的字段&#xff0c;方法和构造 函数的信息进行编程访问 图来自黑马程序员 获取class对象的三种方式&#xff1a; 1&#xff09;Class.forName("全类名") 2&#xff09;类名.class 3) 对象.getClass() 图来自黑马程序员 pac…

使用Tailwindcss之后,vxe-table表头排序箭头高亮消失的问题解决

环境 vue2.7.8 vxe-table3.5.9 tailwindcss/postcss7-compat2.2.17 postcss7.0.39 autoprefixer9.8.8 问题 vxe-table 表格表头 th 的排序箭头在开启正序或逆序排序时&#xff0c;会显示蓝色高亮来提示用户表格数据处在排序情况下。在项目开启运行了tailwindcss之后&#xff0…

代码随想录算法训练营day31|134.加油站、135. 分发糖果、406.根据身高重建队列

134.加油站 如下图所示&#xff1a; 当索引一道2的时候&#xff0c;剩余油量的总量13-6 < 0&#xff0c;这个时候说明以索引0为起点不合适&#xff0c;将起点更新为索引3. 两点证明&#xff1a; 1.如果我们从蓝色段中间选一个点开始&#xff0c;是不是最后sumGas就不小于0…

经典老动画电影大全,老动画片大全集全部百度网盘,资源下载百度云

当今社会越来越重视学前教育了&#xff0c;今儿童启蒙的教育也越来越受人们的关注和重视。为了满足社会对未来人才的需要&#xff0c;学前教育成为当今教育领域重要角色的一环。当今动画篇是主流&#xff0c;内容精彩纷呈&#xff0c;越来越受到儿童的喜爱。 儿童的语言敏感期&…

【PL理论深化】(7) Ocaml 语言:静态类型语言 | 自动类型推断 | 多态类型和多态函数 | let-多态类型系统

&#x1f4ac; 写在前面&#xff1a;OCaml 是一种拥有静态类型系统的语言&#xff0c;本章我们就要探讨静态类型系统。 目录 0x00 静态类型系统 0x01 自动类型推断&#xff08;automatic type inference&#xff09; 0x02 多态类型和多态函数 0x03 let-多态类型系统&#…

php,python AES/CBC/PKCS7Padding加密解密 base64/hex编码

1. python版本 import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpadclass AESUtilCBC:def __init__(self, key, iv):self.key key.encode(utf-8)self.iv iv.encode(utf-8)self.pad_length AES.block_sizedef encrypt(self, data):try…

最佳实践 | HelpLook通过PartnerShare实现低成本的市场拓展

在如今许多行业市场竞争非常激烈&#xff0c;扩大品牌影响力、提升产品竞争力成为企业亟待攻克的难题之一。为此&#xff0c;HelpLook AI知识库对接了PartnerShare联盟系统&#xff0c;为SaaS产品如何做好全民分销带来了全新的解决思路。 PartnerShare凭借成熟的推广体系为Hel…

一张图了解KFS

供稿&#xff1a;产品研发中心、战略市场部 编辑&#xff1a;薇薇 审核&#xff1a;日尧

源站静态文件更新后,CDN会自动刷新吗

源站静态文件更新后&#xff0c;CDN不会自动刷新缓存&#xff0c;而是在缓存时间过期后&#xff0c;才会经由用户触发回源获取最新文件。如希望在缓存过期时间之前&#xff0c;实现CDN节点与源站静态文件同步更新&#xff0c;则需要通过CDN控制台-【刷新预取】菜单&#xff0c;…

前端JS必用工具【js-tool-big-box】学习,数值型数组的正向排序和倒向排序

这一小节&#xff0c;我们说一下前端 js-tool-big-box 这个工具库&#xff0c;添加的数值型数组的正向排序和倒向排序。 以前呢&#xff0c;我们的数组需要排序的时候&#xff0c;都是在项目的utils目录里&#xff0c;写一段公共方法&#xff0c;弄个冒泡排序啦&#xff0c;弄…

量化交易面临的难题

量化交易面临的难题 1、监管机构对于算法交易、量化交易的监管越来越严格3、回测场景于实盘交易场景的不匹配性4、策略并非100%有效&#xff0c;并非100%的收益5、股票、基本面、市场新闻之间的关系时刻在变化并且难以捉摸6、很难使用一套通用的交易规则去匹配所有的股票/市场/…

React Native V0.74 — 稳定版已发布

嗨,React Native开发者们, React Native 世界中令人兴奋的消息是,V0.74刚刚在几天前发布,有超过 1600 次提交。亮点如下: Yoga 3.0New Architecture: Bridgeless by DefaultNew Architecture: Batched onLayout UpdatesYarn 3 for New Projects让我们深入了解每一个新亮点…

OElove 婚恋系统 v10.2升级真是及时,你们是不是UI团队换了?不得不说这次UI是真美!当然功能也升级了大大的赞!

怎么说呢&#xff0c;成为OE的老用户已经有五年了&#xff0c;当时买的初衷就是在本地做一个响当当的门户但是因为疫情搁浅了。。。实在是入不敷出&#xff01;转行的这几年又看好了婚恋这个行业于是打算冲头再来&#xff0c;我记得我当时还是8.5&#xff0c;功能比较强大就是太…

CppTest单元测试框架(更新)

目录 1 背景2 设计3 实现4 使用4.1 主函数4.2 使用方法 1 背景 前面文章单元测试之CppTest测试框架中讲述利用宏ADD_SUITE将测试用例自动增加到测试框架中。但在使用中发现一个问题&#xff0c;就是通过宏ADD_SUITE增加多个测试Suite时&#xff0c;每次运行时都是所有测试Suit…

内附下载方式 | 移远通信《5G RedCap技术发展及应用白皮书》重磅发布

6月25日&#xff0c;在2024 MWC上海前夕&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;正式发布其《5G RedCap技术发展及应用白皮书》。 该白皮书对RedCap的技术特点、市场趋势及应用场景进行了全面分析&#xff0c;基于5G技术的发展和演进&#xff…

Kafka入门-基础概念及参数

一、Kafka术语 Kafka属于分布式的消息引擎系统&#xff0c;它的主要功能是提供一套完备的消息发布与订阅解决方案。可以为每个业务、每个应用甚至是每类数据都创建专属的主题。 Kafka的服务器端由被称为Broker的服务进程构成&#xff0c;即一个Kafka集群由多个Broker组成&#…

一款开源、高颜值的AI物联网数据平台

介绍 AIOT人工智能物联网平台是一站式物联网开发基础平台&#xff0c;帮助企业快速实现数字化、精细化数据管理。核心系统为&#xff1a;物联网平台 数据中台&#xff08;数据底座&#xff09; AI。 同时支持文生图、语音合成等。大模型支持陆续也会慢慢开发。 物联系统介绍…

STM32存储左右互搏 模拟U盘桥接QSPI总线FATS读写FLASH W25QXX

STM32存储左右互搏 模拟U盘桥接QSPI总线FATS读写FLASH W25QXX STM32的USB接口可以模拟成为U盘&#xff0c;通过FATS文件系统对连接的存储单元进行U盘方式的读写。 这里介绍STM32CUBEIDE开发平台HAL库模拟U盘桥接Quad SPI总线FATS读写W25Q各型号FLASH的例程。 FLASH是常用的一种…

【学习】科大睿智解读ITSS通过后仍需关注和改进IT服务的原因

为了确保IT服务的质量和效率&#xff0c;很多企业拿到ITSS资质证书后&#xff0c;仍然需要持续关注和改进IT服务&#xff0c;科大睿智总结主要原因有以下几点&#xff1a; 1、随着企业发展业务和市场行情的变化&#xff0c;可能涉及到运维服务中新的业务流程、技术需求或者用户…

[深度学习] 门控循环单元GRU

门控循环单元&#xff08;Gated Recurrent Unit, GRU&#xff09;是一种用于处理序列数据的递归神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;变体&#xff0c;它通过引入门控机制来解决传统RNN在处理长序列时的梯度消失问题。GRU与长短期记忆网络&#xff0…