一.技术要点:
贪吃蛇需要掌握:
c语言函数,枚举,结构体,动态内存管理,预处理指令,链表,Win32 API等
二.Win32 API
1.Win32 API简介
windows可以帮应用程序卡其视窗,描绘图案,使用周边设备,,Win32 API就是windows32位平台上的应用程序编程接口
2.控制台程序
(1).使用cmd命令设置控制台窗口的长宽
输入mode con cols=100 lines=30
(2.)可以通过命令设置控制台的窗口的名字
title xxx
(3.)C语言的system函数实现控制台的命令
#include<stdio.h>
#include<stdlib.h>
int main()
{
system("mode con cols=50 lines=20");
system("title 贪吃蛇");
system("pause");
return 0;
}
(4.)控制台屏幕上的坐标
COORD是windows API中定义的结构体,表示一个字符在控制台屏幕缓冲区上的坐标,坐标(0,0)位于缓冲区左上角
CORRD类型声明:
typedef struct _CORRD
{
SHORT X;
SHORT Y;
}CORRD, *PCORRD;
给结构体定坐标:
#include <windows.h>
CORRD pos = { 10,15 };
(5.)GetStdHandle获取设备
它也是一个windows API函数,用于从一个特定的标准设备(标准输入,标准输出或标准错误)中取得一个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备
函数的声明:
HANDLE GetStdHandle(DWORD nStdHandle);
eg.
HANDLE hOutput = NULL;
//获取标准输出的句柄
hOutput = GetStHandle(STD_OUTPUT_HANDLE);
(6.)GetConsoleCursorInfo获取光标信息
检索有关指定控制台屏幕缓冲区的光标大小和可见性信息(鼠标信息)
函数的声明:
BOOL WINAPI GetConsoleCursorInfo(
HANDLE hConsoleOutput
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);
PCONSOLE_CURSOR_INFO是指向CONSOLE_CURSOR_INFO结构的指针,该结构接受有感主机游标(光标)的信息
eg.
#include <windows.h>
int main()
{
CONSOLE_CURSOR_INFO cursor_info = { 0 };
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleCursorInfo(handle,&cursor_info);
return 0;
}
CONSOLE_CURSOR_INFO是结构体,其中有两个成员,:bVisible和dwSize分别控制光标的可可见性和大小
(7.)SetConsoleCursorPosition设置光标位置
void SetPos(int x,int y)
{
//获得设备句柄
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
//根据句柄设置光标位置
CORRD pos = { x,y };
SetConsoleCursorPosition(handle,pos);
}
(8.)GetAsyncKeyState获取按键情况
想要判断一个键是否被按,可以检测GetAsyncKeyState返回值的最低为是否为1
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)
eg.
#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");
......
}
}
这样可以在按下数字键是在屏幕上输出数字
三.贪吃蛇游戏的设计与分析
一.地图
1.<locale.h>本地化
<locale.h>提供的函数用于控制C标准库中对于不同地区会产生不一样的行为的部分
在标准中,依赖地区的部分有以下几项:
1.数字量的格式
2.货币量的格式
3.字符集
4.日期和时间的表示形式
2.类项
1.LC_COLLATE:影响字符串比较函数strcoll()和strxfrm()
2.LC_CTYPE:影响字符处理函数的行为
3.LC_MONCTARY:影响货币格式
4.LC_NUMERIC:影响printf()的数字格式
5.LC_TIME:影响时间格式strftime()和wcsfting()
6.LC_ALL:针对所有类项修改,将以上的多有类别设置为给定的语言环境
3.setlocale函数
该函数用于修改当前的地区,可以针对一个类项,也可以针对所有类项
函数声明:
char* setlocale(int category,const char* locale);
第一个参数是修改的类项,第二个为地区
C的标准给了第二个参数2种可能取值:1."C"(正常模式) 2.""(本地模式)
在任意程序执行开始时,会隐藏执行调用setlocale(LC_ALL,"C");
第二个参数也可以传入NULL,通过传入NULL可以查询默认的本地信息
4.宽字符的打印
一个宽字符占领个字符的位置
int main()
{
setlocale(LC_ALL,"");
wchar_t ch = L'中国';
wprintf(L"%lc",ch);
return 0;
}
5.地图坐标
可以假设设计一个27行,58列的地图并围绕地图画出墙壁,如下
二.蛇身和食物
蛇身
可以初始化蛇身长度为5,在随机坐标出现蛇,连续五个节点代表蛇身
注意:为了防止社的一个节点的一半出现在墙体里,另一半在墙外,最好让蛇身的每一个节点的X坐标为2的倍数
食物
在墙体内随机生成一个坐标(x的坐标必须为2的倍数),同时坐标不能与蛇身重合
如图:
三.数据结构设计
一.蛇身节点
蛇身可以使用链表设计,需要存储的信息为当前节点的蛇身的坐标(x,y)和下一个节点
typedef struct snakenode
{
int x;
int y;//节点坐标
struct snake* next;
}snakenode, * psnakenode;
二.贪吃蛇状态
enum GAME_STATUS
{
OK = 1,
ESC,
KILL_BY_WALL,
KILL_BY_SELF
};
enum DIRECTION
{
UP = 1,
DOWN,
LEFT,
RIGHT
};
typedef struct snake
{
psnakenode psnake;//维护整条蛇的指针
psnakenode pfood; //指向食物的指针
int score; //当前累计的分数
int foodweight; //一个食物的分数
int sleeptime; //蛇休眠的时间.休眠时间越短,蛇移动的速度越快
enum GAME_STATUS status;
//游戏当前的状态
enum DIRECTION dir;
//蛇的运动方向
}snake,psnake;
三.开始游戏
void gamestart(psnake ps)