上篇我们谈了如何让这条🐍出现在地图里,今天我们就来看看让它如何动起来,话不多说,先来看效果。
🐍动起来
下面是实现代码:
#include<stdio.h>
#include<curses.h>
#include<stdlib.h>
#include<unistd.h>
struct Snake{
int row;
int column;
struct Snake* next;
};
struct Snake* head = NULL;
struct Snake* tail = NULL;
void initNcurses(){
initscr();
noecho();
keypad(stdscr,1);
}
int hadSnakeNode(int row, int column){
struct Snake *p=NULL;
p=head;
while(p!=NULL){
if(p->row==row && p->column==column){
return 1;
}
p=p->next;
}
return 0;
}
void gamePicture(){
int row;
int column;
move(0,0);//让光标从新回到地图的最初位置即坐标(0,0)处
for(row=0;row<25;row++){
if(row==0){
for(column=0;column<25;column++){
printw("**");
}
printw("\n");
}else if(row>0 && row<24){
for(column=0;column<=25;column++){
if(column==0 || column==25){
printw("|");
}else if(hadSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
else{
for(column=0;column<25;column++){
printw("**");
}
}
}
printw("\n");
printw("By your name\n");
}
void addNode(){
struct Snake* new=(struct Snake *)malloc(sizeof(struct Snake));
new->row=tail->row;
new->column=tail->column+1;
new->next=NULL;
tail->next=new;
tail=new;
}
void deleteNode(){
struct Snake* p=(struct Snake*)malloc(sizeof(struct Snake));
p=head;
head = head->next;
free(p);
}
void initSnake(){
struct Snake *p;
while(head != NULL){
p=head;
head=head->next;
free(p);
}
head=(struct Snake*)malloc(sizeof(struct Snake));
head->row=2;
head->column=1;
head->next=NULL;
tail=head;
addNode();
addNode();
}
void moveSnake(){
addNode();
deleteNode();
if(tail->row<0 || tail->row==25 || tail->column==0 || tail->column==25){
initSnake();
}
}
int main(){
initNcurses();
initSnake();
while(1){
gamePicture();
refresh();//刷新界面
usleep(100000);//延时一秒
moveSnake();
}
getch();
endwin();
return 0;
}
看了上述代码,相信大家已经看出来了与上篇博客的不同之处。接下来就来看看是如何实现🐍向右移动的。通过下列图我们来看一下。
通过上图我们可以看出,从1到2,向右移动了一下,左边删掉一个节点,右边增加一个节点。类比从2到3同样如此。依此类推就形成了蛇向右移动的样子。所以我们就不难理解下面的代码。
void moveSnake(){
addNode();
deleteNode();
if(tail->row<0 || tail->row==25 || tail->column==0 || tail->column==25){
initSnake();
}
}
上述代码封装了一个deleteNode();函数:是一个删除节点的操作
void deleteNode(){
struct Snake* p=(struct Snake*)malloc(sizeof(struct Snake));//为p开辟空间
p=head;
head = head->next;//这里直接将头节点指向下一个节点地址赋给头节点,达到删除节点的效果,可以借用上图理解一下。
free(p);//释放p的内存
}
另外这里还有一个if()判断语句:
if(tail->row<0 || tail->row==25 || tail->column==0 || tail->column==25){
initSnake();
}
这里就相当于蛇撞墙死亡后重新复活过来的实现代码。再次调用蛇初始化函数,让蛇重新从出发点开始。
至此,今天C语言贪吃蛇游戏的第四部分就到此为止了,期待下篇博客的完结。