vs 2017下,编写的程序,一个pch.h头文件,这个是项目开始就自带的。一个pch.cpp和snake.cpp。
snake.cpp代码如下:
// snake.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include"pch.h"
#include<time.h>
int main()
{
startgame();
return 0;
}
pch.cpp,代码如下:
#include "pch.h"
#include<windows.h>
#include<conio.h>
#include<time.h>
void startgame() {
//欢迎
welcome();
//打印地图
printfmap();
//初始化蛇
initsnake();
//移动并控制方向
move_controldirection();
}
void welcome() {
printf("\n\n\n\n\n\n\n\n\n");
printf("\t\t\t\t\t\t欢迎来到贪吃蛇游戏");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("\t\t\t\t\t\t");
system("pause"); //暂停
system("cls"); //清屏
printf("\n\n\n\n\n\n\n\n\n\n");
printf("\t\t\t\t\t 用↑.↓.←.→分别控制蛇的移动.\n");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t");
system("pause");
system("cls");
}
void printfmap() {
for (int i = 0; i < 60; i += 2) //这里为什么加2呢,因为这个方块呢是unicode字符集,占两个字节,所以加2
{
setcursorpos(i, 0);
printf("■");
setcursorpos(i, 29);
printf("■");
}
for (int i = 1; i < 30; i++)
{
setcursorpos(0, i);
printf("■");
setcursorpos(58, i);
printf("■");
}
}
//可以调节光标出现的位置
void setcursorpos(int x, int y) {
HANDLE a = GetStdHandle(STD_OUTPUT_HANDLE); //获得我们现在这个控制台窗口的句柄
COORD b = { x,y };
SetConsoleCursorPosition(a, b);
}
void initsnake() {
setcursorpos(22, 10);
printf("■");
}//打印蛇
void printfsnake(snake* a) {
snake* b = a;
while (a!= NULL) {
setcursorpos(a->x, a->y);
printf("■");
a = a->next;
}
///隐藏光标
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);
CursorInfo.bVisible = false;
SetConsoleCursorInfo(handle, &CursorInfo);
}
void overgame() {
system("cls");
printf("\n\n\n\n\n\n\n\n\n");
printf("\t\t\t\t\t\t 游戏结束");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("\t\t\t\t\t\t");
system("pause");
}
//判断是否有键盘敲击并且判断是否碰触边界
void kbhit(const snake* b,char& ch) {
if (b->x == 0 || b->x == 58 || b->y == 0 || b->y == 29) {
overgame();
}
if (_kbhit()) {
ch = _getch();
}
}
//随机产生食物
food random_produce_food() {
food b;
srand((unsigned int)time(NULL));
b.x = rand() % 56+2;
b.y = rand() % 28+1;
return b;
}
//显示相应数据信息
void printfdata() {
setcursorpos(80, 10);
printf("have ate food number:%d", eat_food_number);
setcursorpos(80, 11);
printf("snake length is:%d", eat_food_number + 1);
setcursorpos(80, 12);
printf("spend time:%d s", clock()/1000);
}
void judegeeatfood_increasesnake(snake* b, food& c, char& ch, snake& a) {
//判断是否吃到了食物
if (((b->x) == (c.x) || (b->x) == (c.x - 1)) && (b->y) == (c.y)) {
++eat_food_number;
printfdata();
//蛇身子变长一
snake* y = (snake*)malloc(sizeof(snake));//不然的话,出了这个if之后空间就没了
y->next = NULL;
//1.只有一个蛇节点时
if (b->next == NULL) {
b->next = y;
y->front = b;
switch (ch) {
case 'w': {
y->x = b->x;
y->y = b->y + 1;
break;
}
case 's': {
y->x = b->x;
y->y = b->y - 1;
break;
}
case 'a': {
y->x = b->x + 2;
y->y = b->y;
break;
}
case 'd': {
y->x = b->x - 2;
y->y = b->y;
break;
}
}
}
//2.超过一个蛇的节点时
else {
while (b->next->next != NULL) {
b = b->next;
}
snake* z = b->next;
z->next = y; //将新节点绑到最后
y->front = z;
if ((b->x) < (z->x) && (b->y) == (z->y)) {
y->x = z->x + 2;
y->y = z->y;
}
else if ((b->x) > (z->x) && (b->y) == (z->y)) {
y->x = z->x - 2;
y->y = z->y;
}
else if ((b->x) == (z->x) && (b->y) > (z->y)) {
y->x = z->x;
y->y = z->y - 1;
}
else {
y->x = z->x;
y->y = z->y + 1;
}
b = &a;
}
//重现刷新食物
c = random_produce_food();
setcursorpos(c.x, c.y);
printf("*");
}
}
void move_controldirection() {
//产生蛇头
snake a;
a.x = 22;
a.y = 10;
a.next = NULL;
a.front = NULL;
snake* b = &a;
//显示初始信息
setcursorpos(80, 10);
printf("have ate food number:0");
setcursorpos(80, 11);
printf("snake length is:1");
setcursorpos(80, 12);
printf("spend time:%d s", clock() / 1000);
//最开始的食物
food c;
c = random_produce_food();
setcursorpos(c.x, c.y);
printf("*");
//用来接受用户键盘敲击,默认向右移动
char ch = 'd';
while (1) {
Sleep(250);
//判断是否有键盘输入
kbhit(b, ch);
//判断是否吃到了食物
judegeeatfood_increasesnake(b, c, ch, a);
//这里每次循环打印一遍food是因为如果蛇正好在食物的位置,food会被覆盖,显示不出来的
setcursorpos(c.x, c.y);
printf("*");
switch (ch) {
case 'd':
{//清掉最后一个的显示
while (b->next != NULL) { b = b->next; }
setcursorpos(b->x, b->y);
printf(" ");
//开始时的定向移动
snake* g = b;
while (g->front != NULL) {
g->x = g->front->x;
g->y = g->front->y;
g = g->front;
}
b = &a;
(b->x) += 2;
printfsnake(b);
break;
}
case 'w': {
while (b->next != NULL) { b = b->next; }
setcursorpos(b->x, b->y);
printf(" ");
//开始时的定向移动
snake* g = b;
while (g->front != NULL) {
g->x = g->front->x;
g->y = g->front->y;
g = g->front;
}
b = &a;
--(b->y);
printfsnake(b);
break;
}
case 'a': {
while (b->next != NULL) { b = b->next; }
setcursorpos(b->x, b->y);
printf(" ");
//开始时的定向移动
snake* g = b;
while (g->front != NULL) {
g->x = g->front->x;
g->y = g->front->y;
g = g->front;
}
b = &a;
(b->x) -= 2;
printfsnake(b);
break;
}
case 's': {
while (b->next != NULL) { b = b->next; }
setcursorpos(b->x, b->y);
printf(" ");
//开始时的定向移动
snake* g = b;
while (g->front != NULL) {
g->x = g->front->x;
g->y = g->front->y;
g = g->front;
}
b = &a;
++(b->y);
printfsnake(b);
break;
}
default:
break;
}
}
}
pch.h头文件中的代码如下:
#ifndef PCH_H
#define PCH_H
#include<stdio.h>
#include<windows.h>
//定义蛇的节点
typedef struct _snake {
int x;
int y;
struct _snake *next;
struct _snake* front;
}snake;
struct food {
int x;
int y;
};
int eat_food_number = 0;
void startgame();
void welcome();
void printfmap();
void setcursorpos(int x, int y);
void initsnake();
void move_controldirection();
void printfsnake(struct _snake*);
void overgame();
void kbhit(const struct _snake*,char&);
food random_produce_food();
void judegeeatfood_increasesnake(snake* b, food& c, char& ch, snake& a);
void printfdata();
#endif //PCH_H
写的稍微有点乱,不过慢慢看还是可以看懂得。里面涉及到了一些 Windows API函数,看不懂可以去百度。然后,就是关于蛇身子链表的设计了,其他的都没有什么东西。