/***********************************************/
//Snake.h
#ifndef __SNAKE_H__
#define __SNAKE_H__
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#define WALL "◆"
#define FOOD "■"
#define INIT_X 10
#define INIT_Y 10
//蛇身結點
typedef struct SnakeNode
{
int x;
int y;
struct SnakeNode *next;
}SnakeNode, *pSnakeNode;
//方向
enum Direction
{
UP = 1,
DOWN,
LEFT,
RIGHT
};
//遊戲狀態
enum GameStatus
{
OK,//正常運行
NORMAL_END,//正常結束
KILL_BY_WALL,//撞牆
KILL_BY_SELF//咬到自己
};
typedef struct Snake
{
pSnakeNode _psnake;//蛇身指針維護
pSnakeNode _pFood; //維護食物位置
int _TotalScore; //總分數
int _AddScore; //增加的分數
int _SleepTime; //休眠時間
enum Direction _Dir;//蛇頭方向默認向右
enum GameStatus _Status;//遊戲狀態
}Snake, *pSnake;
//打印歡迎界面
void WelcomeToGame();
//創建地圖
void CreateMap();
//初始化蛇
void InitSnake(pSnake ps);
//初始化食物
void CreateFood(pSnake ps);
//創建貪喫蛇
void GameStart(pSnake ps);
//暫停遊戲
void Pause();
//判斷下一步是不是食物
int NextHasFood(pSnakeNode pn, pSnakeNode pf);
//喫食物
void EatFood(pSnakeNode pn, pSnake ps);
//沒有食物喫
void NoFood(pSnakeNode pn, pSnake ps);
//蛇的移動
void SnakeMove(pSnake ps);
//撞牆
int KillByWall(pSnake ps);
//撞到自身
int KillBySelf(pSnake ps);
//打印幫助信息
PrintHelpInfo(pSnake ps);
//遊戲開始跑起來
void GameRun(pSnake ps);
//結束遊戲
void GameEnd(pSnake ps);
#endif //__SNAKE_H__
/***********************************************/
//Snake.c
#include "Snake.h"
//創新結點
pSnakeNode BuyNode()
{
pSnakeNode pRet = (pSnakeNode)malloc(sizeof(SnakeNode));
if (NULL == pRet)
{
perror("BuyNode::malloc()");
exit(EXIT_FAILURE);
}
pRet->x = 0;
pRet->y = 0;
pRet->next = NULL;
return pRet;
}
//設置位置函數
void SetPos(int x, int y)
{
COORD pos = { 0 };
HANDLE hOutput = NULL;
pos.X = x;
pos.Y = y;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput, pos);
}
//打印歡迎界面
void WelcomeToGame()
{
//設置窗口大小
system("mode con cols=120 lines=30");
SetPos(45, 14);
printf("歡迎來到貪喫蛇小遊戲.");
SetPos(45, 28);
system("pause");
system("cls");
SetPos(40, 13);
printf("用 ↑ ↓ ← → 來控制蛇的移動. F1爲加速.F2爲減速.");
SetPos(40, 15);
printf("加速獲得分數更高");
SetPos(40, 28);
system("pause");
system("cls");
}
//創建地圖
void CreateMap()
{
int i;
SetPos(0, 0);
//上
for (i = 0; i <= 58; i += 2)
{
SetPos(i, 0);
printf(WALL);
}
//下
for (i = 0; i <= 58; i += 2)
{
SetPos(i, 27);
printf(WALL);
}
//左
for (i = 1; i <= 26; i++)
{
SetPos(0, i);
printf(WALL);
}
//右
for (i = 1; i <= 26; i++)
{
SetPos(58, i);
printf(WALL);
}
}
//初始化蛇
void InitSnake(pSnake ps)
{
pSnakeNode first = BuyNode();
pSnakeNode cur = NULL;
int i = 0;
first->x = INIT_X;//蛇在地圖中的起始位置
first->y = INIT_Y;
for (i = 1; i <= 4; i++)//蛇的起始長度爲5☆
{
cur = BuyNode();
cur->x = first->x + 2;
cur->y = first->y;
cur->next = first;
first = cur;
}
cur = first;
while (cur)
{
SetPos(cur->x, cur->y);
printf(FOOD);
SetPos(60, 27);
cur = cur->next;
}
ps->_psnake = first;
}
//初始化食物
void CreateFood(pSnake ps)
{
pSnakeNode pfood = BuyNode();
pSnakeNode cur = ps->_psnake;
pfood->y = rand() % 25 + 1;
do
{
//0-56
pfood->x = rand() % 55 + 2;
} while (pfood->x % 2 != 0);
while (cur)
{
if (cur->x == pfood->x && cur->y == pfood->y)
{
CreateFood(ps);
return;
}
cur = cur->next;
}
ps->_pFood = pfood;
SetPos(pfood->x, pfood->y);
printf(FOOD);
//SetPos(60, 27);
}
//創建貪喫蛇
void GameStart(pSnake ps)
{
//打印歡迎界面
WelcomeToGame();
//創建地圖
CreateMap();
//初始化蛇
InitSnake(ps);
//初始化食物
CreateFood(ps);
ps->_AddScore = 10;
ps->_TotalScore = 0;
ps->_Dir = RIGHT;
ps->_SleepTime = 200;
ps->_Status = OK;
}
//暫停遊戲
void Pause()
{
while (1)
{
Sleep(100);
if (GetAsyncKeyState(VK_SPACE))
break;
}
}
//判斷下一步是不是食物
int NextHasFood(pSnakeNode pn, pSnakeNode pf)
{
return ((pn->x == pf->x) && (pn->y == pf->y));
}
//喫食物
void EatFood(pSnakeNode pn, pSnake ps)
{
pSnakeNode cur = NULL;
pn->next = ps->_psnake;
ps->_psnake = pn;
cur = ps->_psnake;
while (cur != NULL)
{
SetPos(cur->x, cur->y);
printf(FOOD);
cur = cur->next;
}
ps->_TotalScore += ps->_AddScore;
CreateFood(ps);
}
//沒有食物喫
void NoFood(pSnakeNode pn, pSnake ps)
{
pSnakeNode cur = NULL;
pn->next = ps->_psnake;
ps->_psnake = pn;
cur = ps->_psnake;
while (cur->next->next != NULL)
{
SetPos(cur->x, cur->y);
printf(FOOD);
cur = cur->next;
}
SetPos(cur->next->x, cur->next->y);
printf(" ");
free(cur->next);
cur->next = NULL;
}
//蛇的移動
void SnakeMove(pSnake ps)
{
pSnakeNode pNextNode = BuyNode();
switch (ps->_Dir)
{
case UP:
pNextNode->x = ps->_psnake->x;
pNextNode->y = ps->_psnake->y-1;
if (NextHasFood(pNextNode, ps->_pFood))
{
EatFood(pNextNode, ps);
}
else
{
NoFood(pNextNode, ps);
}
break;
case DOWN:
pNextNode->x = ps->_psnake->x;
pNextNode->y = ps->_psnake->y+1;
if (NextHasFood(pNextNode, ps->_pFood))
{
EatFood(pNextNode, ps);
}
else
{
NoFood(pNextNode, ps);
}
break;
case LEFT:
pNextNode->x = ps->_psnake->x-2;
pNextNode->y = ps->_psnake->y;
if (NextHasFood(pNextNode, ps->_pFood))
{
EatFood(pNextNode, ps);
}
else
{
NoFood(pNextNode, ps);
}
break;
case RIGHT:
pNextNode->x = ps->_psnake->x+2;
pNextNode->y = ps->_psnake->y;
if (NextHasFood(pNextNode, ps->_pFood))
{
EatFood(pNextNode, ps);
}
else
{
NoFood(pNextNode, ps);
}
break;
}
}
//撞牆
int KillByWall(pSnake ps)
{
if ((ps->_psnake->x == 0)
|| (ps->_psnake->x == 58)
|| (ps->_psnake->y == 0)
|| (ps->_psnake->y == 27))
{
ps->_Status = KILL_BY_WALL;
}
}
//撞到自身
int KillBySelf(pSnake ps)
{
pSnakeNode pNext = ps->_psnake->next;
while (pNext != NULL)
{
if (pNext->x == ps->_psnake->x && pNext->y == ps->_psnake->y)
{
ps->_Status = KILL_BY_SELF;
return;
}
pNext = pNext->next;
}
}
//打印幫助信息
PrintHelpInfo(pSnake ps)
{
SetPos(61, 6);
printf("總分 = %d", ps->_TotalScore);
SetPos(61, 8);
printf("蛇移動的時間 = %d", ps->_SleepTime);
SetPos(61, 10);
printf("加減速變化的分數 = %d ", ps->_AddScore);
SetPos(61, 15);
printf("用 ↑ ↓ ← → 來控制蛇的移動. F1爲加速.F2爲減速.");
SetPos(61, 17);
printf("空格暫停遊戲");
SetPos(61, 19);
printf("按 ESC鍵 退出遊戲");
}
//遊戲開始跑起來
void GameRun(pSnake ps)
{
do
{
PrintHelpInfo(ps);//幫助提示
//確定方向
if (GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN)
ps->_Dir = UP;
else if(GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP)
ps->_Dir = DOWN;
else if (GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT)
ps->_Dir = LEFT;
else if (GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT)
ps->_Dir = RIGHT;
else if (GetAsyncKeyState(VK_SPACE))
{
//暫停遊戲
Pause();
}
else if (GetAsyncKeyState(VK_ESCAPE))
{
//結束遊戲
ps->_Status = NORMAL_END;
break;
}
else if (GetAsyncKeyState(VK_F1))
{
//加速
if (ps->_SleepTime >= 40)
{
ps->_SleepTime -= 20;
ps->_AddScore += 2;
}
}
else if (GetAsyncKeyState(VK_F2))
{
//減速
if (ps->_SleepTime < 300)
{
ps->_SleepTime += 20;
ps->_AddScore -= 2;
}
}
Sleep(ps->_SleepTime);
//蛇的移動
SnakeMove(ps);
KillByWall(ps);
KillBySelf(ps);
} while (ps->_Status == OK);
}
//結束遊戲
void GameEnd(pSnake ps)
{
pSnakeNode del;
pSnakeNode cur = ps->_psnake;
SetPos(20, 12);
switch(ps->_Status)
{
case NORMAL_END:
printf("遊戲正常結束!");
SetPos(61, 27);
break;
case KILL_BY_WALL:
printf("你撞牆了!");
SetPos(61, 27);
break;
case KILL_BY_SELF:
printf("你把自己咬了!");
SetPos(61, 27);
break;
}
while (cur)
{
del = cur;
cur = cur->next;
free(del);
del = NULL;
}
}
/***********************************************/
//test.c
#include "Snake.h"
void test()
{
Snake snake = { 0 };
srand((unsigned int)time(NULL));
GameStart(&snake);//創建貪喫蛇
GameRun(&snake);
GameEnd(&snake);
}
int main()
{
test();
system("pause");
return 0;
}
簡易的貪喫蛇小遊戲
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.