学了C语言的同学们快来写一个属于自己的贪吃蛇小游戏吧~
我的这个贪吃蛇是最基本的几个功能实现,有了这几个基本的框架,我们可以在后期根据自己的想法来扩展它的功能。下面是我的一些扩展的想法(后面慢慢实现):
1.给界面加上颜色
2.添加一项可以记录最高成绩的功能
3.实现两条蛇竞争的双人贪吃蛇
4.贪吃蛇大作战
Snake.h
#ifndef __Snake__H__
#define __Snake__H__
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#define INIT_X 20
#define INIT_Y 10
#define FOOD "★"//■★□●▼▲♡☞☏⊙◎☻♧♂♀☼▧▨
#define WALL "■"
#define SNAKE "●"
/*
VK_ESCAPE ESC键
VK_RETURN回车键
VK_TABTAB键
VK_SPACE空格键
*/
//方向
enum Dir
{
_UP,//上
_DOWN,//下
_LEFT,//左
_RIGHT//右
};
//蛇的状态
enum Status
{
_OK,//活
_OKEND,//死
_KILLBYSELF,//撞到自己而死
_KILLBYWALL//撞到墙而死
};
typedef struct Snakenode
{
struct Snakenode* _next;
int x;
int y;
}Snakenode;
typedef struct Snake
{
Snakenode* _Snakebody;//蛇的身体
Snakenode* _Snakefood;//蛇的食物
int _TotalScore;//总得分
int _AddScore;//每次加的分
int _Time;//速度
enum Dir _Dir;//蛇走的方向
enum Status Status;//蛇的状态
}Snake;
Snakenode* Buy_Node();
void Set_Pos(size_t x, size_t y);
void Welcom_To_Game();
void Init(Snake* snake);
void CreatMap();
void ScoreAndTips(Snake* snake);
void CreatFood(Snake* snake);
void Game_Start(Snake* snake);
void Game_Run(Snake* snake);
void Game_End();
#endif
Snake.c
#define _CRT_SECURE_NO_WARNINGS
#include"Snake.h"
//创建一个结点
Snakenode* Buy_Node()
{
Snakenode *snakebody;
snakebody = (Snakenode*)malloc(sizeof(Snakenode));
if (snakebody == NULL)
{
perror("error!\n");
exit(0);
}
snakebody->_next = NULL;
return snakebody;
}
//设置光标的位置
void Set_Pos(int x, int y)
{
COORD pos = { 0 };
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取这台机器的光标
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);//设置光标到pos的位置
}
//介绍游戏的游戏界面
void Welcom_To_Game()
{
system("mode con cols=100 lines=30");//设置游戏界面窗口的大小(横100,竖30)
//横 竖
Set_Pos(35, 15);
printf("欢迎来到贪吃蛇小游戏");
Set_Pos(20, 17);
printf("用 ↑.↓.←.→分别控制蛇的移动,F1为加速,F2为减速。");
Set_Pos(35, 19);
printf("加速将能得到更高的分数。");
Set_Pos(35, 29);
system("pause");
system("cls");
}
//初始化蛇
void Init(Snake* snake)
{
Snakenode *node1,*next;
int i = 0;
node1 = Buy_Node();
node1->x = INIT_X;
node1->y = INIT_Y;
node1->_next = NULL;
//创建一个蛇身为4的蛇(头插法)
for (i = 1; i < 4; i++)
{
next = Buy_Node();
next->x = node1->x+2;
next->y = node1->y;
next->_next = node1;
node1= next;
}
//打印蛇身
next = node1;
for (i = 1; i <= 4; i++)
{
Set_Pos(next->x,next->y);
printf(SNAKE);
next = next->_next;
}
snake->_Snakebody = node1;
}
//初始化墙
void CreatMap()
{
int i, j;
//上下
for (i = 0; i <= 58; i += 2)
{
Set_Pos(i,0);
printf(WALL);
Set_Pos(i,29);
printf(WALL);
}
//左右
for (j = 1; j <= 28; j++)
{
Set_Pos(0,j);
printf(WALL);
Set_Pos(58,j);
printf(WALL);
}
}
//初始化食物
void CreatFood(Snake* snake)
{
Snakenode* food,*cur=snake->_Snakebody;
food = Buy_Node();
do
{
food->x = (rand() % 55) + 2;
} while ((food->x)%2 != 0);
food->y = (rand() % 28) + 1;
while (cur)
{
if ((food->x == cur->x) && (food->y == cur->y))
{
CreatFood(snake);
return;
}
cur = cur->_next;
}
snake->_Snakefood = food;
Set_Pos(snake->_Snakefood->x,snake->_Snakefood->y);
printf(FOOD);
}
//判断有没有吃到食物
int If_Food(Snakenode* food,Snakenode* new)
{
if ((food->x == new->x)&&(food->y == new->y))
{
return 1;
}
else
{
return 0;
}
}
//吃到食物后移动
void Eat_Food(Snake* snake, Snakenode* new)
{
new->_next = snake->_Snakebody;
snake->_Snakebody = new;
Set_Pos(snake->_Snakebody->x, snake->_Snakebody->y);
printf(SNAKE);
CreatFood(snake);
}
void Not_Eatfood(Snake* snake, Snakenode* new)
{
Snakenode*cur;
new->_next = snake->_Snakebody;
snake->_Snakebody = new;
cur = snake->_Snakebody;
while (cur->_next->_next)
{
Set_Pos(cur->x, cur->y);
printf(SNAKE);
cur = cur->_next;
}
Set_Pos(cur->x, cur->y);
printf(SNAKE);
Set_Pos(cur->_next->x, cur->_next->y);
printf(" ");
free(cur->_next);
cur->_next = NULL;
}
//蛇开始移动
void Snake_Move(Snake* snake)
{
Snakenode *new = Buy_Node();
switch (snake->_Dir)
{
case _UP:
{
new->x = snake->_Snakebody->x;
new->y = snake->_Snakebody->y-1;
if (If_Food(snake->_Snakefood, new))
{
Eat_Food(snake,new);
snake->_TotalScore += snake->_AddScore;
//system("cls");
ScoreAndTips(snake);
}
else
{
Not_Eatfood(snake, new);
}
}
break;
case _DOWN :
{
new->x = snake->_Snakebody->x;
new->y = snake->_Snakebody->y+1;
if (If_Food(snake->_Snakefood, new))
{
Eat_Food(snake, new);
snake->_TotalScore += snake->_AddScore;
// system("cls");
ScoreAndTips(snake);
}
else
{
Not_Eatfood(snake, new);
}
}
break;
case _LEFT:
{
new->x = snake->_Snakebody->x-2;
new->y = snake->_Snakebody->y;
if (If_Food(snake->_Snakefood, new))
{
Eat_Food(snake, new);
snake->_TotalScore += snake->_AddScore;
//system("cls");
ScoreAndTips(snake);
}
else
{
Not_Eatfood(snake, new);
}
}
break;
case _RIGHT:
{
new->x = snake->_Snakebody->x+2;
new->y = snake->_Snakebody->y;
if (If_Food(snake->_Snakefood, new))
{
Eat_Food(snake, new);
snake->_TotalScore += snake->_AddScore;
//system("cls");
ScoreAndTips(snake);
}
else
{
Not_Eatfood(snake, new);
}
}
break;
}
}
//按空格键暂停
void Pause()
{
while (1)
{
Sleep(100);
if (GetAsyncKeyState(VK_SPACE))
{
break;
}
}
}
//蛇撞到墙而死
void KillByWall(Snake* snake)
{
int x = snake->_Snakebody->x;
int y = snake->_Snakebody->y;
if ((y == 0)||(y==29)||(x==0)||(x==58))
{
snake->Status = _KILLBYWALL;
}
}
//蛇撞到自己而死
void KillBySelf(Snake* snake)
{
Snakenode* cur = snake->_Snakebody->_next;
int x = snake->_Snakebody->x;
int y = snake->_Snakebody->y;
while (cur)
{
if ((cur->x == x)&&(cur->y == y))
{
snake->Status = _KILLBYSELF;
return;
}
cur = cur->_next;
}
}
//加减分数
void ScoreAndTips(Snake* snake)
{
Set_Pos(64,10);
printf("得分:%d ", snake->_TotalScore);
Set_Pos(64, 11);
printf("小 提 示");
Set_Pos(64,12);
printf("---------------------");
Set_Pos(64, 13);
printf("---------------------");
Set_Pos(64, 14);
printf("每个食物得分:%d分", snake->_AddScore);
Set_Pos(64, 15);
printf("不能穿墙,不能咬到自己");
Set_Pos(64, 16);
printf("用↑↓←→分别控制蛇的移动");
Set_Pos(64, 17);
printf("F1 为加速,F2 为减速");
Set_Pos(64, 18);
printf("space:暂停游戏");
Set_Pos(64, 19);
printf("ESC:退出游戏");
}
//游戏中...
void Game_Run(Snake* snake)
{
do{
Snake_Move(snake);
Sleep(snake->_Time);
KillByWall(snake);
KillBySelf(snake);
if (GetAsyncKeyState(VK_UP) && snake->_Dir != _DOWN){
snake->_Dir = _UP;
}
else if (GetAsyncKeyState(VK_LEFT) && snake->_Dir != _RIGHT){
snake->_Dir = _LEFT;
}
else if (GetAsyncKeyState(VK_RIGHT) && snake->_Dir != _LEFT){
snake->_Dir = _RIGHT;
}
else if (GetAsyncKeyState(VK_DOWN) && snake->_Dir != _UP){
snake->_Dir = _DOWN;
}
else if (GetAsyncKeyState(VK_SPACE)){
Pause();
}
else if (GetAsyncKeyState(VK_F1)){
if (snake->_Time <=1000 && snake->_TotalScore >= 0)
{
snake->_Time += 100;
snake->_AddScore -= 1;
}
}
else if (GetAsyncKeyState(VK_F2)){
if (snake->_Time >=10 )
{
snake->_Time -= 100;
snake->_AddScore += 1;
}
}
else if (GetAsyncKeyState(VK_ESCAPE)){
snake->Status = _OKEND;
}
} while (snake->Status == _OK);
}
//开始游戏
void Game_Start(Snake* snake)
{
Welcom_To_Game();
CreatMap();
Init(snake);
CreatFood(snake);
//Set_Pos(62,15);
snake->Status = _OK;
snake->_AddScore = 10;
snake->_Dir = _UP;
snake->_Time = 500;
snake->_TotalScore = 0;
ScoreAndTips(snake);
}
//游戏结束
void Game_End()
{
system("cls");
Set_Pos(35, 15);
printf("游戏结束\n");
Set_Pos(35, 29);
system("pause");
}
main.c
#define _CRT_SECURE_NO_WARNINGS
#include"Snake.h"
void test()
{
Snake snake = { 0 };
//设置食物的时间种子
srand((unsigned)time(NULL));
//开始游戏
Game_Start(&snake);
//游戏中....
Game_Run(&snake);
Game_End();
}
int main()
{
test();
//COORD pos = { 0 };
//HANDLE handle = NULL;
//system("mode con cols=100 lines=30");
//handle = GetStdHandle(STD_OUTPUT_HANDLE);
//pos.X = 50;
//pos.Y = 15;
//SetConsoleCursorPosition(handle, pos);//
//printf("hehe\n");
system("pause");
return 0;
}