文章目录
前言
Linux环境下,基于Ncurse图形库的C语言小游戏项目的目的与意义:承上启下
承上:C语言基础,数据结构链表基础,C变量、流程控制、函数、指针、结构体等
启下:Linux系统编程,文件编程,进程,线程,通信,第三方包等
基础操作:
C编程基础、Linux基本操作(编写、编译、运行程序等)
一、背景知识
这款游戏之所以叫贪吃蛇,其真正用意并不是告诉人们要贪心,它所传递的精神是人们只有不断努力地向前才能得到自己想要的食物就像现在社会存在的机会,而人们只有找好自己的目标才能成功。
尽管现在市面上存在的游戏版本很多,可是贪吃蛇的市场还是很大的。原因就在与它能引人入深,爱不释手。可以说该游戏的优势不仅在于它的简单易行,而且在于它很快顺利的运行。对于那些在外忙忙碌碌的人们,想让他们花费大量的时间在大型游戏上显然是不可能的,但是小游戏却刚好能够迎合他们的需求。哈哈
二、实验分析和理解
①首先需要考虑设计一个运行窗口来实时显示结果,
②然后考虑到蛇的身子是一节一节的,此时最容易联想到的数据结构就是顺序表、链表。
如果把蛇比做顺序表或者链表,在之后吃到食物的时候,身子会变长,这就涉及到插入的操作,所以为了更高的效率,我们用链表实现我们的蛇的部分,最初我们把蛇身子按照七个结点打印在屏幕。
③对于蛇的移动,在屏幕上面蛇的移动看起来是整个身子向前方平移一个单位,但是其原理是我们在屏幕的另一个地方把蛇从新打印一遍,又把之前的蛇身子去除掉。
④对于食物的产生,随机的在地图中产生一个节点,在蛇的头坐标(尾节点)和食物的坐标重复的时候,食物消失,蛇的节点数增加一个。
以此往复
直到死亡:蛇头的坐标和蛇身子的坐标重合 或 蛇头坐标与边界重合
三、头文件
#include <curses.h>
#include <stdlib.h>
四、设计流程
五、流程图
六、算法设计
(1)相关变量
int key;//输入的方向
int dir;//实现方向改变
(2)创建链表
贪吃蛇的身体如何保存是游戏的核心,所以我们需要用到链表来保存蛇的身体,这样就可以随时知道蛇身数据。
struct Snake
{
int hang;
int lie;
struct Snake *next;
};
(3)随机出现食物并记录食物出现的坐标
int x = rand()%20 ;
int y = rand()%20 ;
if(x==0)x+=1;
if(y==0)y+=1;
food.hang=x;
food.lie=y;
rand()函数用来产生随机数
(4)绘制初始界面和游戏地图
int hang,lie;
move(0,0);
for(hang=0;hang<20;hang++){
if(hang==0){
for(lie=0;lie<20;lie++){
printw("--");
}
printw("\n"); //打完一行,换行
for(lie=0;lie<=20;lie++){
if(lie==0 || lie==20){
printw("|");
}
else{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 if(hasFood(hang,lie)){
printw("##");
}
else{
printw(" ");
}
}
printw("\n");
}
if(hang==19){
for(lie=0;lie<20;lie++){
printw("--");
}
printw("\n");
}
}
(5)创建节点,初始化蛇身,addNode创建身体
struct Snake *head=NULL;
struct Snake *tail=NULL;
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 initSnake()
{
struct Snake *p;
dir = RIGHT;//初始方向 向右
while(head != NULL){
p=head;
head=head->next;
free(p);
}
initFood();//出现食物
head=(struct Snake *)malloc(sizeof(struct Snake));
head->hang=1;
head->lie=2;
head->next=NULL;
tail=head;
addNode();
addNode();
}
(6)检测是否死亡
struct Snake *p;
p=head;
if(tail->hang<0||tail->lie==0||tail->hang==20||tail->lie==20){//撞边界 return 1 ;
}
while(p->next != NULL){
if(p->hang==tail->hang && p->lie==tail->lie){
return 1 ;
}
p=p->next;
}
return 0 ;