您的位置:首页 > 其它

一个控制台贪吃蛇小游戏(wsad控制移动)

2013-06-25 12:26 591 查看


/********************************************
* 程序名称:MR.DUAN 的贪吃蛇游戏(链表法)
* 作  者:WindAutumn <fluttingleaves@hotmail.com>
* 最后修改:2012-7-25-PM
* 版 本 号:1.3
*
*
* 以后有空再修改
* *****************************************/

#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>

#define MAXWIDE 80
#define MAXHIGH 24

typedef struct
{
int x;
int y;
} POSITION; // 食物,节点

typedef struct snackbody
{
POSITION body;
snackbody * link;
} SNACK; // 蛇身的链表

void StartGame();
void InitScreen(HANDLE hSnack);
void HideCursor(HANDLE hSnack);
void GotoXY(HANDLE hSnack, int x, int y);

void PrintRandFood(HANDLE hSnack, POSITION * food);
void PrintSnack(HANDLE hSnack, SNACK * snack, int mode);
//int  HeadDirection();
SNACK * SnackHeadWalk(SNACK * snack, int direction);
void IsDied(HANDLE hSnack, SNACK * snack, POSITION * food);
void GameOver(HANDLE hSnack);

void main()
{
system("color 7b");// 白色背景
SetConsoleTitle("MR.DUAN 的贪吃蛇游戏");
StartGame();
}

void StartGame()
{
POSITION food;
SNACK * snack = (SNACK *)malloc(sizeof(SNACK));
char length = 0;// 定义长度
int  direction_get = 0;// 定义获取的方向
int  direction_last = 0;// 定义之后的方向
int  key_direct;// 按下的按键
int  foodflag = 0;// 食物是否存在,1--是,0--否

HANDLE hSnack = GetStdHandle(STD_OUTPUT_HANDLE);
HideCursor(hSnack);
InitScreen(hSnack);

srand(time(NULL));// 初始化随机数生成器,以便产生随机 食物
snack->body.x = 40;// 蛇头
snack->body.y = 12;
snack->link = NULL;

PrintSnack(hSnack, snack, 0);// mode 0 打印初始蛇头
Sleep(500);
while(1)// 贪吃蛇操作
{
if(_kbhit())
{
key_direct = getch();
switch(key_direct)
{
case 'w'  :
direction_get = 1;
break;// 上// 键盘四按键的逆序
case 'a'  :
direction_get = 2;
break;// 左
case 's'  :
direction_get = 3;
break;// 下
case 'd'  :
direction_get = 4;
break;// 右
}
}
if((direction_last != direction_get + 2)&&(direction_last != direction_get - 2))
direction_last = direction_get;// 如果行进方向和获取方向不为相反,则改变行进方向
snack = SnackHeadWalk(snack, direction_last);

if(0 == foodflag)
{
PrintRandFood(hSnack, &food);// 如果食物已经被吃,则产生新的食物
foodflag = 1;// 食物标记为 未吃
}

if(snack->body.x == food.x && snack->body.y == food.y)// 头碰到食物
{
PrintSnack(hSnack, snack, 0);// 只打头不去尾
foodflag = 0;// 食物被吃,没有食物了
length++;
}
else
{
PrintSnack(hSnack, snack, 0);// 打头
PrintSnack(hSnack, snack, 1);// 去尾
}
IsDied(hSnack, snack, &food);
Sleep(500);
}
}

void InitScreen(HANDLE hSnack)// 打印周围红框框
{
int i;
SetConsoleTextAttribute(hSnack, FOREGROUND_INTENSITY | FOREGROUND_RED |
BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);// 红色字体,白色背景
GotoXY(hSnack, 0, 0);
printf("╔");
for(i=1; i<(MAXWIDE-1)/2; i++)
printf("═");
printf("╗");

for(i=1; i< MAXHIGH; i++)
{
GotoXY(hSnack, 0, i);
printf("║");
GotoXY(hSnack, MAXWIDE-2, i);
printf("║");
}

GotoXY(hSnack, 0, MAXHIGH);
printf("╚");
for(i=1; i<(MAXWIDE-1)/2; i++)
printf("═");
printf("╝");

GotoXY(hSnack, 0, 0);
}

void HideCursor(HANDLE hSnack)
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(hSnack, &cursor_info);
}

void GotoXY(HANDLE hSnack, int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(hSnack, coord);
}

void PrintRandFood(HANDLE hSnack, POSITION * food)// 2--78 中的偶数, 1--23
{
food->x = (rand()%76 + 2)/2*2;
food->y = rand()%22 + 1;
SetConsoleTextAttribute(hSnack,FOREGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
GotoXY(hSnack, food->x, food->y);
printf("█");
}

void PrintSnack(HANDLE hSnack, SNACK * snack, int mode)
{
if(0 == mode)
{
GotoXY(hSnack, snack->body.x, snack->body.y);
SetConsoleTextAttribute(hSnack,FOREGROUND_BLUE | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
printf("□");
}
if(1 == mode)
{
SNACK * ptail, *pnext;
ptail = snack;
pnext = ptail->link;
while(pnext->link!=NULL)
{
ptail = ptail->link;
pnext = ptail->link;
}
GotoXY(hSnack, pnext->body.x, pnext->body.y);
printf("  ");
ptail->link = NULL;
free(pnext);
}
}

/*int  HeadDirection()
{
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD inRec;
DWORD res;

ReadConsoleInput(hInput, &inRec, 0, &res);
if(inRec.EventType == KEY_EVENT)
{
switch(inRec.Event.KeyEvent.wVirtualKeyCode)
{
case VK_UP    : return 1;
case VK_DOWN  : return 2;
case VK_LEFT  : return 3;
case VK_RIGHT : return 4;
}
}
return 0;
}*/

SNACK * SnackHeadWalk(SNACK * snack, int direction)
{
// 0为默认值,默认向右,1为向上,2为向下,3为向左,4为向右

SNACK * newhead = (SNACK * )malloc(sizeof(SNACK));
switch(direction)
{
case 1 :
newhead->body.x = snack->body.x;
newhead->body.y = snack->body.y - 1;
break;
case 3 :
newhead->body.x = snack->body.x;
newhead->body.y = snack->body.y + 1;
break;
case 2 :
newhead->body.x = snack->body.x - 2;
newhead->body.y = snack->body.y;
break;
case 0 :
case 4 :
newhead->body.x = snack->body.x + 2;
newhead->body.y = snack->body.y;
break;
}
newhead->link = snack;
return newhead;
}

void IsDied(HANDLE hSnack, SNACK * snack, POSITION * food)
{
SNACK * pCompare = snack;
if(snack->body.x == 0 || snack->body.y ==0 || snack->body.x == MAXWIDE ||snack->body.y == MAXHIGH)
GameOver(hSnack);// 撞墙死亡
while(pCompare->link!=NULL)
{
if(pCompare->body.x == snack->body.x && pCompare->body.y == snack->body.y && pCompare!=snack)
GameOver(hSnack);// 吃到自己死亡
pCompare = pCompare->link;
}
}

void GameOver(HANDLE hSnack)
{
GotoXY(hSnack, MAXWIDE/2, MAXHIGH/2);
printf("GAME OVER!");
GotoXY(hSnack, MAXWIDE/2, MAXHIGH/2 + 1);
printf("PRESS ANY KEY TO EXIT.");
getch();
exit(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: