当前位置: 首页 > news >正文

C语言 基于Ncurse库的贪吃蛇游戏项目

为了敲键盘及时响应,需要用到ncurse

测试代码: ncurse1.c

/* ncurse1.c */
#include <curses.h> //ncurse的头文件。int main()
{char c;int i = 0;//ncurse界面的初始化函数。initscr(); for(i=0;i<=2;i++){c = getch();printw("\n");//ncurse下的打印函数。printw("Input: %c\n",c); }//等待用户的输入,没有该函数程序会直接退出,看不到printw()的结果。getch(); //调用程序退出函数,恢复shell终端的显示,没有该函数终端可能会乱码。 endwin(); return 0;
}
//输入指令测试 gcc ncurse1.c -lcurses

 游戏的规划实现步骤

  1. Ncurse 函数初始化
  2. 边框图像设置 (for循环)
  3. 贪吃蛇身子节点    (结构体:行,列,下一个节点)
  4. 第一个节点  (静态设置)
  5. 设的整的身子  (静态设置)
  6. 改进 4,5蛇身子的问题, (采用结构体指针指向下一个,尾插法的方式)
  7. 蛇身子向右移动 move(0,0)光标界面不乱,通过按键key来向右行驶, 尾部加节点,注意必须要释放头节点来达到平衡。
  8. 贪吃蛇撞壁  
  9. 主动向右行驶,不需要按键key ,边框图像然后refresh()刷新界面。
  10. 方向键控制蛇变化 , key按键与dir配合,如果key向下,dir就变化,并switch选择增加往那个方向加节点。
  11. 主函数采用linux两个线程,(按键与自动)同时移动,并且都不退出。
  12. 贪吃蛇随机位置的设定。
  13. 咬死自己。

代码:

#include <curses.h>
#include <stdlib.h>#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2struct Snake
{int row;int line;struct Snake* next;
};struct Snake* head = NULL;
struct Snake* tail = NULL;
int key;
int dir;struct Snake food;void initFood()//初始化食物节点
{int x = rand() % 20;//随机出现位置int y = rand() % 20;food.row = x;food.line = y;
}void initNcurse()//初始化curses图形库
{initscr();keypad(stdscr,1);//使用keypad可以在stdscr中接受键盘的功能键noecho();//对于输出的功能键的值不做出回应,以免界面溢出
}int hasSnakeNode(int i,int j)//传参:行号,列号
{struct Snake* p;p = head;while(p != NULL){if(p->row==i && p->line==j){return 1;//gamePic中打印一个节点"[]"}p=p->next;}return 0;
}int hasFood(int i,int j)//打印食物
{if(food.row==i && food.line==j){return 1;}return 0;
}void gamePic()//打印图形界面
{int row;int line;move(0,0);for(row=0;row<20;row++){//第0行为20个"--"if(row==0){for(line=0;line<20;line++){printw("--");}printw("\n");}//第0-19行为左右两边一个"|",中间21个"  "(空格)为了对齐第一行if(row>=0 && row<=19){//一共打印20行for(line=0;line<=20;line++){if(line==0 || line==20){printw("|");//打印两边}else if(hasSnakeNode(row,line)){printw("[]");//打印蛇的身体}else if(hasFood(row,line)){printw("##");//打印食物}else{printw("  ");//打印中间}}printw("\n");}//打印第19行,与第一行一样if(row==19){for(line=0;line<20;line++){printw("--");}printw("\n");printw("by Andy,key = %d\n",key);//打印作者名字以及方向键的值}}
}void addNode()//加节点
{struct Snake* new = (struct Snake*)malloc(sizeof(struct Snake));//开辟新节点空间new->next = NULL;switch(dir){//根据用户按的功能键的方向来决定如何添加一个节点case UP://列不变,行减一的位置添加new->row = tail->row - 1;new->line = tail->line;break;case DOWN:new->row = tail->row + 1;new->line = tail->line;break;case LEFT:new->row = tail->row;new->line = tail->line - 1;break;case RIGHT:new->row = tail->row;new->line = tail->line + 1;break;}tail->next = new;tail = new;//新节点变成尾部
}void deleteNode()//删除节点
{struct Snake* p;p = head;head = head->next;free(p);
}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->row = 1;//第一行head->line = 1;//第一列head->next = NULL;//防止野指针tail = head;//头插法addNode();//加4个节点addNode();addNode();addNode();
}int ifSnakeDie()//蛇死亡的条件
{struct Snake* p;p = head;if(tail->row < 0 || tail->line == 0 || tail->row == 20 || tail->line == 20){//四个边界return 1;}while(p->next != NULL){if(p->row == tail->row && p->line == tail->line){//头咬到尾巴return 1;}p = p->next;}return 0;
}void moveSnake()//蛇的移动
{addNode();if(hasFood(tail->row,tail->line)){initFood();}else{deleteNode();}if(ifSnakeDie()){initSnake();}
}void* refreshBox()//刷新界面
{while(1){moveSnake();//蛇移动gamePic();//重新打印界面refresh();//刷新覆盖原界面usleep(100000);//0.1s}
}void turn(int direction)//绝对值解决方向问题
{if(abs(dir) != abs(direction)){dir = direction;}
}void* changeDir()//根据用户按的功能键走位
{while(1){key = getch();switch(key){case KEY_DOWN:turn(DOWN);//转向break;case KEY_UP:turn(UP);break;case KEY_LEFT:turn(LEFT);break;case KEY_RIGHT:turn(RIGHT);break;}}
}int main()
{initNcurse();//第一步:搭建curses环境initSnake();//第三步:打印蛇的身体gamePic();//第二步:打印图形界面pthread_t th1;//线程1pthread_t th2;//线程2pthread_create(&th1,NULL,refreshBox,NULL);//运行线程1:不断刷新界面pthread_create(&th2,NULL,changeDir,NULL);//运行线程2:不断改变方向while(1);//让线程一直进行getch();//让程序一直重复输入功能键还能执行endwin();//curses函数return 0;
}

还需要不断改进。。。。。。

http://www.lryc.cn/news/12650.html

相关文章:

  • 【Java基础】Java语言特性
  • python进阶--Numyp库(一)
  • CV学习笔记-Inception
  • 注意力机制笔记——结合沐神和B站老弓up主
  • 建议收藏,轻松搞懂区块链
  • php设计一个新春祝福墙
  • KubeSphere 社区双周报 | OpenFunction 集成 WasmEdge | 2023.02.03-02.16
  • 数字IC/FPGA 秋招知识点不全面整理
  • 你知道java8是如何排序Map嘛?
  • 【李忍考研传】一、李忍
  • 测牛学堂:软件测试python深入之类和对象的属性和方法总结
  • css实例--新闻页面
  • SpringCloudGateway 动态转发后端服务
  • 使用canvas写一个flappy bird小游戏
  • KVM-2、虚拟化基础
  • 设计模式之观察者模式与访问者模式详解和应用
  • [SSD固态硬盘技术 18] Over-Provisioning (OP 预留空间)详解,谁“偷”走了SSD的容量?
  • spring注解方式整合Dubbo源码解析
  • 大数值金额大写转换(C语言)
  • 迷宫问题图解 : 基于骨架提取、四邻域
  • 设计模式 - 如何在库和主程序之间互相调用数据和函数
  • Redis面试题:1~2亿条数据需要缓存,请问如何设计这个存储案例
  • 程序员必备的软技能-《如何阅读一本书》
  • Java数据结构-栈、队列常用类(Stack、ArrayDeque、LinkedLList)
  • 拯救了大批爬虫程序员,因为一个简单的神器
  • 2023年美赛C题Wordle预测问题三、四建模及Python代码详细讲解
  • 相关性-回忆录(持续更新)
  • (必备技能)使用Python实现屏幕截图
  • 「数据仓库」怎么选择现代数据仓库?
  • 6.3 使用 Swagger 生成 Web API 文档