c语言小游戏实践-贪吃蛇

今天无意间翻以前的代码时看到了当初写的贪吃蛇,改了改几处bug,增加了一个记录得分的模块。感觉自己最多只能拿到55分。有兴趣的小伙伴可以看看。

/*名称:贪吃蛇

  作者:tedist

  基本实现方法:链表表示蛇体,在while循环以及Sleep函数下用printf函数实现游戏的动态化。(在没有吃到食物的时候用增头去尾的方法表示移动,吃到食物的时候不去掉尾)

  1.定义蛇体的每一个结点,定义食物。

  2.预处理地图位置,地图墙壁

  3.所需函数
   1. 光标定位   void gotoxy()
   2.地图初始化 void initmap()
   3.刷新食物   void creatfood() *食物在刷新的时候不能出现在蛇的身上
   4.蛇的操控   void controlSnake()*蛇不能进行180度的转弯
   5.碰撞判定   int crush()
   6.失败标志   int faile()
   7.游戏速度   void speed()
   8.当游戏结束时如果分数大于历史最高分则保存,增加游戏的可玩性。
   
  
  4.主函数
    如果之前有score文档保存最高分数则读取显示,没有就新建一个score文件保存最高得分
	地图初始化
	while(1)
	{
	蛇的操作
	失败标志;break;
	}
	结束游戏若分数大于最高分那么保留最高分。
	退出游戏。

*/
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<math.h>

#define wallx 4
#define wally 4 //墙壁的位置//

#define len 3   //蛇的初始长度//

#define wallwidth 40
#define wallheight 20 //围墙的大小//

int speed=200;//定义初始的运动速度//

COORD cor;//在构建围墙的时候用到的位置变量//

char ch=72;
char pre=72;//定义蛇一开始的初始运动方向,并为蛇之前运动的方向保留一个变量//
int eat=0;//判定蛇此时是否吃到了食物//

int length;//记录蛇的长度//
int maxscore;//记录最高记录//
int scorewallwidth=10;//分数框的宽度//

typedef struct snode
{
	COORD cor;
	snode* next;
}snode,*snake;//定义构成蛇的节点的存储结构//

typedef struct
{
	COORD cor;
}food;//定义食物的存储结构//
food f;

void hide()
{
CONSOLE_CURSOR_INFO cursor_info={1,0};
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(hout, &cursor_info);
}//将光标隐藏起来//

void gotoxy(COORD cor)
{
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hout,cor);
}//光标定位函数//


int crush(COORD cor1,COORD cor2)
{
	if(cor1.X==cor2.X&&cor1.Y==cor2.Y)
		return 1;
	else
		return 0;
}//判断是否碰撞的函数//

void creatfood(snake p)
{
	int a=1;
	while(a)
	{
		a=0;
		srand((unsigned int)time(NULL));
	    f.cor.X=(rand()%(wallwidth-2)+(wallx+1));
	    f.cor.Y=(rand()%(wallheight-2)+(wally+1));
	    for(;p->next!=NULL;p=p->next)
		{
		    if(crush(p->cor,f.cor))
			{
				a=1;
				break;
			}//当随机生成的食物与蛇的身体重复时重新生成一个食物//
		}
	}
	gotoxy(f.cor);
	printf("$");
}//在地图上随机生成食物的函数//

snake Initmap()
{
	int i;
	snake head,pre,p;
	for(i=0;i<wallwidth;i++)
	{
		cor.X=wallx+i;
		cor.Y=wally;
		gotoxy(cor);
		printf("*");
	}
	for(i=0;i<wallwidth;i++)
	{
		cor.X=wallx+i;
		cor.Y=wally+wallheight-1;
		gotoxy(cor);
		printf("*");
	}
	for(i=0;i<wallheight;i++)
	{
		cor.X=wallx;
		cor.Y=wally+i;
		gotoxy(cor);
		printf("*");
	}
	for(i=0;i<wallheight;i++)
	{
		cor.X=wallx+wallwidth-1;
		cor.Y=wally+i;
		gotoxy(cor);
		printf("*");
	}//生成墙壁//
	head=(snake)malloc(sizeof(snode));
	pre=p=head;
	head->cor.X=wallx+wallwidth/2;
	head->cor.Y=wally+wallheight/2;
	head->next=NULL;
	for(i=1;i<len;i++)
	{
		p=(snake)malloc(sizeof(snode));
		p->cor.X=head->cor.X;
		p->cor.Y=head->cor.Y+i;
		pre->next=p;
		p->next=NULL;
		pre=p;
	}
	length=len;//初始化长度//
	creatfood(head);
	p=head;
	while(p)
	{
		gotoxy(p->cor);
		printf("*");
		p=p->next;
	}//输出蛇//
	return head;
}//初始化地图//

void Speed()
{
	speed-=3;
}//游戏速度函数//
		
snake controlsnake(snake p)
{
	snake head;
	if(kbhit())
	{
		getch();
		ch=getch();
	}//得到键值//
	if(abs(pre-ch)==2||abs(pre-ch)==8)
		ch=pre;//防止出现往蛇之前运动的方向相反的方向运动会死亡的bug//
	head=(snake)malloc(sizeof(snode));
	head->cor.X=p->cor.X;
	head->cor.Y=p->cor.Y;
	pre=ch;
	switch(ch)
	{
	case 72:head->cor.Y-=1;break;
	case 80:head->cor.Y+=1;break;
	case 75:head->cor.X-=1;break;
	case 77:head->cor.X+=1;break;
	}
	head->next=p;
	gotoxy(head->cor);
	printf("*");
	if(!eat)
	{
		for(p=head;p->next->next!=NULL;p=p->next);
		gotoxy(p->next->cor);
		printf(" ");
		free(p->next);
		p->next=NULL;
	}
    eat=0;
	return head;
}//蛇运动的控制函数//

int faile(snake head)
{
	snake p;
	p=head;
	if(!(p->cor.X>wallx&&p->cor.X<(wallx+wallwidth-1)&&p->cor.Y>wally&&p->cor.Y<wallheight+wally-1))
		return 1;
	for(p=p->next;p!=NULL;p=p->next)
	{
		if(crush(head->cor,p->cor))
			return 1;
	}
	return 0;
}//判定蛇是否死亡//
//..........游戏部分............//

void initsframe()
{
	int i;
	for(i=1;i<scorewallwidth;i++)
	{
		cor.X=wallx+wallwidth-1+i;
		cor.Y=wally;
		gotoxy(cor);
		printf("*");
		cor.X=wallx+wallwidth-1+i;
		cor.Y=wally+wallheight-1;
		gotoxy(cor);
		printf("*");
	}
	for(i=0;i<wallheight;i++)
	{
		cor.X=wallx+wallwidth+scorewallwidth-2;
		cor.Y=wally+i;
		gotoxy(cor);
		printf("*");
	}
}//得分方框建立//

void score()
{
	cor.X=wallx+wallwidth+1;
	cor.Y=wally+2;
	gotoxy(cor);
	printf("MAX");
	cor.X=wallx+wallwidth+2;
	cor.Y=wally+4;
	gotoxy(cor);
	printf("%d",maxscore);
	cor.X=wallx+wallwidth+1;
	cor.Y=wally+7;
	gotoxy(cor);
	printf("score");
}//最高分以及当前得分的显示//

void main()
{
	FILE*fp;
	if(!(fp=fopen("score","a+")))
	{
		printf("cannot open the file/n");
		exit(0);
	}
	fscanf(fp,"%d",&maxscore);
	fclose(fp);//读取历史文件中的最高分//
	if(!maxscore){maxscore=0;}
	snake head;
	printf("——————————\n");
	printf("    欢迎进入游戏    \n");
	printf("——————————");
	score();
	initsframe();
	head=Initmap();
	hide();
	while(1)
	{
		head=controlsnake(head);
		if(crush(head->cor,f.cor))
		{
			Speed();
			length+=1;
			eat=1;
			creatfood(head);
		}
		if(faile(head))
		{
			break;
		}
		cor.X=wallx+wallwidth+2;
	    cor.Y=wally+9;
	    gotoxy(cor);
	    printf("%d",length);
		Sleep(speed);
	}
	printf("GAME OVER");
	if(length>maxscore)
	{
		printf("恭喜你创造了新记录!!!");
        if(!(fp=fopen("score","w")))
		{
	    	printf("cannot open this file");
	    	exit(0);
		}
		fprintf(fp,"%d",length);
		fclose(fp);//当前分数比记录高的时候自动保存成为最高纪录//
	}
	getch();
}



 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值