本节需用到的知识点:

(1)windows句柄HANDLE

(2)GetStdHandle()

(3)SetConsoleCursorPosition()

想要蛇自己移动,就需要定义一个表示蛇移动方向的变数direction,direction等于1,2,3,4时,表示上下左右,当输入w a s d 是,分别为direction赋值。

具体操作如下

在程序开始定义一个direction

int direction=1; //1表示向上,程序开始默认向上

//2表示向下

//3表示向左

//4表示向右

然后我们只需要修改move()函数内的部分程序,即可实现蛇自己运动

void move() //响应键盘输入,控制蛇的移动
{
map[snake_x][snake_y]=0; //更新地图,将蛇的老位置赋值为0
if(kbhit())
{
char c;
c=getch();
switch(c)
{
case w:direction=1; break; //按w键,蛇向上移动
case s:direction=2; break; //按s键,蛇向下移动
case a:direction=3; break; //按a键,蛇向左移动
case d:direction=4; break; //按d键,蛇向右移动
default: break;
}
}
switch(direction) //根据direction值,改变蛇的坐标
{
case 1:snake_x--; break;
case 2:snake_x++; break;
case 3:snake_y--; break;
case 4:snake_y++; break;
default:break;
}
map[snake_x][snake_y]=3; //更新地图,将蛇的新位置赋值为3
}

如果感觉蛇的运动速度太慢,我们可以更改Sleep()函数内的睡眠时间,比如Sleep(200)或Sleep(100),但我们会发现,当睡眠时间减少时,屏幕闪的太严重,极大的影响了游戏体验,这时我们就需要使用windows下的移动游标的相关函数来自己写一个清屏函数,关于与windows系统相关的函数,大家如果不打算深入学习windows编程,则不需要太深入理解,只要了解函数作用即可。

下面一一浅显的介绍一下

(1)HANDLE 名称为句柄,用来表示windows里的各类资源的,如屏幕,键盘、游标等

(2)GetStdHandle(),用来获取windows资源的句柄

HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); 看英文名字就知道大概意思,获取输出设备的句柄赋值给声明的变数handle,这句话的意思就是我们已经能够用handle来代表屏幕窗口了。

(3)SetConsoleCursorPosition(),通过传递游标位置参数,修改游标位置

清屏函数代码如下

void clear()
{
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄
COORD coord; //定义游标位置结构体,其中包含x y坐标两个变数
coord.X=0; //x=0屏幕最上方
coord.Y=0; //y=0屏幕最左边
SetConsoleCursorPosition(handle,coord);//将游标位置移至屏幕左上角
}

这样我们将clear()替代system("cls"),将睡眠时间缩小至100,也不会发生闪屏现象了

完整程序代码如下

#include <stdio.h>
#include<Windows.h>
#include<conio.h>

int map[20][40]; //二维数组map[][],用来表示游戏地图
//为0时,表示空白,什么都没有
//为1时,表示上下围墙
//为2时,表示左右围墙
//为3时,表示蛇
//为4时,表示食物

int snake_x=10,snake_y=20; //用来表示蛇的位置坐标
int direction=1;

void clear()
{
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄
COORD coord; //定义游标位置结构体,其中包含x y坐标两个变数
coord.X=0; //x=0屏幕最上方
coord.Y=0; //y=0屏幕最左边
SetConsoleCursorPosition(handle,coord);//将游标位置移至屏幕左上角
}
void show() //显示界面
{
for(int i=0;i<20;i++) //列印地图
{
for(int j=0;j<40;j++)
switch(map[i][j])
{
case 0: printf(" ");break; //0代表空格,什么也不列印
case 1: printf("-");break; //1代表上下围墙
case 2: printf("|");break; //2代表左右围墙
case 3: printf("@");break; //3代表蛇身用@表示
case 4: printf("$");break; //4代表食物用$表示
}
printf("
");
}
}

void init() //初始化地图
{
int i,j;
for(i=0;i<20;i++)
for(j=0;j<40;j++)
map[i][j]=0; //初始化二维数组,全部置为0

for(i=0;i<20;i++)
for(j=0;j<40;j++)
{
if(i==0||i==19)
map[i][j]=1; //赋值上下围墙 ------------
if(j==0||j==39)
map[i][j]=2; //赋值左右围墙||||||||||||||
}

map[snake_x][snake_y]=3; //利用变数在地图中间初始化蛇身
map[15][6]=4; //初始化食物位置,随便定义了一个位置
show();
}

void move() //响应键盘输入,控制蛇的移动
{
map[snake_x][snake_y]=0; //更新地图,将蛇的老位置赋值为0
if(kbhit())
{
char c;
c=getch();
switch(c)
{
case w:direction=1; break; //按w键,蛇向上移动
case s:direction=2; break; //按s键,蛇向下移动
case a:direction=3; break; //按a键,蛇向左移动
case d:direction=4; break; //按d键,蛇向右移动
default: break;
}
}
switch(direction) //根据direction值,改变蛇的坐标
{
case 1:snake_x--; break;
case 2:snake_x++; break;
case 3:snake_y--; break;
case 4:snake_y++; break;
default:break;
}
map[snake_x][snake_y]=3; //更新地图,将蛇的新位置赋值为3
}
void main()
{
init();
while(1)
{
clear(); //调用自定义的清屏函数
move();
show();
Sleep(100); //睡眠函数,使程序暂停0.1s
}
}

下一节就要开始介绍贪吃蛇游戏中最重要的一部分了

(1)怎么检测蛇碰到了围墙或食物

(2)怎样使多节长度的蛇沿著一定的轨迹移动,大家可以先想一想思路


推荐阅读:
查看原文 >>
相关文章