C语言---贪吃蛇(一)---准备工作

这篇具有很好参考价值的文章主要介绍了C语言---贪吃蛇(一)---准备工作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

c语言知识我们已经学完,下来我们制作一个小游戏—贪吃蛇,来巩固我们的编程。


1.Win32 API介绍

本次实现贪吃蛇会使⽤到的⼀些Win32 API知识,接下来我们就学习⼀下。

1.1.Win32 API

Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是⼀个很大的服务中心,调用这个服务中心的各种服务(每⼀种服务就是一个函数),可以帮应用程序达到开启
视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是Microsoft Windows
32位平台的应⽤程序编程接口。

1.2. 控制台程序

平常我们运行起来的黑框程序其实就是控制台程序。
我们可以使用cmd命令来控制台窗口的长宽:设置控制台窗口的大小,30行,100列。

mode con cols=100 lines=30
C语言---贪吃蛇(一)---准备工作,C语言,c语言

参考:mode命令
也可以通过命令设置控制台窗口的名字:

title 贪吃蛇
C语言---贪吃蛇(一)---准备工作,C语言,c语言

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

#include<stdio.h>
#include<Windows.h>
int main()
{
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");
	system("pause");
	return 0;
}

C语言---贪吃蛇(一)---准备工作,C语言,c语言

1.3.控制台屏幕上的坐标COORD

COORD 是Windows API中定义的⼀个结构体,表⽰⼀个字符在控制台屏幕幕缓冲区上的坐标,坐标系
(0,0) 的原点位于缓冲区的顶部左侧单元格。C语言---贪吃蛇(一)---准备工作,C语言,c语言
COORD类型的声明:

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

给坐标赋值:

COORD pos = { 10, 15 };

1.4.GetStdHandle

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

HANDLE GetStdHandle(DWORD nStdHandle);

实例:

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

1.5.GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息

BOOL WINAPI GetConsoleCursorInfo(
HANDLE hConsoleOutput,
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);
PCONSOLE_CURSOR_INFO 是指向 CONSOLE_CURSOR_INFO 结构的指针,该结构接收有关主机游标
(光标)的信息

实例:

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

1.5.1. CONSOLE_CURSOR_INFO

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

typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

• dwSize,由光标填充的字符单元格的百分比。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的水平线条。
• bVisible,游标的可见性。 如果光标可见,则此成员为 TRUE。

CursorInfo.bVisible = false; //隐藏控制台光标

1.6.SetConsoleCursorPosition

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的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)
{
	//获取标准输出的句柄(用来标识不同设备的数值)
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor_info;
	COORD pos = { x,y };
	//设置标准输出上光标的位置为pos
	SetConsoleCursorPosition(houtput, pos);
}

1.7. GetAsyncKeyState

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

SHORT GetAsyncKeyState(
int vKey
);

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。
GetAsyncKeyState 的返回值是short类型,在上⼀次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中,最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。
如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.

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

参考:虚拟键码 (Winuser.h) - Win32 apps
实例:检测数字键

#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)
int main()
{
	while (1)
	{
		if (KEY_PRESS(0x30))
			printf("0\n");
		else if (KEY_PRESS(0x31))
			printf("1\n");
		else if (KEY_PRESS(0x32))
			printf("2\n");
		else if (KEY_PRESS(0x33))
			printf("3\n");
		else if (KEY_PRESS(0x34))
			printf("4\n");
		else if (KEY_PRESS(0x35))
			printf("5\n");
		else if (KEY_PRESS(0x36))
			printf("6\n");
		else if (KEY_PRESS(0x37))
			printf("7\n");
		else if (KEY_PRESS(0x38))
			printf("8\n");
		else if (KEY_PRESS(0x39))
			printf("9\n");
	}
	return 0;
}

2.游戏地图

在游戏地图上,我们打印墙体使用宽字符:□,打印蛇使用宽字符●,打印食物使用宽字符★
普通的字符是占⼀个字节的,这类宽字符是占用2个字节。
这里再简单的讲⼀下C语言的国际化特性相关的知识,过去C语言并不适合非英语国家(地区)使用。
C语言最初假定字符都是单字节的。但是这些假定并不是在世界的任何地方都适用。

C语言字符默认是采用ASCII编码的,ASCII字符集采用的是单字节编码,且只使用了单字节中的低7位,最高位是没有使用的,可表示为0xxxxxxxx;可以看到,ASCII字符集共包含128个字符,在英语国家中,128个字符是基本够用的,但是,在其他国家语言中,比如,在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样⼀来,这些欧洲国家使⽤的编码体系,可以表示最多256个符号。但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不⼀样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel,在俄语编码中又会代表另⼀个符号。但是不管怎样,所有这些编码方式中,0–127表示的符号是⼀样的,不⼀样的只是128–255的这⼀段。
⾄于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。⼀个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是 GB2312,使用两个字节表示⼀个汉字,所以理论上最多可以表示256 x 256 = 65536 个符号。

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

2.1.<locale.h>本地化

<locale.h>提供的函数用于控制C标准库中对于不同的地区会产生不⼀样行为的部分。
在标准中,依赖地区的部分有以下几项:
• 数字量的格式
• 货币量的格式
• 字符集
• 日期和时间的表示形式

2.2 类项

通过修改地区,程序可以改变它的行为来适应世界的不同区域。但地区的改变可能会影响库的许多部
分,其中⼀部分可能是我们不希望修改的。所以C语言支持针对不同的类项进行修改,下⾯的⼀个宏,
指定⼀个类项:
• LC_COLLATE:影响字符串比较函数 strcoll() 和 strxfrm() 。
• LC_CTYPE:影响字符处理函数的行为。
• LC_MONETARY:影响货币格式。
• LC_NUMERIC:影响 printf() 的数字格式。
• LC_TIME:影响时间格式 strftime() 和 wcsftime() 。
• LC_ALL - 针对所有类项修改,将以上所有类别设置为给定的语⾔环境。
每个类项的详细说明,请参考

2.3 setlocale函数

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

setlocale 函数用于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。
setlocale 的第⼀个参数可以是前面说明的类项中的⼀个,那么每次只会影响⼀个类项,如果第一个参数是LC_ALL,就会影响所有的类项。
C标准给第二个参数仅定义了2种可能取值:“C”(正常模式)和" "(本地模式)。
在任意程序执行开始,都会隐藏式执行调⽤:

setlocale(LC_ALL, “C”);

当地区设置为"C"时,库函数按正常方式执行,小数点是⼀个点。
当程序运行起来后想改变地区,就只能显示调用setlocale函数。用" "作为第2个参数,调用setlocale函数就可以切换到本地模式,这种模式下程序会适应本地环境。
比如:切换到我们的本地模式后就支持宽字符(汉字)的输出等。

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

2.4 宽字符的打印

那如果想在屏幕上打印宽字符,怎么打印呢?
宽字符的字面量必须加上前缀“L”,否则 C 语言会把字面量当作窄字符类型处理。前缀“L”在单引号前面,表示宽字符,对应 wprintf() 的占位符为 %lc ;在双引号前面,表示宽字符串,对应wprintf() 的占位符为 %ls 。

#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"%lc\n", ch1);
wprintf(L"%lc\n", ch2);
wprintf(L"%lc\n", ch3);
wprintf(L"%lc\n", ch4);
return 0;
}

普通字符和宽字符打印出宽度的展示如下:
C语言---贪吃蛇(一)---准备工作,C语言,c语言

2.5 地图坐标

我们假设实现⼀个棋盘27行,58列的棋盘(行和列可以根据自己的情况修改),再围绕地图画出墙,如下:
C语言---贪吃蛇(一)---准备工作,C语言,c语言

2.6 蛇身和食物

初始化状态,假设蛇的长度是5,蛇身的每个节点是●,在固定的⼀个坐标处,比如(24, 5)处开始出现蛇,连续5个节点。
注意:蛇的每个节点的x坐标必须是2个倍数,否则可能会出现蛇的⼀个节点有⼀半儿出现在墙体中,另外⼀般在墙外的现象,坐标不好对齐。
关于食物,就是在墙体内随机生成⼀个坐标(x坐标必须是2的倍数),坐标不能和蛇的身体重合,然后打印★。
C语言---贪吃蛇(一)---准备工作,C语言,c语言


下一章博客中,我们会对游戏的实现,再进一步进行讲解文章来源地址https://www.toymoban.com/news/detail-855625.html

到了这里,关于C语言---贪吃蛇(一)---准备工作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 普通单目相机标定——准备工作

    普通单目相机标定——准备工作

            这里我们还是以普通相机为例(非鱼眼相机)来进行后续的相关标定操作,再回顾下相机的成像模型如下所示。         已知相机内参(fx,fy,u0,v0),畸变系数[k1,k2,k3,p1,p2],相机外参[R|T]。世界坐标系中点Pw(Xw,Yw,Zw),投影至像素坐标系点p(u,v)的计算过程如下。 1)

    2024年02月15日
    浏览(12)
  • vue前端开发准备工作ing...

    在项目开始前需要将项目的包管理工具问题解决,这里我使用的包管理工具是yarn。 安装yarn 在你的vue文件目录下的终端安装 npm i -g yarn 创建项目 如果你使用的npm包管理工具就使用如下命令创建项目 如果是yarn: 安装依赖 在你创建的项目文件下的终端安装 npm: npm install yarn:

    2024年01月17日
    浏览(63)
  • 物流实时数仓——概述与准备工作

    物流实时数仓——概述与准备工作

    目录 一、架构设计与技术栈 (一)数仓架构设计  (二)所用技术栈 (三)最终效果 二、关于离线与实时的相关概念 三、实时数仓设计思路 Hadoop 3.3.4 Zookeeper 3.7.1 Kafka 3.3.1 Hbase 2.4.11 Redis 6.0.8 Flink 1.17.0 Clickhouse Spring Sugar 物流         业务 离线         批处理         在处理数据

    2024年01月24日
    浏览(11)
  • JavaWeb准备工作和部分环境配置

    JavaWeb准备工作和部分环境配置

    web开发: web:网页的意思 静态web:提供的数据资源不会发生改变 动态web:数据是不断变化的,现代网站几乎都是动态网站技术栈: Servlet/JSP:基于java,主推B/S架构,可以 ​ 承载高并发,语法类似ASP ​ASP:微软,国内早期流行。在html中嵌入VB脚本, c# ​PHP:开发速度快,功能

    2024年02月08日
    浏览(10)
  • 5.Python爬虫前的准备工作

    5.Python爬虫前的准备工作

    Python 爬虫作为 Python 编程的进阶知识,要求具备较好的 Python 编程基础 了解 Python 语言的多进程与多线程,并熟悉正则表达式语法,也有助于编写爬虫程序 了解 Web 前端的基本知识,比如 HTML、CSS、JavaScript,这能够帮助分析网页结构,提炼出有效信息 掌握 OSI 七层网络模型,

    2024年01月25日
    浏览(13)
  • C++入门实现黑客攻击系统(准备工作)

    C++入门实现黑客攻击系统(准备工作)

    分析项目需求 黑客打开这个攻击系统后,首先看到的就是一个“功能菜单”。 以便让黑客选择所需要的功能。 假设需求如下: 1.网站404攻击 2.网站篡改攻击 3.网站攻击记录 4.DNS攻击 5.服务器重启攻击 创建一个空项目CP1 添加文件admin.c 运行结果: 执行方式1(开发时使用)

    2024年02月08日
    浏览(14)
  • 数据清洗:数据挖掘的前期准备工作

    数据清洗:数据挖掘的前期准备工作

    ⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者: 秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们 点赞👍🏻、收藏

    2024年02月07日
    浏览(17)
  • 第一周:AI产品经理跳槽准备工作

    第一周:AI产品经理跳槽准备工作

    因素1:AI行业发展现状机会和未来 可以关注一些AI行业报告,这里我读了大概十来份报告,截取了一些关注点。 报告下载: 2023中国AI商业落地投资价值研究报告(63页):人工智能机会、价值评估和AI+行业场景分析、服务商案例、未来发展; 2. AI人才市场情况 报告下载:2

    2024年02月02日
    浏览(10)
  • 02. 坦克大战项目-准备工作和绘制坦克

    02. 坦克大战项目-准备工作和绘制坦克

    1. 首先我们要创建四个类 1. Tank类 介绍:Tank 类主要用来表示坦克的基本属性和行为 2. Hero类 介绍:Hero 类: 继承自 Tank 类,表示游戏中的主角坦克。 通过 super(x, y) 调用父类构造方法,初始化主角坦克的位置。 3. MyPanel类 介绍:MyPanel类: 继承自 JPanel ,用于绘制游戏的绘图

    2024年01月22日
    浏览(10)
  • 物流实时数仓DWD层——1.准备工作

    目录 1.创建主程序——DwdOrderRelevantApp类 2.创建DWD层的事实表——来源于订单表和订单明细表 (1)创建订单表实体类 (2)创建订单明细表实体类 (3)创建交易域:下单事务事实表实体类,并整合(1)与(2),采用下单时间 (4)创建交易域:支付成功事务事实表实体类,并整合(1)与(2),采

    2024年02月01日
    浏览(12)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包