纯c语言写的小游戏,本人才疏学浅,代码有很多不足,仅供给初学者参考。
头文件(snack.h)
#ifndef __SNACK_H__
#define __SNACK_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
#define WALL "▓"
#define SNACK "●"
#define FOOD "★"
#define INIT_X 10
#define INIT_Y 20
#define INIT_LONG 4
enum Direction
{
UP = 1, //上
DOWN, //下
LEFT, //左
RIGHT //右
};
typedef enum GameStatus //游戏状态
{
OK, //正常
NORMAL_END, //正常结束
KILL_BY_WALL, //撞墙
KILL_BY_SELF //咬到自己
};
typedef struct SnackNode //表示蛇身节点
{
int x;
int y;
struct SnackNode* _pNext;
}SnackNode, *pSnackNode;
typedef struct Snack
{
pSnackNode _psnack;//位置
pSnackNode _pfood;//食物位置
int _TotalScore; //得分
int _AddScore; //增加分数
int _SleepTime;
enum Direction _Dir;
enum GameStatus _Status;
}Snack, *pSnack;
void setpos (int x, int y);//控制光标位置
int WelcomeToGame_1 ();//欢迎界面1
void WelcomeToGame_2 ();//欢迎界面2
void CreateMap ();//初始化地图
void InitSnack (pSnack ps);//初始化蛇
void CreateFood (pSnack ps);//打印食物
void GameStart (pSnack ps);//游戏开始
void SnackMove(pSnack ps);//蛇移动
void Killed_By_Wall(pSnack ps);//撞墙死
void Collide_Self(pSnack ps);咬到自己死
void AboutGame (pSnack ps);//游戏说明
int color(int x); //改变字体颜色
int GetLength (pSnack ps);//获取蛇的长度
void Exit_Game(pSnack snack);//退出游戏
#endif
主要函数(main.c)
#include "snack.h"
void setpos (int x, int y)
{
COORD pos = {0};
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), pos);
}
int WelcomeToGame_1 ()
{
int i = 0;
system ("mode con cols=100 lines=30"); //设置界面大小
system ("title 贪吃蛇");
setpos (38, 8);
color (11);
printf ("贪吃蛇xiao游戏\n");
setpos (38, 13);
printf ("1、开始游戏");
setpos (38, 15);
printf ("2、退出");
setpos (88, 28);
printf ("2018/08/26");
setpos (38, 17);
printf ("请选择:");
scanf ("%d", &i);
system ("cls");
return i;
}
void WelcomeToGame_2 ()
{
color (11);
setpos (32, 11);
printf ("提示:");
setpos (35, 13);
printf ("用↑↓←→控制蛇的移动方向,f1加速,f2减速");
setpos (35, 15);
printf ("速度越快,得分越多");
setpos (35, 28);
printf ("LOADING...");
Sleep (2500);
system ("cls");
}
void CreateMap ()
{
int i = 0;
color (15);
//上边界
for (i=0; i<=58; i+=2)
{
setpos (i, 0);
printf (WALL);
}
//左边界
for (i=0; i<30; i++)
{
setpos (0, i);
printf (WALL);
}
//下边界
for (i=2; i<=58; i+=2)
{
setpos (i, 29);
printf (WALL);
}
//右边界
for (i=1; i<29; i++)
{
setpos (58, i);
printf (WALL);
}
}
pSnackNode BuySnackNode ()
{
pSnackNode cur = (pSnackNode)malloc (sizeof (SnackNode));
if (cur == NULL)
{
printf ("创建蛇身节点出错,游戏结束");
exit (1);
}
cur ->x = 0;
cur ->y = 0;
cur ->_pNext = NULL;
return cur;
}
void print_snack(pSnack ps)
{
pSnackNode cur = ps->_psnack;
while (cur)
{
setpos (cur->x, cur->y);
color (14);
printf (SNACK);
cur = cur->_pNext;
}
color (12);
}
void InitSnack (pSnack ps)
{
int i = INIT_LONG;
pSnackNode cur = NULL;
pSnackNode first = (pSnackNode)malloc (sizeof (SnackNode));
if (first == NULL)
{
printf ("创建蛇头节点出错,游戏结束");
exit (1);
}
first->x = INIT_X;
first->y = INIT_Y;
first->_pNext = NULL;
while (--i)
{
cur = BuySnackNode ();
cur ->x = first->x + 2;
cur->y = first->y ;
cur->_pNext = first;
first = cur;
}
ps->_Dir = RIGHT;
ps->_psnack = first;
ps->_AddScore = 10;
ps->_SleepTime = 200;
ps->_TotalScore = 0;
ps->_Status = OK;
print_snack(ps);
}
void CreateFood (pSnack ps)
{
int x = 0;
int y = 0;
int col = 0;
pSnackNode snack = ps ->_psnack ;
pSnackNode food = BuySnackNode();
y = rand()% 28 + 1;
do
{
x = rand ()% 55 + 2;
}while ((x%2) != 0);
food ->x = x;
food ->y = y;
while (snack)
{
if (food->x == snack->x && food->y == snack->y)
{
break;
}
else
{
snack = snack->_pNext;
}
}
if (snack == NULL)
{
ps->_pfood = food;
setpos (food->x, food->y);
col = rand() % 15+1;
color (col);
printf (FOOD);
}
else
{
CreateFood (ps);
}
}
void Killed_by_Self(pSnack ps)
{
pSnackNode cur = ps->_psnack->_pNext;
while (cur != NULL)
{
if (cur->x == ps->_psnack ->x && cur->y == ps->_psnack ->y)
{
setpos (18, 21);
printf ("很遗憾, 你把自己给咬死了!!!\n");
ps->_Status = KILL_BY_SELF;
break;
}
cur = cur->_pNext;
}
}
void Killed_By_Wall(pSnack ps)
{
if (ps->_psnack ->x == 0 || ps->_psnack ->x == 58 || ps->_psnack->y == 29 || ps->_psnack ->y == 0)
{
setpos (18, 21);
printf ("很遗憾,你撞墙了!!!\n");
ps->_Status = KILL_BY_WALL;
}
}
void GameStart (pSnack ps)
{
int i = 0;
do
{
AboutGame (ps);
//检测是否从键盘上按下一个值
if(GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN) //上
{
ps->_Dir = UP;
}
if(GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP) //下
{
ps->_Dir = DOWN;
}
if(GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT) //左
{
ps->_Dir = LEFT;
}
if(GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT) //右
{
ps->_Dir = RIGHT;
}
if(GetAsyncKeyState(VK_ESCAPE))//退出
{
ps->_Status = NORMAL_END;
}
if(GetAsyncKeyState(VK_F1))//加速
{
if(ps->_SleepTime > 50)
{
ps->_SleepTime -= 30;
}
ps->_AddScore += 5;
}
if(GetAsyncKeyState(VK_F2))//减速
{
if(ps->_SleepTime <= 500)
{
ps->_SleepTime += 50;
if(ps->_AddScore != 6)
ps->_AddScore -= 6;
else
ps->_AddScore = 6;
}
}
if(GetAsyncKeyState(VK_SPACE))//暂停
{
while(1)
{
Sleep(100);
if(GetAsyncKeyState(VK_SPACE))
{
break;
}
}
}
Sleep(ps->_SleepTime);
SnackMove(ps);
Killed_By_Wall(ps);
Killed_by_Self(ps);
}while (ps->_Status == OK);
setpos (18, 23);
printf ("请稍后...");
Sleep (2500);
system ("cls");
setpos (45, 10);
printf ("GAME OVER");
setpos (45, 15);
printf ("总分:%d", ps->_TotalScore);
setpos (80, 28);
system ("pause");
}
void Eat_Food(pSnack ps)
{
//分数增加
ps->_TotalScore += ps->_AddScore;
//吃掉食物后吧食物销毁
free (ps->_pfood );
ps->_pfood = NULL;
//打印蛇
setpos (ps->_psnack ->x, ps->_psnack ->y);
print_snack (ps);
//在生成新的食物
CreateFood (ps);
//每吃一个食物,速度增加
if (ps->_SleepTime >= 100)
{
ps->_SleepTime -= 10;
ps->_AddScore += 5;
}
}
void Not_Eat_food(pSnack ps) // 没有吃东西,长度不变,只需要把最后一个节点处打印成空格,在销毁掉最后一个节点
{
pSnackNode cur = ps->_psnack;
while (cur->_pNext ->_pNext != NULL)
{
cur = cur->_pNext;
}
setpos (cur->_pNext ->x, cur->_pNext->y);
printf (" ");
free (cur->_pNext);
cur->_pNext = NULL;
//打印蛇
setpos (ps->_psnack->x, ps->_psnack->y);
print_snack (ps);
}
void SnackMove (pSnack ps)
{
pSnackNode cur = BuySnackNode ();
switch (ps->_Dir)
{
case UP:
{
cur->x = ps->_psnack ->x;
cur->y = ps->_psnack ->y-1;
cur->_pNext = ps->_psnack ;
ps->_psnack = cur;
if (cur->x == ps ->_pfood ->x && cur->y == ps->_pfood->y)
{
Eat_Food(ps);
}
else
{
Not_Eat_food(ps);
}
}
break;
case DOWN:
{
cur->x = ps->_psnack ->x;
cur->y = ps->_psnack ->y+1;
cur->_pNext = ps->_psnack ;
ps->_psnack = cur;
if (cur->x == ps ->_pfood ->x && cur->y == ps->_pfood->y)
{
Eat_Food(ps);
}
else
{
Not_Eat_food(ps);
}
}
break;
case LEFT:
{
cur->x = ps->_psnack ->x-2;
cur->y = ps->_psnack ->y;
cur->_pNext = ps->_psnack ;
ps->_psnack = cur;
if (cur->x == ps ->_pfood ->x && cur->y == ps->_pfood->y)
{
Eat_Food(ps);
}
else
{
Not_Eat_food(ps);
}
}
break;
case RIGHT:
{
cur->x = ps->_psnack ->x+2;
cur->y = ps->_psnack ->y;
cur->_pNext = ps->_psnack ;
ps->_psnack = cur;
if (cur->x == ps ->_pfood ->x && cur->y == ps->_pfood->y)
{
Eat_Food(ps);
}
else
{
Not_Eat_food(ps);
}
}
break;
}
}
void AboutGame (pSnack ps)
{
color (2);
setpos (65, 9);
printf ("游戏说明:");
setpos (68, 11);
printf ("控制方向:↑↓←→");
setpos (68, 13);
printf ("暂停:空格");
setpos (68, 15);
printf ("退出游戏:esc");
setpos (68, 17);
printf ("f1加速,f2减速");
setpos (68, 19);
printf ("分数:+%d", ps->_AddScore);
color (11);
}
int color(int c) //改变字体颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色
return 0;
}
void Exit_Game(pSnack ps)
{
pSnackNode cur = ps->_psnack;
pSnackNode pre = NULL;
while (cur != NULL)
{
pre = cur;
cur = cur->_pNext;
free (pre);
pre = NULL;
}
}
功能测试test.c
#include "snack.h"
void test ()
{
int i = 0;
int j = 0;
Snack snack;
srand ((unsigned)time(NULL));
do
{
//开始界面
i = WelcomeToGame_1 ()-2;
switch (i)
{
case -1:
{
WelcomeToGame_2 ();
//构造地图(边界)
CreateMap ();
//初始化蛇
InitSnack (&snack);
//构造食物
CreateFood (&snack);
//开始游戏
GameStart (&snack);
}
break;
case 0:
setpos (38, 15);
printf ("退出游戏!!\n");
Exit_Game(&snack);
break;
default :
setpos (38, 15);
printf ("你的选择有误,2s后请重新选择...");
Sleep (2000);
break;
}
}while (i);
setpos (66, 28);
system ("pause");
}
void test_food ()
{
int i = 0;
Snack snack;
WelcomeToGame_2 ();
//构造地图(边界)
CreateMap ();
//初始化蛇
InitSnack (&snack);
//构造食物
for (; i<100; ++i)
{
CreateFood (&snack);
Sleep (500);
}
}
int main()
{
test ();
return 0;
}