一、边界死亡 刷新初始化 refresh( ) ulseep( )
睡眠时间函数 #include <unsitd.h>
用与延迟挂起进程,进程被挂起放倒ready queue
usleep和sleep usleep以微秒为单位 sleep以秒为单位
//界面刷新
void* refreshInterface()
{
while(1){
moveSnake();//移动
gamePic();//打印输出
refresh();//更新终端屏幕
usleep(100000);//控制蛇的运动速度,以微秒为单位,100毫秒睡眠一次,执行挂起不动
}
}
二、循环 自行游走
//扫描键入的值判断方向
void* changeDirection()
{
while(1){
key = getch();
switch(key){
case KEY_DOWN:
dir = DOWN;
break;
case KEY_UP:
dir = UP;
break;
case KEY_LEFT:
dir = LEFT;
break;
case KEY_RIGHT:
dir = RIGHT;
break;
}
}
}
三、循环 方向转换
四、双循环 用线程 #include <pthread.h>
多核是同时运行,单核是争夺CPU的资源。
gcc a.c -lcurses -lpthread -o a 编译
man malloc man手册
:set nu 行号
vim a.c +89 定位到89行
#include <curses.h>//不是标准库 1.sudo apt-get install libncurses5-dev 2.vi /usr/include/crses.h 3.gcc my_snake,c -lcurses
#include <stdio.h>
#include <stdlib.h>//malloc
#include <pthread.h>//Linux线程
#include <unistd.h>//睡眠时间函数usleep()与sleep()类似,用于延迟挂起进程。进程被挂起放到ready queue。
//提供对 POSIX 操作系统(可移植系统)接口 API 的访问功能的头文件的名称,是一组定义了UNIX-like操作系统接口标准的规范,旨在增加移植性和兼容性。
#define UP 1
#define DOWN -1
#define LEFT 2
#define RIGHT -2
//定义贪吃蛇节点结构体
struct Snake
{
int hang;
int lie;
struct Snake *next;
};
struct Snake *head = NULL;//定义蛇尾(链表头)
struct Snake *tail = NULL;//定义蛇头(链表尾)
int key;//记录键入的值 changeDirection()函数中使用到
int dir;//记录方向的值 addNode()函数中使用到
//函数封装初始化Ncurse界面
void initNcurse()
{
initscr();//ncurse界面的初始化函数
keypad(stdscr,1);//从标准stdscr中接受功能键,TRUE代表是否接收
noecho();//大多数的交互式应用程序在初始化时会调用noecho()函数,用于在进行控制操作时不显示输入的控制字符。
}
//判断地图上的点是否是蛇身节点
int judgeSnakeNode(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;
move(0,0);//将光标定位到0行0列 ncurses的性质
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(judgeSnakeNode(hang,lie)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
if(hang==19)
{
for(lie=0;lie<20;lie++){
printw("--");
}
printw("\n");
}
}
printw("by tanyang!");
}
//增加新节点(通过方向判断加在哪)
void addNode()
{
struct Snake *new = (struct Snake *)malloc(sizeof(struct Snake));
switch (dir){//根据键入的值来增加节点,修改tail所指结点中hang,lie并将修改后的值赋值给新节点
case UP:
new->hang=tail->hang-1;
new->lie=tail->lie;
break;
case DOWN:
new->hang=tail->hang+1;
new->lie=tail->lie;
break;
case LEFT:
new->hang=tail->hang;
new->lie=tail->lie-1;
break;
case RIGHT:
new->hang=tail->hang;
new->lie=tail->lie+1;
break;
}
new->next=NULL;
tail->next=new;
tail=new;
}
//初始化蛇身
void initSnake()
{
struct Snake *p;
dir = RIGHT;//蛇头初始方向为RIGHT
while (head!=NULL)
{
p=head;
head=head->next;
free(p);
}
head=(struct Snake *)malloc(sizeof(struct Snake));
head->hang=4;
head->lie=4;
head->next=NULL;
tail=head;//初始时尾指针指向头
addNode();
addNode();
addNode();//增加3节点,设置初始蛇身长度
}
//删除蛇尾(头结点)
void deleteNode()
{
struct Snake *p;
p = head;
head = head->next;
free(p);//释放p=head原先头节点
}
//蛇的移动(蛇头增加新节点,删除蛇尾节点)
void moveSnake()
{
addNode();//增加新节点
deleteNode();//删除蛇尾(头结点)
if(tail->hang==1 || tail->lie==1 || tail->hang==20 || tail->lie==20){//边界
initSnake();
}
}
//界面刷新
void* refreshInterface()
{
while(1){
moveSnake();//移动
gamePic();//打印输出
refresh();//更新终端屏幕
usleep(100000);//控制蛇的运动速度,以微秒为单位,100毫秒睡眠一次,执行挂起不动
}
}
//扫描键入的值判断方向
void* changeDirection()
{
while(1){
key = getch();
switch(key){
case KEY_DOWN:
dir = DOWN;
break;
case KEY_UP:
dir = UP;
break;
case KEY_LEFT:
dir = LEFT;
break;
case KEY_RIGHT:
dir = RIGHT;
break;
}
}
}
int main()
{
pthread_t t1;
pthread_t t2;
initNcurse();
initSnake();
gamePic();
pthread_create(&t1, NULL, refreshInterface, NULL);
pthread_create(&t2, NULL, changeDirection, NULL);
while(1);
getch();//获取用户的输入
endwin();//没有会破坏show的界面
return 0;
}