Linux编程---贪吃蛇⼩游戏
如何使⽤ncurse
#include<curses.h>
int main()
{
initscr();//ncurse 界⾯的初始化函数
printw("This is curses window\n");//在ncurse模式下的printf
getch();//等待⽤户输⼊,如果没有这句话,程序就退出了,看不到运⾏的结果,也就是看不到上⾯那句话endwin();//程序退出,调⽤改函数来恢复shell终端的显⽰,如果没有这句话,shell终端字乱码,坏掉
return0;
}
编译curses⽂件
gcc xxx.c -lcurses
ncurse的上下左右键
vi /usr/include/curses.h 可查看ncurse的宏定义
#define KEY_DOWN 0402
#define KEY_UP  0403
#define KEY_LEFT 0404
#define KEY_RIGHT 0405
验证代码
#include<curses.h>
int main()
{
int key;
initscr();
keypad(stdscr,1);//设置了可以在stdscr中接受键盘的功能键(快捷键),1代表“是”
while(1){
key =getch();
switch(key){
case KEY_DOWN:
printw("DOWN\n");
break;
case KEY_UP:
printw("UP\n");
break;
case KEY_LEFT:
printw("LEFT\n");
break;
case KEY_RIGHT:
printw("RIGHT\n");
break;
}
}
endwin();
return0;
}
贪吃蛇⼩游戏参考代码
此贪吃蛇⼩游戏的链表插⼊⽅式采⽤的是尾插法,*head 是贪吃蛇的头节点,也是贪吃蛇的尾巴。
#include<ncurses.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#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;//贪吃蛇的头
struct Snake food;//贪吃蛇的⾷物
int key;
int dir;
void initNurses()
{
initscr();//ncurse 界⾯的初始化函数
keypad(stdscr,1);//设置了可以在stdscr中接受键盘的功能键(快捷键),1代表“是”}
void initfood()
{
int x =rand()%19+1;//产⽣1~20的随机数
int y =rand()%20+1;//产⽣1~21的随机数
food.hang = x;
food.lie = y;
}
int hasfood(int i,int j)
{
if(food.hang == i && food.lie == j){
return1;
}
return0;
}
int hasSnakeNode(int hang,int lie)
{
struct Snake *p;
p = head;
while(p !=NULL){
if(p->hang==hang && p->lie == lie){
return1;
}
p = p->next;//遍历贪吃蛇链表
}
return0;
}
void gamePic()
{
int hang;//定义地图位置⾏
int lie;//定义地图位置列
move(0,0);//当按下⽅向键时,让贪吃蛇往所按的⽅向键⼀直⾏⾛
贪吃蛇的编程代码
for(hang=0; hang<=21; hang++){
for(lie=0; lie<=22; lie++){
if(hang==0|| hang==21){//地图第⼀⾏和最后⼀⾏为“--”墙
if(lie==0){
printw(" -");
}else if(lie==22){
printw("- ");
}else{
printw("--");
}
}else if(lie==0){//地图第⼀列和最后⼀列为“|”墙
printw(" |");
}else if(lie==22){
printw("| ");
}else if(hasSnakeNode(hang,lie)){//打印贪吃蛇初始位置
printw("[]");
}else if(hasfood(hang,lie)){//打印贪吃蛇⾷物初始位置
printw("##");
}else{
printw("  ");
}
}
printw("\n");
}
}
void addNode()//通过尾插法增加链表节点
{
struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
new->lie = tail->lie+1;
new->next =NULL;
switch(dir){
case UP://向上移动
new->hang = tail->hang-1;
new->lie = tail->lie;
break;
case RIGHT://向右移动
new->hang = tail->hang;
new->lie = tail->lie+1;
break;
case LEFT://向左移动
new->hang = tail->hang;
new->lie = tail->lie-1;
break;
case DOWN://向下移动
new->hang = tail->hang+1;
new->lie = tail->lie;
break;
}
tail->next =new;
tail =new;//让新的节点成为链表尾节点
}
void deleNode()
{
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->hang =1;
head->lie =1;//贪吃蛇尾巴的初始位置
head->next =NULL;
tail = head;
addNode();
addNode();
addNode();//初始化后的贪吃蛇有4个节点
}
int ifSnakeDie()//贪吃蛇撞死
{
struct Snake *p;
p = head;
if(tail->hang ==0|| tail->lie ==0|| tail->hang ==21|| tail->lie ==22){
return1;//撞墙死
}
while(p->next !=NULL){//撞⾃⼰尾巴死
if(p->hang == tail->hang && p->lie == tail->lie)
return1;
p = p->next;
}
return0;
}
void moveSnake()
{//贪吃蛇每移动⼀个位置相等于链表尾插⼊⼀个节点,链表头节点删除
addNode();//通过尾插法增加链表节点
if(hasfood(tail->hang, tail->lie)){
initfood();//当贪吃蛇吃到⾷物时,重新创造⾷物
}else{//有吃到⾷物就跳过了删除节点,等于增加了⼀个节点,没吃到⾷物执⾏删除节点,实现贪吃蛇⾏⾛动态过程deleNode();//删除头节点
}
if(ifSnakeDie()){//如果贪吃蛇撞死,重新初始化贪吃蛇
initSnake();
}
}
void*refreshJieMian()
{
while(1){
usleep(150000);//时延要放在while的⾸⾏,不然游戏地图容易出现乱码,可调节贪吃蛇⾏⾛速度
moveSnake();//贪吃蛇⾏⾛函数定义
gamePic();//地图界⾯不断刷新
refresh();//刷新的界⾯在同⼀个位置出现
}
}
void turn(int diretion)
{//贪吃蛇在往⼀个⽅向移动时,⽆法通过⼀次按键让它反向移动。例如贪吃蛇在往左⽅向移动时,⽆法通过⼀次按键向右移动。
if(abs(diretion)!=abs(dir)){
dir = diretion;
}
}
}
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()
{
pthread_t t1;
pthread_t t2;
initNurses();//Nurses初始化
initSnake();//贪吃蛇初始化
gamePic();//贪吃蛇地图初始化
pthread_create(&t1,NULL, refreshJieMian,NULL);//创建线程1,让界⾯不断刷新
pthread_create(&t2,NULL, changeDir,NULL);//创建线程线程2,让贪吃蛇接受按键可以转向while(1);//让进程不退出
endwin();
return0;
}
演⽰视频

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。