[C语言]链表实现贪吃蛇及部分模块优化

飞来科技  发布时间:2019-08-09 02:04:08

本文关键词:c语言贪吃蛇实现

c语言 贪吃蛇游戏_c 语言贪吃蛇代码_c语言贪吃蛇实现

好了,现在可以给蛇赋予节点了。原理也很简单,在函数尾部加三个节点就好。我们应当蛇头在右,共有三个节点,位置居中c语言贪吃蛇实现,但是小蛇的座标也是为(28c语言贪吃蛇实现,14),后两个节点依次为(26,14)、(24,14)。

boolInitializeSnake(Snake*psnake)

scan=(psnake->head);

pnew=(Node*)malloc(sizeof(Node));

printf("pnew==NULL");

pnew->place.x=28-2*i;

pnew->place.y=14;

pnew->next=NULL;

psnake->size++;

PrintIn(NODE,pnew->place.x,pnew->place.y);

psnake->head=pnew;

scan=scan->next;

scan->next=pnew;

食品可用一个全局函数来指出,该函数存储一个坐标值。因此可用上之前定义的Place结构。

Foodfood={,};

而坐标值的范围就能确保两点就好:在地图内;不与蟒蛇重合。

food.x=rand()%(WIDTH-5)+2;

food.y=rand()%(HEIGHT-2)+1;

Node*scan=snake.head;

c 语言贪吃蛇代码_c语言 贪吃蛇游戏_c语言贪吃蛇实现

if(scan->place.x==food.x&&

scan->place.y==food.y)

scan=scan->next;

PrintIn(FOOD,food.x,food.y);

//AfterEatFood();

蛇的移动本质很简单,就是不断更新蛇的位置,并打印。所以我们需要一个循环:

首先我们需要接收输入,用于控制游戏进行

这里介绍一个函数

2.//检查当前是否有鼠标输入,若有则回到一个非值,如果离开

这是一个非阻塞函数,有键按下时前往非,但此时键盘码一直在鼠标缓冲队列中。所以在确认键盘有响应以后,再用一个char数组将输入从缓冲区中调出来。

2.ch=getch();

现在我们应当网游中'w' 's' 'a' 'd'控制方向,括号暂停,但是对于用户的输入,我们需要分析是否非法。我用了一个数组+循环来替代一连串的if:

ch=getch();

当我们得到的输入非法时,我们仍需分析现在的输入方向是否与之前的方向相反,其实在我设计的这个手游里,蟒蛇可不能折叠往自己头上碾过去。

在我用函数实现的那种版本里,我用了一大串if-else来防止相反的输入,这只是简单,却很脑残。所以我用一个更简单的方式取代了它。在我们应当为正确输入的五个字符中,ASCII码分别为a:97,d:100,w:119,s:115,space:32,其中ad是争执的一对,ws是争执的一对。ad的数值为±3,ws的数值为±4,括号直接暂停,所以不予考虑。所以我们只需要判断,所以输入ch的值与方向direction的数值为±3或者±4,所以就可以判断输入不非法,丢弃。

if(!(direction-ch==4||direction-ch==-4||direction-ch==3||direction-ch==-3))

direction=ch;

之前版本10行的小事,现在有意义的源码只有5行。

为了方便对移动的座标进行操作,我们声明一个数组,用于存储不同方向下坐标的改变:

c语言贪吃蛇实现_c语言 贪吃蛇游戏_c 语言贪吃蛇代码

{,,-2,2},

不同下标分别对于w s a d,因为长度60的WIDTH其实只有30个单位,但是x值一次加2。

由于蟒蛇每个结点都一个样,但是没有必要每次循环都把一切的结点重新输出一遍,只需要更新头结点和尾结点就好。在网游中,无论是撞墙、不管其它情形,蛇只要移动了,所以他头结点的座标一定会改变,所以我们可以在移动后先把新的蟒蛇打印出来。至于蛇尾,所以蛇移动后并没有吃到食品,蛇尾则删除,吃到了的话蛇尾则保存。所以在打印了颈部之后再分析头部是否吃到食品,再对蛇尾进行处理。

PrintIn(NODE,snake.head->place.x+dir_value[][],snake.head->place.y+dir_value[1][]);//打印头部

if(snake.head->place.x+dir_value[][]==food.x&&snake.head->place.y+dir_value[1][]==food.y)

//AddNode(&snake);//尾插法

Node*tail=GetTail(&snake);

PrintIn(SPACE,tail->place.x,tail->place.y);//场景上去除尾部节点

在硬盘中,我们则需要更新各个结点的座标。如果吃到了水果,则加入一个节点(我用的尾插法),并将前一结点的值赋给后一结点。先前的头结点坐标值赋给第二节点,头结点则按照输入,更新新的座标值。没有吃到的话,也直接赋值,尾结点坐标值因为下一步就要更新,但是可丢弃不管,只需得到前一结点坐标就好。

PrintIn(NODE,snake.head->place.x+dir_value[][],snake.head->place.y+dir_value[1][]);

if(snake.head->place.x+dir_value[][]==food.x&&snake.head->place.y+dir_value[1][]==food.y)

CreateFood();

Node*tail=GetTail(&snake);//得到尾结点

PrintIn(SPACE,tail->place.x,tail->place.y);

RenewSnake(&snake);//函数各结点值的跟新

snake.head->place.x+=dir_value[][];//龙爪更新

snake.head->place.y+=dir_value[1][];

其中RenewSnake()变量用于更新一个链表(蛇),使前一个节点的值赋给后一个节点,对这个只需要两个临时数组就可以。

c语言贪吃蛇实现_c 语言贪吃蛇代码_c语言 贪吃蛇游戏

从这简单的流程图可看出一点端倪,现在我们把流程完善一下。

如果我们得到了一些普适性的方式,源码如下:

voidRenewSnake(Snake*psnake)

intx_index[2]={,},y_index[2]={,};

Node*scan=psnake->head;

x_index[i%2]=scan->place.x;

y_index[i%2]=scan->place.y;

for(i=1;i<psnake->size;i++)

x_index[(i+1)%2]=scan->next->place.x;

y_index[(i+1)%2]=scan->next->place.y;

scan->next->place.x=x_index[i%2];

scan->next->place.y=y_index[i%2];

scan=scan->next;

同理,其他三个方向应该这样。

在这个手游中,我们需要这样几个变量:

其中,length其实可以不需要。我们需要在吃到食品后进行一系列的操作,如加分,再次生成食物等等。所以在移动时的判断里加入一些变量。

if(snake.head->place.x+dir_value[][]==food.x&&snake.head->place.y+dir_value[1][]==food.y)

CreateFood();

c 语言贪吃蛇代码_c语言 贪吃蛇游戏_c语言贪吃蛇实现

生成食物还需要加分等操作,但是我们可以把加分等操作的变量(AfterEatFood();)放在该字段末尾。不过这种的话,网游直到生成的第一个食物就需要提醒了,所以我们的两个全局函数都是负值。

Pos(WIDTH+20,HEIGHT-20);

printf("%d=%d",++length,snake.size);

Pos(WIDTH+16,HEIGHT-18);

Pos(WIDTH+16,HEIGHT-16);

在蛇移动后,我们还需分析蛇是否撞墙或者咬到本身。撞墙是大蛇与界限坐标的比较,咬到本身则可以用一个循环。

boolThroughWall(Snake*psnake)

if(psnake->head->place.x==0||psnake->head->place.x==WIDTH-2||

psnake->head->place.y==||psnake->head->place.y==HEIGHT-1)

Pos(25,15);

Pos(,HEIGHT);

boolBiteItself(Snake*psnake)

Node*scan=psnake->head;

scan=scan->next;

if(scan->place.x==psnake->head->place.x&&

scan->place.y==psnake->head->place.y)

Pos(25,15);

printf("咬到本身,游戏结束!");

最终在循环末尾加入Sleep,控制游戏的节拍。

Sleep(speed);

本文来自互联网,由机器人自动采编,文章内容不代表本站观点,请读者自行辨别信息真伪,如有发现不适内容,请及时联系站长处理。

    时时彩平台