上两篇博客已经完成了这款小游戏的前期编程学习,这次我们就来开始完成这款游戏的“主人公”,如何让这条🐍出现在地图里,话不多说,马上进入正题。
简单说明一下:在上图左上角为🐍身,也就是后面每次🐍死亡后会从那个地方再次活过来,这个我们后续再说。如果有学习过链表的小伙伴,相信接下来的编程对你来说将会是一件很轻松的事情。先来看一下整体代码。
#include<stdio.h>
#include<curses.h>
#include<stdlib.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;
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 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();
}
int main(){
initNcurses();
initSnake();
gamePicture();
// while(1);
getch();
endwin();
return 0;
}
上述代码跟上篇部分相似的就不在赘述,我们今天主要来谈下今天新增的部分函数代码,通过看上图,我们可以发现🐍身,其实可以看做由3个节点组成,这就好比链表中增加节点,关于链表的基本操作,可以看我的另一篇博客:关于链表学习
下面代码很明显我们采用的是尾插法。
void addNode(){
//创建一个新节点new,并为它开辟空间
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 initSnake(){
struct Snake *p;//定义了一个结构体指针变量
while(head != NULL){
p=head;
head=head->next;
free(p);//释放p变量的内存
}
head=(struct Snake*)malloc(sizeof(struct Snake));//为头节点开辟空间
//头节点初始化
head->row=2;
head->column=1;
head->next=NULL;
tail=head;//第一个节点头尾地址一样
addNode();//增加节点
addNode();
}
有了前面的讲解,相信这一段代码很轻松就能理解了。
如何让🐍身显现出来呢?就要涉及下面的代码
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;
}
else if(hadSnakeNode(row,column)){
printw("[]");
}
注意这两部分是两个地方不同的代码,可以说这两部分”互相呼应“,很明显上面那部分只返回1或0,当为1时下面那部分开始打印🐍身。所以说问题就会回到什么时候会返回1,也就是下面那部分代码:
if(p->row==row && p->column==column){
return 1;
}
可以这样理解,在打印地图时,蛇身的节点坐标(包括横坐标,纵坐标),刚好等于地图的坐标返回1。这里在hadSnakeNode(int row, int column);函数中蛇身的头节点地址赋给了p,通过检验p的地址是否为空,来一遍遍的遍历🐍身(链表),确定打印的🐍身在地图中的显示位置(这里要通过gamePicture();函数)。
好了,今天”🐍身“的显现完成就到这里了,可以自己动手试试,打造属于一条属于自己的小蛇。