在Windows环境下的C语言小项目——贪吃蛇
#include
#include
#include
#include
#define U 1
#define D 2
#define L 3
#define R 4 // status of snake
typedef struct SNAKE //蛇身的一个节点
{
int x;
int y;
struct SNAKE *next;
} snake;
// global variable
int score = 0, add = 10; //总得分与每次吃食物得分
int status, sleeptime = 200; //每次运行时间间隔
snake *head, *food; //蛇头指针,食物指针
snake *q; //遍历蛇的时候用到的临时指针
int endGamestatus = 0; //游戏结束的情况,1:撞到墙;2.咬到自己;3:主动退出游戏
void Pos();
void CreatMap();
void InitSnake();
int BiteSelf();
void CreateFood();
void CantCrossWall();
void SnakeMove();
void Pause();
void RunGame();
void InitGame();
void EndGame();
void GameStart();
int main() //主函数
{
GameStart();
RunGame();
return 1;
}
void Pos(int x, int y) //设置光标位置
{
COORD pos;
HANDLE hOutput;
pos.X = x;
pos.Y = y;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE); //返回标准输入、输出
SetConsoleCursorPosition(hOutput, pos);
}
void CreatMap() //创建地图
{
int i;
for (i = 0; i < 58; i += 2) //打印上下边框
{
Pos(i, 0);
printf("■"); //一个方块占两个位置
Pos(i, 26);
printf("■");
}
for (i = 1; i < 26; i++) //打印左右边框
{
Pos(0, i);
printf("■");
Pos(56, i);
printf("■");
}
}
void InitSnake() //初始化蛇身
{
snake *tail;
int i;
tail = (snake *)malloc(sizeof(snake)); //从蛇尾开始,头插法,以x,y设定开始的位置
tail->x = 24;
tail->y = 5;
tail->next = NULL;
for (i = 1; i <= 4; i++) //初始长度为5
{
head = (snake *)malloc(sizeof(snake));
head->next = tail;
head->x = 24 + 2 * i; //修改
head->y = 5;
tail = head;
}
while (tail != NULL) //从头到尾,输出蛇身
{
Pos(tail->x, tail->y);
printf("■");
tail = tail->next;
}
}
int BiteSelf() //判断是否咬到了自己
{
snake *self;
self = head->next;
while (self != NULL)
{
if (self->x == head->x && self->y == head->y)
{
return 1;
}
self = self->next;
}
return 0;
}
void CreateFood() //随机出现食物
{
snake *food_1;
srand((unsigned)time(NULL)); //为了防止每次产生的随机数相同,种子设置为time
food_1 = (snake *)malloc(sizeof(snake));
while (1)
{
food_1->x = 3;
while ((food_1->x % 2) != 0) //保证食物能与蛇头对其
{
food_1->x = rand() % 52 + 2;
}
food_1->y = rand() % 24 + 1;
q = head;
while (q->next != NULL)
{
if (q->x == food_1->x && q->y == food_1->y)
{ //判断刷新点与蛇身重合
break;
}
q = q->next;
}
if(q->next ==NULL) break;
}
Pos(food_1->x, food_1->y);
food = food_1;
//*****************************************************
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
WORD wOldColorAttrs;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
// Save the current color
GetConsoleScreenBufferInfo(h, &csbiInfo);
wOldColorAttrs = csbiInfo.wAttributes;
// Set the new color
SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_BLUE); //| BACKGROUND_GREEN
printf("●");
SetConsoleTextAttribute(h, wOldColorAttrs);
//****************************************************
// printf("■");
}
void CantCrossWall() //不能穿墙
{
if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
{
endGamestatus = 1;
EndGame();
}
}
void SnakeMove() //蛇前进,上U 下D 左L 右R
{
snake *nexthead;
CantCrossWall();
nexthead = (snake *)malloc(sizeof(snake));
if (status == U)
{
nexthead->x = head->x;
nexthead->y = head->y - 1;
if (nexthead->x == food->x && nexthead->y == food->y)
{
nexthead->next = head;
head = nexthead;
q = head;
while (q != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score = score + add;
CreateFood();
}
else //如果没有食物
{
nexthead->next = head;
head = nexthead;
q = head;
while (q->next->next != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = NULL;
}
}
if (status == D)
{
nexthead->x = head->x;
nexthead->y = head->y + 1;
if (nexthead->x == food->x && nexthead->y == food->y)
{
nexthead->next = head;
head = nexthead;
q = head;
while (q != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score = score + add;
CreateFood();
}
else //如果没有食物
{
nexthead->next = head;
head = nexthead;
q = head;
while (q->next->next != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = NULL;
}
}
if (status == L)
{
nexthead->x = head->x - 2;
nexthead->y = head->y;
if (nexthead->x == food->x && nexthead->y == food->y)
{
nexthead->next = head;
head = nexthead;
q = head;
while (q != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score = score + add;
CreateFood();
}
else //如果没有食物
{
nexthead->next = head;
head = nexthead;
q = head;
while (q->next->next != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = NULL;
}
}
if (status == R)
{
nexthead->x = head->x + 2;
nexthead->y = head->y;
if (nexthead->x == food->x && nexthead->y == food->y)
{
nexthead->next = head;
head = nexthead;
q = head;
while (q != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
score = score + add;
CreateFood();
}
else //如果没有食物
{
nexthead->next = head;
head = nexthead;
q = head;
while (q->next->next != NULL)
{
Pos(q->x, q->y);
printf("■");
q = q->next;
}
Pos(q->next->x, q->next->y);
printf(" ");
free(q->next);
q->next = NULL;
}
}
if (BiteSelf() == 1)
{
endGamestatus = 2;
EndGame();
}
}
void Pause() //暂停
{
while (1)
{
Sleep(300);
if (GetAsyncKeyState(VK_SPACE))
{
break;
}
}
}
void RunGame() //控制游戏
{
Pos(64, 14);
printf("================================");
Pos(64, 15);
printf("| 不能穿墙,不能咬到自己 |");
Pos(64, 16);
printf("|用↑,↓,→,←分别控制蛇的移动 |");
Pos(64, 17);
printf("| F1为加速,F2为减速 |");
Pos(64, 18);
printf("|ESC:退出游戏,spare:暂停游戏. |");
Pos(64, 19);
printf("================================");
status = R;
while (1)
{
Pos(64, 10);
printf("得分:%d", score);
Pos(64, 11);
printf("每个食物得分为:%d分", add);
if (GetAsyncKeyState(VK_UP) && status != D)
{
status = U;
}
else if (GetAsyncKeyState(VK_DOWN) && status != U)
{
status = D;
}
else if (GetAsyncKeyState(VK_LEFT) && status != R)
{
status = L;
}
else if (GetAsyncKeyState(VK_RIGHT) && status != L)
{
status = R;
}
else if (GetAsyncKeyState(VK_SPACE))
{
Pause();
}
else if (GetAsyncKeyState(VK_ESCAPE))
{
endGamestatus = 3;
break;
}
else if (GetAsyncKeyState(VK_F1))
{
if (sleeptime >= 50)
{
sleeptime -= 30;
add += 2;
if (sleeptime == 320)
add = 2;
}
}
else if (GetAsyncKeyState(VK_F2))
{
if (sleeptime < 350)
{
sleeptime += 30;
add -= 2;
if (sleeptime == 350)
add = 1;
}
}
Sleep(sleeptime);
SnakeMove();
}
}
void InitGame() //开始界面
{
Pos(30, 5);
printf("欢迎");
// Pos(40,25);
system("pause");
system("cls");
Pos(25, 12);
printf("↑↓←→控制蛇的移动,F1 为加速,F2 为减速nn");
printf("n");
system("pause");
system("cls");
}
void EndGame() //结束游戏
{
system("cls");
Pos(24, 12);
if (endGamestatus == 1)
{
printf("对不起,您撞到墙了。Game Over");
}
else if (endGamestatus == 2)
{
printf("对不起,您咬到自己了。游戏结束.");
}
else if (endGamestatus == 3)
{
printf("您的已经结束了游戏。");
}
Pos(24, 13);
printf("您的得分是%dn", score);
while (getchar() != 'y')
printf("close?[y]");
exit(0);
}
void GameStart() //游戏初始化
{
system("mode con cols=100 lines=30");
InitGame();
CreatMap();
InitSnake();
CreateFood();
}