首页 > 文章资讯 > 新闻资讯
C语言项目游戏,贪吃蛇大作战
更新时间:2022-08-02 01:20:49 作者:云寺手游

C语言项目游戏,贪吃蛇大作战

效果图





参考代码

(使用的编译器VS2019)

#include<stdio.h>

#include<time.h>

#include<windows.h>

#include<conio.h>

#include<stdlib.h>

#define U 1

#define D 2

#define L 3

#define R 4

int zifu[6] = { 0,0,0,0,0,0 }; //用来存放欢迎界面“贪吃蛇大作战”的横坐标值

int k; //用来设定“贪吃蛇大作战”字幕的起始横坐标值

int Hscore = 0;

int score = 0, fen = 10;

int endgame = 0;

int sleeptime = 400; //蛇每次运行的时间状态,修改可以获得不同1的蛇得爬行速度

int zhuangtai; //设置蛇的运行状态

typedef struct Snake {

int x;

int y;

struct Snake* text;

}Snake; //绘制蛇的结构体变量

Snake* head, * food; //设置蛇的头指针,食物也以指针来确定

Snake* pp; //定义蛇的指针,用来调换蛇头

int color(int c);

void gotoxy(int x, int y);

void welcome(); //游戏欢迎界面

void choie(); //游戏选择框界面

void map(); //构建游戏地图

void scorerecord(); //游戏得分记录函数

void snake(); //初始化蛇身

void creatfood(); //创建随机食物

int bitemyself(); //判断蛇是否咬到自己

void ifwall(); //判断蛇是否撞到墙

void sleepdown(); //加速函数

void sleepup(); //减速函数

void move(); //蛇的控制移动方向

void keycontrol(); //按键控制蛇的移动

void shibai(); //失败函数,绘制失败界面

void end(); //游戏结束判断函数

void Filein(); //文件写入函数

void choose(); //选择函数

void File(); //文件写入函数

int color(int c)

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);

return 0;

}

void gotoxy(int x, int y)

{

COORD c;

c.X = x;

c.Y = y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);

}

int main()

{

welcome();

return 0;

}

void welcome()

{

int i,j, m = 1;

int z;

int n;

while (1)

{

k = 20; //横坐标起始位置为20

for (i = 0; i < 6; i++) //给zifu数组赋值,从数组地位到高位,一次存放‘贪吃蛇大作战’的横坐标值

{

zifu[i] = k + m;

if (zifu[i] == 53) //因为横坐标起始位置为20,设定的移动长度为33,20+33=53,第一次到zifu[i]==53以后要使它重新等于20

//就需要对显示屏长度33求余,53-66之间就会使“大作战”在显示屏前面,呈现“大 作 战 贪 吃 蛇”

{ //字样,此时由于“蛇”的横坐标值达到了66,66%33==0;这时再加上20,就会出现字体重合现象。为了解决这个问题,只有

m = m + 13; //把53-66之间的数值拿走,使zifu的某个值达到53以后,之间跳转成66,所以让m=m+13;

}

z = (k + m) % 33;

zifu[i] = z + 20;

k += 4;

}

color(2);

gotoxy(zifu[0], 10);

printf("贪");

color(5);

gotoxy(zifu[1], 10);

printf("吃");

color(10);

gotoxy(zifu[2], 10);

printf("蛇");

color(9);

gotoxy(zifu[3], 10);

printf("大");

color(12);

gotoxy(zifu[4], 10);

printf("作");

color(14);

gotoxy(zifu[5], 10);

printf("战");

Sleep(500); //调用延时函数,这样才能看出移动效果,否者可能因为执行过快,而无法呈现移动效果

gotoxy(zifu[0], 10); //输出空格,制造出字体移动的效果

printf(" ");

gotoxy(zifu[1], 10);

printf(" ");

gotoxy(zifu[2], 10);

printf(" ");

gotoxy(zifu[3], 10);

printf(" ");

gotoxy(zifu[4], 10);

printf(" ");

gotoxy(zifu[5], 10);

printf(" ");

m += 2; //每次在横坐标上移动两个字节

srand(time(NULL));

n = rand() % 15 + 1;

for (i = 10; i <= 58; i++)

{

for (j = 5; j <= 15; j++)

{

if (i == 10 || i == 58)

{

color(n);

gotoxy(i, j);

printf("▊");

}

if (j == 5 || j == 15)

{

color(n % 13 + 1);

gotoxy(i, j);

printf("▃");

}

}

}

color(11);

gotoxy(60, 9);

printf("制作人:沙雕");

gotoxy(60, 10);

printf("年纪:这和游戏有什么关系");

gotoxy(60, 11);

printf("这个沙雕有话要讲:");

color(13);

gotoxy(60, 12);

printf("不知道怎么开始有吧?傻批");

gotoxy(60, 13);

printf("随便按一个键嘛,真傻!");

if (_kbhit())

{

choie();

}

}

}

void choie()

{

system("cls"); //清屏

int xuanze;

int i, j;

gotoxy(43, 18); //光标移动到指定位置,输出标题

color(11);

printf("贪吃蛇大作战"); //标题

color(14);

for(i=29;i<=74;i++) //用两个循环输出边框

for (j = 20; j <= 30; j++)

{

if (i == 29 || i == 74)

{

gotoxy(i, j);

printf("|");

}

else

if (j == 20 || j == 30)

{

gotoxy(i, j);

printf("=");

}

}

color(12);

gotoxy(33, 22);

printf("1,开始游戏");

gotoxy(52, 22);

printf("2,游戏说明");

gotoxy(33, 27);

printf("3,退出游戏");

color(3);

gotoxy(38, 33);

printf("请输入你的选择:【】bb");

color(14);

scanf_s("%d", &xuanze);

switch (xuanze)

{

case 1:

system("cls");

map();

snake();

creatfood();

File();

keycontrol();

end();

break;

case 2:

system("cls");

color(13);

printf("不能撞墙,不能咬自己,用方向键控制蛇的移动n");

printf("F1加速,F2减速。空格键暂停,再按空格键继续n");

printf("按ESC退出游戏。");

_getch();

system("cls");

choie();

break;

case 3:

exit(0);

break;

default:

gotoxy(38, 36);

printf("你未正确输入");

system("cls");

welcome();

}

}

void map() //绘制游戏范围边框

{

int i;

for (i = 0; i < 58; i += 2)

{

gotoxy(i, 0);

color(5);

printf("□");

gotoxy(i, 26);

printf("□");

}

for (i = 1; i < 26; i++)

{

gotoxy(0, i);

printf("□");

gotoxy(56, i);

printf("□");

}

}

void scorerecord()

{

File();

gotoxy(64, 4);

color(11);

printf("*最高纪录*:%d", Hscore);

gotoxy(64, 8);

color(4);

printf("得分:%d", score);

color(13);

gotoxy(73, 11);

printf("小 提 示");

gotoxy(60, 13);

color(6);

printf("-------------------");

gotoxy(60, 25);

printf("-------------------");

color(3);

gotoxy(64, 14);

printf("每个食物得分:%d分", fen);

gotoxy(64, 16);

printf("不能撞墙,不可以咬自己");

gotoxy(64, 20);

printf("用方向键控制蛇得移动");

gotoxy(64, 22);

printf("Space:暂停游戏");

gotoxy(64, 24);

printf("Esc:退出游戏");

}

void File()

{

FILE* fp;

int err;

err = fopen_s(&fp,"save.txt", "a+");

fscanf_s(fp, "%d", &Hscore);

fclose(fp);

}

void snake()

{

Snake* tt;

int i;

tt = (Snake*)malloc(sizeof(Snake)); //从蛇尾开始往蛇头设置蛇身的坐标

tt->x = 24;

tt->y = 5;

tt->text = NULL;

for (i = 1; i <= 4; i++) //设置蛇身,初始化长度为5

{

head = (Snake*)malloc(sizeof(Snake)); //利用循环,不断开辟一个空间,该空间成为蛇头

head->y = 5; //直到达到蛇的初始化位置

head->x= 24 + 2 * i;

head->text = tt;

tt = head;

}

while (tt != NULL) //输出蛇身

{

gotoxy(tt->x, tt->y);

color(14);

printf("■");

tt = tt->text;

}

}

void creatfood()

{

Snake* food1;

label:srand((unsigned)time(NULL)); //初始化随机食物

food1 = (Snake*)malloc(sizeof(Snake));

while ((food1->x % 2) != 0)

{

food1->x = rand() % 52 + 2; //设置随机食物的横坐标随机值

}

food1->y = rand() % 24 + 1;

pp = head; //把头指针给pp,然后遍历蛇身

while (pp->text != NULL)

{

if (pp->x == food1->x && pp->y == food1->y) //判断食物位置是否与蛇身重合

{ //如果重合就释放第一个食物指针,然后重新生成食物

free(food1);

goto label;

}

pp = pp->text;

}

gotoxy(food1->x, food1->y); //如果不重合,就输出食物

food = food1;

color(12);

printf("■");

}

int bitemyself()

{

Snake *she;

she = head->text;

while (she != NULL)

{

if (she->x == head->x && she->y == head->y)

return 1;

she = she->text;

}

return 0;

}

void ifwall() //判断蛇是否撞到墙,原理是看蛇头的坐标是否和边界坐标重合

{

if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)

{

endgame = 1;

end();

}

}

void sleepup() //蛇的加速函数

{

if (sleeptime >= 50)

{

sleeptime = sleeptime - 10;

fen = fen + 2;

}

}

void sleepdown() //蛇的减速函数

{

if (sleeptime <= 350)

{

sleeptime = sleeptime + 30;

fen = fen - 2;

if (sleeptime == 350)

{

fen = 1;

}

}

}

void move()

{

Snake* xiayige; //下一个食物出现位置

ifwall(); //判断蛇是否撞到墙

xiayige = (Snake*)malloc(sizeof(Snake)); //为食物开辟指针

if (zhuangtai == U) //先判断此时蛇的状态,如果状态朝上,xiayige开辟的空间为蛇前行的下一个位置,然后蛇就长了一节

{ //再判断食物是不是和已经长长的蛇的蛇头重合,如果重合,就输出蛇

xiayige->x = head->x;

xiayige->y = head->y - 1;

xiayige->text = head;

head = xiayige;

pp = head;

if (xiayige->x == food->x && xiayige->y == food->y)

{

while (pp != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

score = score + fen;

sleepup();

creatfood();

}

else //如果不重合,输出原来的蛇,就不给蛇加长了

{

while (pp->text->text != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

gotoxy(pp->text->x, pp->text->y);

color(3);

printf(" "); //输出空格消除蛇移动的痕迹

free(pp->text);

pp->text = NULL;

}

}

if (zhuangtai == D)

{

xiayige->x = head->x;

xiayige->y = head->y + 1;

xiayige->text = head;

head = xiayige;

pp = head;

if (xiayige->x == food->x && xiayige->y == food->y)

{

while (pp != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

score = score + fen;

sleepup();

creatfood();

}

else

{

while (pp->text->text != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

gotoxy(pp->text->x, pp->text->y);

color(3);

printf(" ");

free(pp->text);

pp->text = NULL;

}

}

if (zhuangtai == L)

{

xiayige->x = head->x-2;

xiayige->y = head->y;

xiayige->text = head;

head = xiayige;

pp = head;

if (xiayige->x == food->x && xiayige->y == food->y)

{

while (pp != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

score = score + fen;

sleepup();

creatfood();

}

else

{

while (pp->text->text != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

gotoxy(pp->text->x, pp->text->y);

color(3);

printf(" ");

free(pp->text);

pp->text = NULL;

}

}

if (zhuangtai == R)

{

xiayige->x = head->x+2;

xiayige->y = head->y;

xiayige->text = head;

head = xiayige;

pp = head;

if (xiayige->x == food->x && xiayige->y == food->y)

{

while (pp != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

score = score + fen;

sleepup();

creatfood();

}

else

{

while (pp->text->text != NULL)

{

gotoxy(pp->x, pp->y);

color(14);

printf("■");

pp = pp->text;

}

gotoxy(pp->text->x, pp->text->y);

color(3);

printf(" ");

free(pp->text);

pp->text = NULL;

}

}

if (bitemyself() == 1)

{

endgame = 2;

end();

}

}

void keycontrol()

{

zhuangtai = R;

while (1)

{

scorerecord();

if (GetAsyncKeyState(VK_UP) && zhuangtai != D) //方向键↑

zhuangtai = U;

else if (GetAsyncKeyState(VK_DOWN) && zhuangtai != U) //方向键↓

zhuangtai = D;

else if (GetAsyncKeyState(VK_LEFT) && zhuangtai != R) //方向键←

zhuangtai = L;

else if (GetAsyncKeyState(VK_RIGHT) && zhuangtai != L) //方向键→

zhuangtai = R;

if (GetAsyncKeyState(VK_SPACE)) //如果按下空格键

{

while (1)

{

Sleep(300); //不断延迟时间来达到暂停的目的,再次按下方向键就跳出延迟时间的循环

if (GetAsyncKeyState(VK_SPACE))

{

break;

}

}

}

else if (GetAsyncKeyState(VK_ESCAPE)) //如果按下ESC键就退出

{

endgame = 3;

break;

}

else if (GetAsyncKeyState(VK_F1))

sleepup();

else if (GetAsyncKeyState(VK_F2))

sleepdown();

Sleep(sleeptime);

move();

}

}

void shibai()

{

system("cls");

int i;

gotoxy(17, 5);

color(11);

printf("+----------------------------------------------------------------+");

for (i = 6; i <= 19; i++)

{

gotoxy(17, i);

printf("|");

gotoxy(82, i);

printf("|");

}

gotoxy(17, 20);

printf("+----------------------------------------------------------------+");

}

void end()

{

system("cls");

if (endgame == 1)

{

shibai();

gotoxy(35, 9);

color(12);

printf("你撞到墙了,大哥。游戏结束!");

}

else if (endgame == 2)

{

shibai();

gotoxy(35, 9);

color(12);

printf("咬到自己了,憨包。游戏结束!");

}

else if (endgame == 3)

{

shibai();

gotoxy(40, 9);

color(12);

printf("你已结束游戏。");

}

gotoxy(43, 12);

color(13);

printf("你得到了%d分", score);

if (score >= Hscore) //分数高于最高分

{

color(10);

gotoxy(33, 16);

printf("创纪录啦!牛逼克斯啦");

Filein(); //将最高分写入文件中

}

else

{

color(10);

gotoxy(33, 16);

printf("继续努力,你离最高分还差%d分", Hscore - score);

}

choose();

}

void Filein()

{

FILE* ff; //定义文件指针

int err; //由于fopen_s函数与fopen函数不同,fopen_s函数执行成功返回0,执行失败返回一个非零整数值

if ((err = fopen_s(&ff, "save.txt", "w+")) != 0) //所以定义一个整形变量err用来接收该函数的返回值

{

printf("文件打开失败");

exit(0);

}

fprintf(ff, "%d", score);

fclose(ff);

}

void choose()

{

int n;

gotoxy(25, 23);

color(12);

printf("我不服,我要扳骚-------------1");

gotoxy(59, 23);

printf("太菜了,不想玩了-------------2");

gotoxy(46, 25);

color(11);

scanf_s("%d", &n);

switch (n)

{

case 1:

system("cls");

score = 0;

sleeptime = 600;

fen = 10;

choie();

break;

case 2:

exit(0);

break;

default:

gotoxy(35, 27);

color(12);

printf("你输入的信息有错误,眼睛不好使!");

system("pause >nul"); //按任意键

end();

choose();

break;

}

}

猜你喜欢
最新资讯