这学期课程设计用c语言编写了windows环境下的贪吃蛇,多次修改后形成了暂时性的最终版,功能有等级选择,游戏说明,排行榜等等,以下是截图和部分源代码。
使用到的头文件、变量和函数
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 100
#define ESC 27
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define ENTER 13
#define BRICK "■"
enum direction//蛇头方向
{
left,
right,
up,
down
};
typedef struct food//食物
{
int x;
int y;
}Food;
typedef struct Node//蛇身的节点
{
int x;
int y;
}Sna;
typedef struct SnakeBody//蛇的身体
{
Sna snakenode;
struct SnakeBody *next;
}SnakeNode, *SnakeList;
typedef struct SnakeData//蛇本身数据,体长和头的方向
{
int snakelen;
enum direction dir;
}SnaData;
int SPEECH=150;//速度
int len; //地图长
int wide; //地图宽
int map[N][N]; //地图数组
int map2[N][N];//真实地图数组
int Score=0;//分数
int mark=0;//判断要不要清除蛇尾节点
int stop=1;//游戏停止判断
int level=1;//等级
int HighScore[10][5];//排行榜分数
SnakeData Sdata;//记录蛇本身数据
SnakeNode *tail;//记录蛇尾节点
SnakeList S;//蛇
Food F;//健康的食物
Food B;//腐烂的食物
int q=1; //表示当前菜单指针所在位置
int p=1; //难度指针所在位置
int c;
int start,end,ftime;
int fx,fy;
int temp;
void color(unsigned short c);
void gotoxy(int x,int y);
void HideCursor();
void readmap(int level);//读取地图
void drawmap();//画地图
void Initfood(SnakeList S,Food *F,Food *B,int a);//建立食物
void DrawFood(Food *F,int a);//画食物
int JudgeFood(SnakeList S,Food *F,Food *B);//判断食物座标合法性
void Initsnake(SnakeList *S);//初始化蛇
void Creatsnake(SnakeList S);//建立蛇
void InitNode(SnakeList S,int x,int y);//建立蛇节点
void Drawsnake(SnakeList S,Food *F,Food *B);//画蛇和判断蛇吃食物和判断蛇过草地
void movesnake(SnakeList S);//蛇的移动
void move(SnakeList S);//清理蛇尾节点
void keyboard();//获取键盘输入
void paly(SnakeList S,Food *F,Food *B);//玩游戏函数
unsigned char getkey();
void textout(int y,int x,int ch,char s[]);
void DrawMenu();//画主界面
void drawtext();//画主菜单
void Choose();//主菜单各个选项的进入
void DrawInfo();//画游戏信息
void DrawHelp();//画帮助信息
void DrawHelp2();//画操作说明
void DrawBox1();//难度菜单的边框
void DrawBox2();//游戏信息的边框
void DrawBox3();//游戏结束信息的边框
void DrawLevel();//画难度选择界面
void DrawLevel2();
void StopMenu();//画游戏结束界面
void select(int c);//主菜单上下选择
void LevelChoose();//难度菜单上下选择
void LevelChoose2();
void readscore(int level);//读取一个排行榜数据
void ReadAllScore();//读取所有排行榜数据
void DrawScore(int level,int x);//画一个排行榜
void DrawRank();//画所有排行榜
void DrawRank2();
void JudgeScore(int level);//判断分数大小是否记录进排行榜
需要用到的基本函数:
void color(unsigned short c)
{//颜色选择
HANDLE app=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(app,c);
}
void gotoxy(int x,int y)//光标跳转
{
COORD cr;
HANDLE app=GetStdHandle(STD_OUTPUT_HANDLE);
cr.X=x;
cr.Y=y;
SetConsoleCursorPosition(app,cr);
}
void HideCursor()//隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
蛇的建立使用链表,蛇身移动和加长用到头插法:
void InitNode(SnakeList S,int x,int y)
{//蛇的节点创建
SnakeNode *q=(SnakeNode *)malloc(sizeof(SnakeNode));
SnakeNode *p=S;
q->next=NULL;
q->snakenode.x=x;
q->snakenode.y=y;
q->next=p->next;
p->next=q;
}
食物座标合法性判断:
int JudgeFood(SnakeList S,Food *F,Food *B)
{//判断食物位置是否合法,F为要建立的食物,B为已经建立的食物
SnakeNode *p=S->next;
if(F->x%2 != 0) //使得食物座标x一直为偶数,方便判断
return 0;
if(F->x==B->x && F->y== B->y)//判断食物和已建立食物座标是否一样
return 0;
if(F->x < 8 || F->x > 90)//判断食物座标是否在外墙上
return 0;
if(F->y < 2 || F->y > 16)
return 0;
if(map2[F->y+1][F->x+1] == 1)//判断食物座标是否在障碍物(内墙)上
return 0;
while(p!=NULL)//判断食物座标是否在蛇上
{
if(F->x == p->snakenode.x && F->y == p->snakenode.y)
{
return 0;
}
p=p->next;
}
return 1;
}
蛇穿草地部分代码:
if((level == 2 || level == 3 || level == 4 || level == 5) && (tail->snakenode.x == 92 || tail->snakenode.x == 4)) //如果蛇穿墙而过,在蛇尾过墙后重新输出该位置的墙体
{
gotoxy(tail->snakenode.x,tail->snakenode.y);
color(2);
printf("▲");
}
if((level == 3 || level == 4) && (tail->snakenode.y ==17 || tail->snakenode.y ==1))
{
gotoxy(tail->snakenode.x,tail->snakenode.y);
color(2);
printf("▲");
}
蓝色食物每10秒换位置:
//每10秒蓝色Food变换一次位置
ftime=(end-start) /1000;
if(ftime % 10 == 0 && map2[B->y][B->x] == 5 && ftime != temp)
{
gotoxy(B->x,B->y);
printf(" ");
map2[B->y][B->x]=0;
Initfood(S,B,F,5);
temp=ftime;
}
运行程序: