本节详细解释贪吃蛇如何向右移动
通过链表的角度分析一下原理:
走了一步的蛇特点很明显,删去了第一个节点,添加了一个新节点。
以这种编程思路我们来实现这种效果。
我们前面的章节讲解了键位的检测(不懂的去看:e讲解ncurse获取上下左右键)现在我们将这些结合起来。
void addNode()
{
struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));
new->hang = head->hang;
new->lie = tail->lie+1;
new->next = NULL;
tail->next = new;
tail = new;
}
蛇身体移动的过程就是链表节点增加删减的过程,封装函数addNode()来增加节点。
代码如下:
#include <curses.h>
#include <stdlib.h>
struct Snake
{
int hang;
int lie;
struct Snake * next;
};
struct Snake * head;
struct Snake * tail;
void initNcurse()
{
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int i,int j)
{
struct Snake * p;
p = head;
while(p != NULL)
{
if(p->hang == i && p->lie == j)
{
return 1;
}
p = p -> next;
}
return 0;
}
void gamePic()
{
int hang;
int lie;
for(hang = 0;hang < 20;hang ++)
{
if(hang == 0)
{
for(lie = 0;lie < 20;lie ++)
{
printw("--");
}
printw("\n");
}
if(hang >= 0 && hang <= 19)
{
for(lie = 0;lie <= 20;lie ++)
{
if(lie == 0 || lie == 20) printw("|");
else if(hasSnakeNode(hang,lie)) printw("[]");
else printw(" ");
}
printw("\n");
}
if(hang == 19)
{
for(lie = 0;lie < 20;lie ++)
{
printw("--");
}
printw("\n");
printw("by beiweiqiuAC");
}
}
}
void addNode()
{
struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));
new->hang = head->hang;
new->lie = tail->lie+1;
new->next = NULL;
tail->next = new;
tail = new;
}
void initSnake(){
head = (struct Snake *)malloc(sizeof(struct Snake));
head->hang = 2;
head->lie = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleNode()
{
// struct Snake * p;
// p = head;
head = head ->next;
// free(p);
}
void moveSnake()
{
struct Snake * p;
struct Snake * new;
addNode();
deleNode();
p = head;
}
int main()
{
int con;
initNcurse();
initSnake();
gamePic();
while(1)
{
con = getch();
if(con == KEY_RIGHT){
moveSnake();
gamePic();
}
}
getch();//防止程序退出
endwin();
return 0;
}
该文件命名为snake8.c,在终端加入该指令进行编译:
gcc snake.c -lcurses
运行编译出来的可执行文件:
./a.out
执行效果如下:
很明显出现了换行,但小蛇确实向右移动了,下面我们着手解决这个问题。
这个出现的主要原因是因为ncurse的显示机制,ncurse其实是有光标的,当我们按下右键时候,ncurse会在光标的位置将这个地图在打印一遍。
我们希望把新的一张图覆盖在原来的图上,应该如何操作呢?
用库中自带的函数move(0,0);加入到gamePic()中
void gamePic()
{
int hang;
int lie;
move(0,0);
for(hang = 0;hang < 20;hang ++)
{
if(hang == 0)
{
for(lie = 0;lie < 20;lie ++)
{
printw("--");
}
printw("\n");
}
if(hang >= 0 && hang <= 19)
{
for(lie = 0;lie <= 20;lie ++)
{
if(lie == 0 || lie == 20) printw("|");
else if(hasSnakeNode(hang,lie)) printw("[]");
else printw(" ");
}
printw("\n");
}
if(hang == 19)
{
for(lie = 0;lie < 20;lie ++)
{
printw("--");
}
printw("\n");
printw("by beiweiqiuAC");
}
}
}
此时我们就完成了想要的效果:
1.执行程序
2.按下右键
3.再次按下右键
OK,本节我们完成了小蛇向右移动。