从零开始实现贪吃蛇小游戏(C语言版第一期)

目录

引言

实现基本的功能:

游戏效果展示:

温馨提示:

1. 了解Win32 API

1.1 Win32 API 介绍

1.2 控制台程序

1.3 控制台命令(引用stdlib.h头文件)

1.4 Win32API(引用windows.h头文件)

1.4.1 控制台屏幕上的坐标COORD

1.4.2 GetStdHandle

1.4.3 CONSOLE_CURSOR_INFO

1.4.4 GetConsoleCursorInfo

1.4.5 SetConsoleCursorInfo

1.4.6 SetConsoleCursorPosition

1.4.7 GetAsyncKeyState


引言

贪吃蛇是1976年推出的一款街机游戏,游戏中玩家控制一条不断移动的蛇,在屏幕上吃掉出现的食物。每吃掉一个食物,蛇的身体就会变长。游戏的目标是尽可能长时间地生存下去,同时避免蛇头撞到自己的身体或屏幕边缘。玩家需要灵活操作,利用策略在有限的空间内避免碰撞,挑战高分。

本文将教你使⽤C语⾔在Windows环境的控制台中模拟实现经典⼩游戏贪吃蛇。

实现基本的功能:

• 贪吃蛇地图绘制

• 蛇吃⻝物的功能(上、下、左、右⽅向键控制蛇的动作)

• 蛇撞墙死亡

• 蛇撞⾃⾝死亡

• 计算得分

• 蛇⾝加速、减速

• 暂停,退出游戏

游戏效果展示:

温馨提示:

请确保学完了C语言课程,数据结构链表,否则看本文可能会比较吃力

1. 了解Win32 API

1.1 Win32 API 介绍

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

1.2 控制台程序

平常我们运⾏代码跳出来的⿊框其实就是控制台程序

int main() {
	printf("Hello World\n");
	return 0;
}

在控制台上方点击鼠标右键,再点击属性

可以更改控制台背景颜色,文字颜色

注意:在windows10/11系统中,默认调用出的是终端,不是控制台

这个小游戏要在控制台中才能正常运行,所以我们在终端上方点击鼠标右键,再点击设置

如图所示,在默认终端应用程序中切换为控制台主机

1.3 控制台命令(引用stdlib.h头文件)

我们可以使⽤cmd命令来设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列

mode con cols=100 lines=30

参考:mode命令

也可以通过命令设置控制台窗⼝的名字:

title 贪吃蛇

参考:title命令

这些能在控制台窗⼝执⾏的命令,也可以调⽤C语⾔函数system来执⾏例如:

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

1.4 Win32API(引用windows.h头文件)

1.4.1 控制台屏幕上的坐标COORD

COORD是WindowsAPI中定义的⼀个结构体,表⽰⼀个字符在控制台屏幕幕缓冲区上的坐标,坐标系 (0,0) 的原点位于缓冲区的顶部左侧单元格。

COORD类型的声明:

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

给坐标赋值:

COORD pos = { 10, 15 };

1.4.2 GetStdHandle

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

HANDLE GetStdHandle(DWORD nStdHandle);




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

参考:GetStdHandle

1.4.3 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.4.4 GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标⼤⼩和可⻅性的信息

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

参考:GetConsoleCursorInfo

1.4.5 SetConsoleCursorInfo

设置指定控制台屏幕缓冲区的光标的⼤⼩和可⻅性。

 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);//设置控制台光标状态
 

参考:SetConsoleCursorInfo

1.4.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);

set_pos:封装⼀个设置光标位置的函数

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

参考:SetConsoleCursorPosition

1.4.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 )
#include <stdio.h>
 #include <windows.h>
 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;
 }

这一期介绍了制作贪吃蛇游戏需要了解的前置知识,可能大家还不是特别清楚上面的各种函数怎么使用,不用担心,下一期会正式开始教学制作贪吃蛇游戏,同时也会继续深入讲解以上函数的使用方式。

那么第一期的内容就到这里了,觉得有收获的同学们可以给个点赞、关注、收藏哦,谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值