实战项目:贪吃蛇游戏的实现(上)

news2024/11/13 9:14:25

前言

Hello, 今天我们来一起完成一个实战项目:贪吃蛇

相信大家都不会对这个游戏感到陌生,贪吃蛇游戏是久负盛名的游戏,他和俄罗斯方块,扫雷游戏等游戏位列世界经典游戏之列。这次我们旨在通过实战项目贪吃蛇的实现,从设计到代码的实现来提升我们的编程能力和逻辑运算能力!

游戏效果展示:

贪吃蛇游戏效果演示

1.项目目标:

  • 使用C语言在 Windows环境下的控制台模拟实现经典小游戏贪吃蛇
  • 实现的基本功能:
  • 贪吃蛇地图的绘制
  • 蛇吃食物的功能(上、下、左、右方向的控制键来控制蛇的动作)
  • 蛇撞到墙后立即死亡
  • 蛇撞到自身立即死亡
  • 计算得分
  • 蛇身发的加速和减速
  • 暂停游戏

2.技术要点

C语言函数、枚举、动态内存管理、预处理指令、初步解接触数据结构中的链表。

3.Windows系统工具函数

 3.1Win32API介绍

本次实现贪吃蛇会使用一些Win32API的知识,我们想要顺利的完成任务就要去认真掌握其中的一些函数。

Windows这个多作业系统除了协调应用程序的执行、分配管理、资源管理之外,他还是一个好大吃的服务中心,调用这个服务中心的服务(每一种服务就是一种函数)。可以帮助我们达到开启视窗、描绘图像、使用周边设备等目的,由于这些函数的服务对象是一些应用程序(Application),所以百年称之为Applicatino Programming Interface,简称API函数。WIN32API也是Microsoft Windows32w位平台的应用程序编程接口。

3.2控制台程序

平常我们运行起来的黑框程序其实就是控制台程序。

我们可以使用cmd命令来设置控制台窗口的长和宽:设置控制台窗口的大小,30行,100列

mode con cols=100 lines=30

也可以通过命令设置窗口的名字:

title 贪吃蛇

 

这些能在控制台窗口执行的命令,也可以调用C语言函数system来执行。例如:

#include<stdio.h>
int main()
{
	//设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列
		system("mode con cols=100 lines=30");
	//设置cmd窗⼝名称
		system("title 贪吃蛇");
		getchar();
	return 0;
}

 3.3控制平台上的坐标COORD

COORD是WindowsAPI上定义的一个结构体·,表示一个字符在控制台屏幕上的坐标 

typedef struct _COORD {
SHORT X;
SHORT Y;
} COORD, *PCOORD;

給坐标赋值:

COORD pos = { 10, 15 };

3.4GetStdHandle

GetStdHandle是一个WindowsAPI函数。它用于从一个特定的标准设备(标准输入、标准输出或者是标准错误)中取得一个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。

HANDLE GetStdHandle(DWORD nStdHandle);

实例:
 

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

3.5GetConsoleCursorInfo

 检索有关指定的控制台的屏幕缓冲区堆的光标大小和课件行的信息

BOOL WINAPI GetConsoleCursorInfo(
HANDLE hConsoleOutput,
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
)

实例:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

3.5.1 CONSOLE_CURSOR_INFO

这个结构体,包含控制台光标信息

typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
  •  deSize,有光标填充的字符单元格的百分比。此值介于1到100之间。光标外观会随着变化,范围从完全填充单元格到单元底部的水平线条。
  • bVisible,游标的可见性。如果光标可见则此成员为TRUE。
CursorInfo.bVisible = false; //隐藏控制台光标

 3.6SetConsoleCursorInfo

设置指定的控制台屏幕缓冲区光标的大小和可见性。

BOOL WINAPI SetConsoleCursorInfo(
HANDLE hConsoleOutput,
const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

实例:

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

3.7 SetConsoleCursorPosition

设置制定控制台屏幕缓冲区中光标位置,我们将想要的设置的光标坐标信息放在COOR来行的pos中,调用SetConsoleCursorPosition的函数将光标的位置设定到指定的位置。

BOOL WINAPI SetConsoleCursorPosition(
HANDLE hConsoleOutput,
COORD pos
)

实例:

COORD pos = { 10, 5};
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//设置标准输出上光标的位置为pos
SetConsoleCursorPosition(hOutput, pos);

SetPos:封装一个光标位置的函数

//设置光标的坐标
void SetPos(short x, short y)
{
COORD pos = { x, y };
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//设置标准输出上光标的位置为pos
SetConsoleCursorPosition(hOutput, pos);
}

3.8GetAsyncKeyState

获取按键情况,这个函数的原型如下:

 

SHORT GetAsyncKeyState(
int vKey
);

将键盘上的每个按键的虚拟键值传递给函数,函数通过返回值来分辨案件的状态。

GetAsyncKeyState的返回值是short类型的,在上一次调用GetAsyncKeyState函数后,如果返回的是16位的short数据,最高位是1,说明按键的状态是按下,如果最高位是0,则按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。

如果我们要判断一个案件是否被按过,可以检测GetAsyncKeyState返回值的最低位是否为1.

#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

4.贪吃蛇游戏的设计与分析

4.1地图 

 我们最终想要的贪吃蛇大纲可能就是这个样子,按我们要如何进行的图的布置呢?

 

这里我们不得不在讲一下控制窗台的知识了,如果想要在控制台的窗口指定位置输出信息,我们得知道该位置的坐标,所以首先介绍一下控制窗口的坐标知识。

控制窗口的坐标只是如下所示,横向的是x轴,从左向右依次增长,纵向是Y轴,从上到下一次增长。

 

在游戏地图上,我们打印墙体使用宽字符:□ ;打印蛇身我们使用:●;打印食物‘使用宽字符:★’,普通的字符只占一个字节,这类宽字符是占用2个字节。

这里简单的讲一下C语言国际化特性相关的知识,过去C语言并不适合非英语的国家(地区)使用。

C语言最初假定假定字符都是自己的。但是这些假定并不是在世界所有的地方都适用。

后来C鱼啊一年适应到了国际化,C语言标准中不断加入国际化的支持,比如:加入和宽字符的类型wchar_t和宽字符的输入和输出函数,加入<locale.h>头文件,其中提供了允许程序员针对特定地区(通常是国家或者说特定语言的地理地区)调整程序行为的函数。

4.1.1<locale.h>本地化

<locale.h>提供的函数用于控制C语言标准库中对于不同地区会产生的不一样行为的部分·。
在标准可以中,依赖地区的部分有以下几项:

  • 数字量的格式
  • 货币量的格式
  • 字符集
  • 日期和时间的表示形式

 4.1.2类项

通过修改地区,程序可以改变它的行为来适应世界的不同区域。单区域的改变可能影响库的许多部分其中一部分可能使我们不希望改变的。所以C语言针对不同的类项进行修改,下面的一个宏,指定一个类项:

• LC_COLLATE

• LC_CTYPE

• LC_MONETARY

setlocale(LC_ALL, "C");

• LC_NUMERIC

• LC_TIME

• LC_ALL - 针对所有类项修改

4.1.3 setlocale函数

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

setlocale函数用于修改当前的地区,可以针对一个类想项修改,也可以针对所有的类项修改。

setlocale的·第一个参数可以是前面说明的类项中的一个,那么每次只会影响一个类项,如果第一个·参数是LC_ALL,就会影响所有的类项。

C标准给定的第二个参数仅定义了两种可能得取值:“c” 和“ ”。

在任意程序运行是,都会隐藏式执行调用:

setlocale(LC_ALL, "C");

当地区设置为"c"时,库函数按正常的方式执行,小数点是一个点。

的那个吃呢工序运行起来之后想要改变地区,就只能显示调用setlocale函数。用“”作为第二个参数,调用setlocale函数就可以切回到本地模式,这中模式下程序 会适应本地环境。比如:切换到我们本地模式后就支持宽字符(汉字的输出)等。

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

4.1.4宽字符的打印

那如果想在屏幕上打印宽字符,怎么打印呢?

 

#include <stdio.h>
#include<locale.h>
int main() {
setlocale(LC_ALL, ""
wchar_t ch1 = L'●';
wchar_t ch2 = L'⽐';
wchar_t ch3 = L'特';
wchar_t ch4 = L'★';
printf("%c%c\n", 'a', 'b');
wprintf(L"%c\n", ch1);
wprintf(L"%c\n", ch2);
wprintf(L"%c\n", ch3);
wprintf(L"%c\n", ch4);
return 0;
}

从输出来看,我们发现一个普通的字符占一个字符的位置但是打印一个汉字字符,占用2个字符的位置,那么我们如果在贪吃蛇中使用宽字符,就得憨憨处理地图上的坐标计算。

1个坐标1个正常字符

2个坐标可以存放一个宽字符 

 4.1.5地图坐标

我们假设实现一个棋盘27行,58列的棋盘(行和列可以根据自己的爱好设计修改),再围绕地图画出墙如下:
 

4.2蛇身和食物

初始化状态,假设蛇的长度为5,蛇身上的·节点是●,在固定的一个坐标处,比如(24,5)处开始出现蛇,连续5个节点。注意:蛇的每个节点的x坐标必须是2的倍数,否则可能出现蛇的一个节点有一半出现在墙体中。另外一半在墙体外的现象,坐标不好对齐。

关于食物,就是在墙体内随机生成一个坐标(X坐标必须是2的倍数),坐标不能和蛇的身体重合,让后打印★ 

 

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

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

相关文章

opencv2.4.9源码在Windows下VS2019的编译

1、opencv2.4.9解压后根目录下建立build文件夹 2、采用CMake-gui进行编译 记得把上面两个√去掉&#xff0c;用老版本的opencv再用cuda完全没有意义&#xff0c;我们只是验证算法用。 把这个√也去掉。 重新Configure和Generate&#xff0c;如下图&#xff1a; 然后&#xff1…

大模型汇总:文心一言大模型、腾讯混元大模型、通义千问大模型、字节豆包大模型、智普清言大模型、KIMI 大模型、紫东太初大模型、讯飞星火大模型

文心一言大模型 作为百度自主研发的大型语言模型&#xff0c;具有显著的特点、广泛的应用场景以及独特的优势。以下是对文心一言特点、应用、优势的详细介绍&#xff1a; 特点&#xff1a;知识增强&#xff1a; 文心一言通过持续学习技术&#xff0c;不断吸收海量数据和知识…

Postman接口测试基础教程--2024最新版

文章目录 一、Postman 简介二、Postman 功能概览三、Postman 安装说明1. 下载与安装2. 界面导航说明3. 发送第一个请求 四、Postman 基础功能1. 常见类型的接口请求查询参数的接口请求表单类型的接口请求上传文件的表单请求JSON 类型的接口请求 2. 接口响应数据解析3. 接口管理…

基于GA遗传算法的拱桥静载试验车辆最优布载matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于GA遗传算法的拱桥静载试验车辆最优布载matlab仿真。主要是为了实现桥梁静载试验自动化布载&#xff08;确定车辆位置使得满足加载效率ηq的要求&#xff0c;0…

初级python代码编程学习---- 简单记事本小程序

简单记事本小程序 提供一个基于Python的简单记事本小程序示例。这个小程序将允许用户添加、查看和删除记事条。 # Simple Note Pad Mini-Application # 记事本数据结构 notes [] def add_note(note): """添加一条新的记事条""" …

可重用性功能 在 Jira 中扩展测试管理

在当今动态的软件开发环境中&#xff0c;高效且可扩展的测试管理对于确保软件产品的质量和可靠性至关重要。Jira 是一种流行的项目管理工具&#xff0c;它通过与Zephyr Scale的集成为测试管理提供了强大的解决方案。 在这篇博文中&#xff0c;我们将探讨可重用性功能在测试管理…

信创教育:培养未来科技创新的生力军

随着全球数字化转型的加速&#xff0c;信息技术应用创新&#xff08;简称“信创”&#xff09;产业作为推动国家信息技术自主可控和产业升级的关键领域&#xff0c;正迎来前所未有的发展机遇。信创教育&#xff0c;作为培养未来科技创新生力军的重要阵地&#xff0c;其重要性和…

智慧卫生间环境传感器有哪些?智慧卫生间的特点@卓振思众

随着科技的进步和人们对生活品质的要求不断提高&#xff0c;智慧卫生间作为现代化设施的代表&#xff0c;越来越受到关注。智慧卫生间不仅仅是在外观设计上做文章&#xff0c;更在于其背后强大的智能系统&#xff0c;特别是环境传感器的应用&#xff0c;让厕所的管理和使用变得…

第36课 Scratch入门篇:画正多边形

画正多边形 故事背景: 绘制一个正多边形! 程序原理: 我们前面学习了绘制三角形(3 条边,旋转 120 度),正方形(4 条边,旋转 90 度),我们可以归纳一个公式,针对正多边形,有n条边,那么旋转的角度就是 360/n。通过程序实现就是 开始编程 1、隐藏预设的猫咪角色,…

【C#】 接口 继承

简介 继承是面向对象编程的核心特性之一&#xff0c;它允许我们创建一个类&#xff08;称为子类&#xff09;来继承另一个类&#xff08;称为基类&#xff09;的属性和方法。 作用 这样&#xff0c;我们可以重用代码&#xff0c;减少重复&#xff0c;并使我们的代码更加模块…

无限金币版《废土世界》安卓手机游戏下载,游戏分享

《废土世界》&#xff08;JunkWorld&#xff09;是由IRONHIDE游戏工作室开发的一款塔防游戏&#xff0c;它将玩家带入一个荒凉、贫瘠的后末日世界&#xff0c;玩家需要带领一队拾荒者穿越沙漠和放射性沼泽&#xff0c;进行生存战斗。游戏以其战略深度和丰富的塔防元素为特色&am…

RabbitMQ高级特性 - 消息和队列TTL、死信队列

文章目录 消息和队列TTL概述实战开发 死信队列概述实战开发 消息和队列TTL 概述 a&#xff09;TTL&#xff08;Time To Live 过期时间&#xff09;&#xff0c;RabbitMQ 可以对消息和队列设置 TTL. 当消息到达存活时间之后&#xff0c;还没有被消费&#xff0c;就会被自动清除…

fmql之Linux移植

先了解以下linux移植的大致流程&#xff0c;以及需要的资料、软件等。 《领航者ZYNQ之嵌入式Linux开发指南_V2.0》第十八章 Linux内核移植 (amobbs.com 阿莫电子技术论坛) 前言 复旦微&#xff08;他人经验&#xff09; 复旦微fmql的操作指南来了&#xff1a; 复旦微 FMQL L…

算法:排序(前言)

所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。排序算法&#xff0c;就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视&#xff0c;尤其是在大量数据的处理方面。一个优秀的…

还在担心Android功能不会用吗?Intro Showcase View助你快速实现功能引导

还在担心Android功能不会用吗?Intro Showcase View助你快速实现功能引导 1. 引言 在现代应用开发中,如何有效引导用户快速上手并掌握应用的核心功能,是提升用户体验的重要一环。功能引导不仅帮助用户理解复杂功能,还能提高用户留存率,减少因操作复杂度带来的用户流失。随…

将Excel数据导入到SQL Server数据库

1.找到SQLServer导入导出工具&#xff0c;有32位和64位 2.打开后点击 下一步 3.选择数据源、Excel文件&#xff0c;自动匹配Excel的版本&#xff0c;根据实际情况&#xff0c;勾选首行是否是列名 4.选择目标&#xff0c;如图 5.点击属性&#xff0c;设置要导入的目标数据库…

zookeeper+kafka群集

一 :消息队列 1:什么是消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。 消息队列(Message Queue)是一种应用间的通信方式&#xff0c;消息发送后可以立即返回由消息…

【Datawhale X 魔搭 】AI夏令营第四期大模型方向,Task2:头脑风暴会,巧灵脑筋急转弯(持续更新)

队伍名称&#xff1a;巧灵脑筋急转弯 队伍技术栈&#xff1a;python&#xff0c;LLM&#xff0c;RAG&#xff0c;大模型&#xff0c;nlp&#xff0c;Gradio&#xff0c;Vue&#xff0c;java 队友&#xff1a;知唐&#xff08;队长&#xff09;&#xff0c;我真的敲不动…

RCE绕过技巧

目录 EVAL长度限制突破技巧 1.使用反引号 2.file_put_contents写入文件 3.php5.6变长参数usort回调后门 命令长度限制突破技巧 1.拼接文件名 无字母数字的webshell命令执行 1.取反码 2.上传临时文件 EVAL长度限制突破技巧 分析代码&#xff1a;首先传递一个param参数&…

优思学院|日本制造的质量真的那么好吗?回顾日本的质量发展

时代不停改变&#xff0c;时移势易&#xff0c;没有事情是永恒的。 事实上&#xff0c;在20世纪40年代&#xff0c;日本产品常被认为是廉价、劣质的制品&#xff0c;并不如大家所想像的那么好。日本的工业领导者意识到了这个问题&#xff0c;决心生产出创新的高质量产品。 一…