C语言实现贪吃蛇小游戏

C语言链表-贪吃蛇

设计思路

贪吃蛇的整体移动,可以只简化为蛇头与蛇尾的移动,当贪吃蛇的蛇头碰到蛇身或障碍物或超出指定范围时,游戏结束,因此我们作出以下设计:
1. 蛇身体结构设计 :蛇身整体的移动,可看作一个先进先出的队列,因此我们使用一个无附加表头的循环链表作队,来存储蛇的每一个节点(二维坐标值);
2. 地图状态设计:我们使用一个二维坐标来标志地图的状态,用-1标志食物的位置,用1标志蛇身,用0标志无障碍。


效果展示(gif)

程序源码


#include<graphics.h>

#include<conio.h>

#include<stdlib.h>

#include <stdio.h>

#include<time.h>

#define R 16  	//每个格子尺寸:R*R

#define W 27

#define L 42	//活动范围:(L-2)*(W-2)个格子

//template <class T>

struct dot{//坐标值结构体

    int x;

	int y;

};

//template <class T>

struct Node{

    dot data;

	Node *next;

};

//template <class T>

class Cqueue{ // 无附加表头的循环链表作队

private:

	Node *rear;//尾指针

public:

	Cqueue()//构造空队

	{rear=NULL;}

	bool Empty()//判断空否

	{return !rear;}

	struct dot DeQueue()

	{//出队操作

		struct dot d;

		if(!rear ) throw "空";

		Node *q=rear->next;

		//d.x=q->data.x;

		//d.y=q->data.y;

		d=q->data;

		rear->next=q->next;

		if(rear==q) rear=NULL;//最后一个元素的特殊处理

		delete q;

		return d;

	}

	void EnQueue(int a,int b){//入队操作

		Node *q=new Node; 

		q->data.x=a;q->data.y=b;

		if(!rear){rear=q;rear->next=rear;}//空时的处理

		else 

		{q->next=rear->next;rear->next=q;rear=q;}

	}

};

void show(int* p)//输出状态数组值

{

	int i,j;

	char num[4];

	//setbkmode(TRANSPARENT);

	setcolor(RED);

	for(i=0;i<L-2;i++)

		for(j=0;j<W-2;j++){

			sprintf(num, "%d", *(p++));

			outtextxy(i*R+R,j*R+R,num);}

}

void setfood(int* p)//设置食物

{

	int x,y;

	do{

		x=R+rand()%(R*L-2*R);

		y=R+rand()%(R*W-2*R);

		x=x/R;

		y=y/R;

	}while(*(p+(x-1)*(W-2)+(y-1))==1);

	setfillcolor(RED);

	fillcircle(x*R+R/2,y*R+R/2,R/2);

	*(p+(x-1)*(W-2)+(y-1))=-1;

}

void finish(int n)//游戏结束时调用

{

	setfont(2*R,0,"方正舒体", 0,0,2, 0,0,0);

	setbkmode(TRANSPARENT);

	setcolor(WHITE);

	outtextxy((6+L)*R/2,(4+W)*R/2,"come over");

	//system("pause");

	Sleep(1500);

	return;

}

void move(int x,int y,Cqueue Q,int* p)//蛇的移动

{

	

	char c=getch();

	char k=c;//k记录c的上一次状态

	int num=0;

	struct dot t;

	while(c != 27)

	{

		//show(p);

		Sleep(300);

		// 获取按键

		if (kbhit())

		{

			c = getch();

			if(k=='a'||k=='d'){

				if(c=='a'||c=='d')

					c=k;}

			else{

			if(k=='w'||k=='s')

				if(c=='w'||c=='s')

					c=k;}

			k=c;

		}

		// 根据输入,计算新的坐标

		switch(c)

		{

			

			case 'a': x-=R; break;

			case 'd': x+=R; break;

			case 'w': y-=R; break;

			case 's': y+=R; break;

			case 27: break;

		}

		if(x<R||x>=R*(L-1)||y<R||y>=R*(W-1))

		{

			finish(num);

			return;

		}

		if(*(p+(x/R-1)*(W-2)+y/R-1)==0)

		{

			Q.EnQueue(x,y);

			*(p+(x/R-1)*(W-2)+y/R-1)=1;

			//setcolor(RED);

			setfillcolor(YELLOW);

			solidrectangle(x,y,x+R,y+R);

 

			t=Q.DeQueue();

			*(p+(t.x/R-1)*(W-2)+t.y/R-1)=0;

			solidrectangle(t.x,t.y,t.x+R,t.y+R);

			

		}

		else

			if(*(p+(x/R-1)*(W-2)+y/R-1)==-1)

			{

				num++;

				Q.EnQueue(x,y);

				*(p+(x/R-1)*(W-2)+y/R-1)=1;

				setfillcolor(RED);

				fillcircle(x+R/2,y+R/2,R/2);

				setfillcolor(YELLOW);

				solidrectangle(x,y,x+R,y+R);

				setfood(p);//重置食物

			}

			else{

				finish(num);

				p=NULL;

				return;}

	}

}

void main()

{

	initgraph(R*L,R*W);

	srand(time(NULL));

	Cqueue Q;//循环链接队

	//struct dot p;//蛇尾坐标

	int wall[L-2][W-2];0:障碍物/空区域;-1:食物;1:蛇身

	setcolor(GREEN);

	//rectangle(R-1,R-1,641-R,641-R);

	int i,j;

	for(i=R;i<R*L;i+=R)

		line(i,R,i,R*W-R);

	for(j=R;j<R*W;j+=R)

		line(R,j,R*L-R,j);

	for(i=0;i<L-2;i++)//初始化数组wall

		for(j=0;j<W-2;j++)

			wall[i][j]=0;

	setwritemode(R2_XORPEN);

	int x,y;

	do{//创建第一个结点为蛇首

		x=rand()%(R*L);

		y=rand()%(R*W);

	}while(x<R||x>=R*(L-1)||y<R||y>=R*(W-1));

	x=x/R*R;

	y=y/R*R;

	wall[x/R-1][y/R-1]=1;

	Q.EnQueue(x,y);

	//setcolor(RED);

	setfillcolor(YELLOW);

	solidrectangle(x,y,x+R,y+R);

	setfood(wall[0]);//设置第一个食物

	move(x,y,Q,wall[0]);

	

	getch();

	closegraph();

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值