实战项目:贪吃蛇游戏的实现(上)
前言
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的倍数),坐标不能和蛇的身体重合,让后打印★
相关文章:
实战项目:贪吃蛇游戏的实现(上)
前言 Hello, 今天我们来一起完成一个实战项目:贪吃蛇。 相信大家都不会对这个游戏感到陌生,贪吃蛇游戏是久负盛名的游戏,他和俄罗斯方块,扫雷游戏等游戏位列世界经典游戏之列。这次我们旨在通过实战项目贪吃蛇的实现,…...
SHT30温湿度传感器全解析——概况,性能,MCU连接,样例代码
常见温湿度传感器测量范围:(价格仅供参考,具体性能要看折线图) 型号DHT11DHT20AHT10AHT20AHT30SHT20价格¥ 2.49¥3.04¥ 1.9¥1.4¥ 1.3¥5.5温度测量范围20—90%RH0—100%RH0—100%RH0—…...
SQL server 同环比计算模板
1、计算 月 年 季度的环比和同比 计算公式如下: 环比增长率 (本期数 - 上期数) / |上期数| 100% 同比增长率 (本期数 - 同期数) / |同期数| * 100% --- dbo.ads_erp_finance_gross_profit_actual_invoice_yoy_m…...
python发送外部请求
在Python中,服务器发送外部请求是一个常见的操作,尤其是在需要集成不同服务或API时。有多种库可以帮助你完成这项任务,但最流行和广泛使用的库之一是requests。以下是如何使用requests库在Python服务器中发送外部请求的基本步骤: …...
c++并发编程面试题
1. C中lock_guard和unique_lock的区别? 在C中,lock_guard和unique_lock都是用于管理互斥锁的类,它们提供了一种 RAII(Resource Acquisition Is Initialization)机制来确保锁在作用域结束时自动释放。尽管它们的目的相…...
K8S上安装LongHorn(分布式块存储) --use
要在 Kubernetes上安装 LongHorn,您可以按照以下步骤进行操作: 准备工作 参考 官网教程将LongHorn只部署在k8s-worker5节点上。https://github.com/longhorn/longhorn 安装要求 Each node in the Kubernetes cluster where Longhorn is installed must f…...
2024年前端技术发展趋势分析
2024年的前端技术发展趋势继续受到快速变化的技术环境和不断增长的用户期望的影响。以下是2024年前端技术发展的几个关键趋势: 1. Web 组件和自定义元素 Web 组件技术(包括 Shadow DOM、HTML Templates 和 Custom Elements)正在成为构建可重…...
spring boot 笔记大杂烩
一,springboot项目创建 springboot创建时idea会打开start.spring.io失败报错 可以手动打开这个页面,然后选择maven项目,然后修改group和name名然后添加依赖web,然后生成项目包,解压缩后用idea打开就能用了 运行后报错…...
如何在香港云服务器上优化网站性能?
在香港云服务器上优化网站性能可以通过以下几种方式进行,确保用户从全球各地访问时获得快速、稳定的体验: 1. 使用内容分发网络 (CDN) 优势:CDN可以将静态内容(如图像、视频、CSS、JavaScript文件)缓存到全球多个节点…...
STM32低功耗与备用备份区域
STM的备份备用区域其实就是两个区块:BKP和RTC。低功耗则其实是STM32四种模式中的三种耗能很低的模式。 目录 一:备用区域 1.BKP 2.RTC 二:低功耗模式 1.睡眠模式: 2.停机模式: 3.待机模式: 一&…...
武汉某汽配公司携手三品软件 共绘PLM项目新蓝图
近日,三品软件与武汉某汽配公司达成战略合作,双方将共同启动PLM项目,以助力该公司在汽车制造业的研发管理领域实现全面升级。 客户简介 该公司自2008年成立以来,一直专注于为汽车制造业提供自动化输送系统、车辆装配的合装技术和…...
uniapp多图上传uni.chooseImage上传照片uni.uploadFile,默认上传9张图
uniapp多图上传uni.chooseImage上传照片uni.uploadFile 代码示例: /**上传照片 多图*/getImage() {uni.chooseImage({count: 9, //默认9sizeType: [original, compressed], //可以指定是原图还是压缩图,默认二者都有sourceType: [album], //从相册选择/…...
MySQL——内置函数
时间函数 select * from msg where date_add(sendtime, interval 2 minute) > now(); 理解: ------------------------------|-----------|-------------|------------------ 初始时间 now() 初始时间2min 字符串 length函数返回字符串长度,以字节为…...
2024年最新版小程序云开发数据模型的开通步骤,支持可视化数据库管理,支持Mysql和NoSql数据库,可以在vue3前端web里调用操作
小程序官方又改版了,搞得石头哥不得不紧急的再新出一版,教大家开通最新版的数据模型。官方既然主推数据模型,那我们就先看看看新版的数据模型到底是什么。 一,什么是数据模型 数据模型是什么 数据模型是一个用于组织和管理数据的…...
智慧水库大坝安全监测预警系统解决方案
前言 水库大坝作为重要的水利设施,承载着防洪涝、灌溉、发电等功能,关系着无数人的生命财产安全,一旦发生意外事故,后果将不堪设想,因此需要建立一套水库大坝安全监测预警系统解决方案。 系统概述 水库大坝安全监测…...
基于SpringBoot+VUE的社区团购系统(源码+文档+部署)
主要内容:Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能与大数据、单片机开发、物联网设计与开发设计、简历模板、学习资料、面试题库、技术互助、就业指导等 业务范围:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写…...
LeetCode 3151. 特殊数组 I【数组】简单【Py3,C++,Java,GO,Rust】
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
超级字符串技能:提升你的编码游戏
嘿嘿,uu们,今天咱们来详解字符函数与字符串函数,好啦,废话不多讲,开干! 1.:字符分类函数 C语言中又一系列的函数是专门做字符分类的,也就是一个字符属于什么类型的字符的,这些函数的使用需要包含头文件ctype.h 这些函数的使用方法都十分类似,博主在这里就举两到三个…...
米联客-FPGA程序设计Verilog语法入门篇连载-16 Verilog语法_时钟分频设计
软件版本:无 操作系统:WIN10 64bit 硬件平台:适用所有系列FPGA 板卡获取平台:https://milianke.tmall.com/ 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑! 1概述 本小节讲解Verilog语法的时钟…...
【Echarts】custom自定义图表实现甘特图
效果图 主要注意点: 1、右上角图例visualMap实现 2、visualMap增加formatter 3、series使用custom自定义图表,encode解析四维数组。核心是renderItem方法,必填项,且需要注意要全部定义在options里面!!&…...
【高等代数笔记】003线性方程组的解法(一)
1. 线性方程组的解法 1.1 解线性方程组的矩阵消元法 【例1】解线性方程组 { x 1 3 x 2 x 3 2 3 x 1 4 x 2 2 x 3 9 − x 1 − 5 x 2 4 x 3 10 2 x 1 7 x 2 x 3 1 \left\{\begin{array}{ll} x_{1}3x_{2}x_{3}2 \\ 3x_{1}4x_{2}2x_{3}9 \\ -x_{1}-5x_{2}4x_{3}10 \\…...
Scrapy入门教程
Scrapy入门教程:打造高效爬虫的第一步 1. 引言 在当今的网络世界中,信息是无价的资源。而爬虫工具则是获取这些资源的有力武器。Scrapy 是 Python 生态系统中最强大的爬虫框架之一,它不仅功能强大,而且易于扩展,适用…...
Microsoft VBA Excel VBA学习笔记——双重筛选+复制数值1.0
问题场景 CountryProductCLASS 1CLASS 2CLASS 3CLASS 4CLASS 5CLASS 6…USApple0.3641416030.8918210610.0591451990.7320110290.0509636560.222464259…USBanana0.2300833330.4027262180.1548836670.2988904860.7802326210.028592635…CNApple0.7762370470.5075548320.481978…...
谷歌反垄断官司败诉后,或又面临被拆分风险?
KlipC报道:上周8月5日,美国法院裁定谷歌的搜索业务违反了美国反垄断法,非法垄断在线搜索和搜索文本广告市场。据悉,胜诉的美国司法部正在考虑拆分谷歌。其他选项包括强制谷歌与竞争对手分享更多数据,以及防止其在人工智…...
数据结构入门——06树
1.树 树(Tree)非线性数据结构,它是n(n≥0)个节点的有限集合,它满足两个条件 : 有且仅有一个特定的称为根(Root)的节点; 其余的节点可以分为m(m…...
FFmpeg源码:av_packet_move_ref、av_packet_make_refcounted函数分析
一、av_packet_move_ref函数 (一)av_packet_move_ref函数的声明 av_packet_move_ref函数声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavcodec/packet.h中: /*** Move every field in src to ds…...
12 中断
12 中断 1、内核中断编程2、顶半部和底半部机制2.1 任务的相关概念2.1.1 分类2.1.2 优先级2.1.3 进程调度2.1.4 休眠sleep 2.2 顶半部和底半部实现机制2.2.1 顶半部特点2.2.2 底半部特点2.2.3 底半部实现方法之:tasklet2.2.4 底半部实现机制之工作队列2.2.5 底半部实现机制之软…...
经典算法题总结:十大排序算法,外部排序和Google排序简介
十大排序算法 就地性:顾名思义,原地排序通过在原数组上直接操作实现排序,无须借助额外的辅助数组,从而节省内存。通常情况下,原地排序的数据搬运操作较少,运行速度也更快。 稳定性:稳定排序在完…...
服务器是什么?怎么选择适合自己的服务器?
在这个数字化的世界中,我们每天都在与各种网站打交道,浏览新闻、购物、看视频等。你是否曾经好奇过,这些网站是如何运行的?它们又是如何实现随时随地可访问的呢? 在这背后,有一个神秘的角色在默默地支撑着…...
区块链技术的应用场景
区块链技术是一种分布式数据库或公共分类账的形式,它保证了数据的完整性和透明性。它最初是为了支持比特币这种加密货币而被发明的,但现在已经被广泛应用于多种领域,包括供应链管理、投票系统、数字身份验证等。 基本概念 区块 (Block) 区块…...
网站开发网站设计案例/seo培训师
ComboBox自定义数据源实现用户输入时出现与用户输入匹配的项using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace _2012_11_15Pra…...
PHP关于简单企业网站开发过程简介/网站外链的优化方法
综述 算是笔记吧!计算机视觉主要任务划分: Semantic segmentation是pixel oriented。也就是面向像素的,事实上这种训练数据需要在每一个pixel上提供label。ClassificationLocalization 识别单个物品并且识别位置(E.g, draw box&…...
做网站个体户经营范围/百度知道网址
介绍: MongoDB是一个基于分布式文件存储的数据库。高性能,开源,无模式的文档型数据库,为WEB应用提供可扩展的高性能数据存储,是当前NoSql数据库中比较热门的一种,由C语言编写。 MongoDB是一个介于关系数据库…...
品牌全案策划案例/上海谷歌seo
1、类加载机制 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。 2、类加载的时机 类从被加载到虚拟机内存中开始,到卸载出…...
网站建设佰首选金手指二七/长春百度seo公司
原始地址:http://www.myhack58.com/Article/sort099/sort0100/2015/62781.htm 一、生成密钥 现在我们通过xshell生成密钥,注意:本章节,我只进行截图,不做进一步的文章说明。 如下: 我们现在有了公钥…...
wordpress怎么打删除线/谷歌浏览器入口
# 获取我的订单元素class属性值get_class_name driver.find_element_by_link_text(我的订单).get_attribute(class)# 判断class属性值是否为activeself.assertEqual(at,uactive) 转载于:https://www.cnblogs.com/liuliu-word/p/9930209.html...