c语言第一个小游戏:贪吃蛇小游戏06

实现贪吃蛇四方向的风骚走位

实现代码

#include <curses.h>

#include <stdlib.h>

struct snake{

int hang;

int lie;

struct snake *next;

};

struct snake *head;

struct snake *tail;

int key;

int dir; //全局变量

#define UP 1 //这个是宏定义,主要就是让人更好理解 ,也为了后期的方向做了铺垫

#define DOWN -1

#define LEFT 2

#define RIGHT -2

void initNcurse()

{

initscr();

keypad(stdscr,1);

noecho();

}

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;

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 shijintao\n");

printw("key =%d\n",key);

}

void addNode()

{

struct snake *new;

new =(struct snake *)malloc(sizeof(struct snake));

new->next=NULL;

switch(dir){

case UP:

new->hang=tail->hang-1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case DOWN:

new->hang=tail->hang+1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case LEFT:

new->lie=tail->lie-1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

case RIGHT:

new->lie=tail->lie+1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

}

}

当为dir为up的时候 hang变,lie不变

当为dir为down的时候 hang变,lie不变

当为dir为left的时候 lie变,hang不变

当为dir为right的时候 lie变,hang不变

void initSnake()

{

struct snake *p;

dir = RIGHT; //这边我们设置了一个初始方向 dir是全局变量

while(head != NULL){

p=head;

head=head->next;

free(p);

}

head = (struct snake *)malloc(sizeof(struct snake));

head->hang=2;

head->lie=2;

head->next=NULL;

tail = head;

addNode();

addNode();

}

void deleteNode()

{

struct snake *p;

p = head;

head = head->next;

free(p);

}

void moveSnake()

{

addNode();

deleteNode();

if(tail->hang==0||tail->hang==20||tail->lie==20||tail->lie==0){

initSnake();

}

}

void * changeDir()

{

while(1){

key =getch();

switch(key){ //这个key是全局变量 会通过changeDir函数改变

case KEY_DOWN:

dir = DOWN; //这个DOWN是通过宏定义定义的

break;

case KEY_UP:

dir = UP;

break;

case KEY_RIGHT:

dir = RIGHT;

break;

case KEY_LEFT:

dir = LEFT;

break;

}

}

}

void * gamerefresh()

{

while(1){

moveSnake();

gamepic();

refresh();

usleep(100000);

}

}

int main()

{

pthread_t th1;

pthread_t th2;

initNcurse();

initSnake();

gamepic();

pthread_create(&th2,NULL,gamerefresh,NULL);

pthread_create(&th1,NULL,changeDir,NULL);

while(1);//死循环不能让主线程退出,这样就可以一直玩游戏了

getch();

endwin();

return 0;

}

优化代码(方向相反不能直接走)

#include <curses.h>

#include <stdlib.h>

struct snake{

int hang;

int lie;

struct snake *next;

};

struct snake *head;

struct snake *tail;

int key;

int dir;

#define UP 1

#define DOWN -1

#define LEFT 2

#define RIGHT -2

void initNcurse()

{

initscr();

keypad(stdscr,1);

noecho(); //这个就是ncurse的按键盘的时候会弹出来乱七八糟的符号,输入这个就可以去掉,不然地图很奇怪,很多乱七八糟的符号

}

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;

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 shijintao\n");

printw("key =%d\n",key);

}

void addNode()

{

struct snake *new;

new =(struct snake *)malloc(sizeof(struct snake));

new->next=NULL;

switch(dir){

case UP:

new->hang=tail->hang-1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case DOWN:

new->hang=tail->hang+1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case LEFT:

new->lie=tail->lie-1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

case RIGHT:

new->lie=tail->lie+1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

}

}

void initSnake()

{

struct snake *p;

while(head != NULL){

p=head;

head=head->next;

free(p);

}

head = (struct snake *)malloc(sizeof(struct snake));

dir = RIGHT;

head->hang=2;

head->lie=2;

head->next=NULL;

tail = head;

addNode();

addNode();

}

void deleteNode()

{

struct snake *p;

p = head;

head = head->next;

free(p);

}

void moveSnake()

{

addNode();

deleteNode();

if(tail->hang==0||tail->hang==20||tail->lie==20||tail->lie==0){

initSnake();

}

}

void turn(int direction)

{

if(abs(dir) != abs(direction)){

dir = direction;

}

}

//这段代码就是更改贪吃蛇不能相反移动的核心了,利用abs绝对值的方法,这个direction是新的方向,这个dir是旧方向 ,在这边我们设置左右上下的值互为相反数,如果他们的绝对值相等的话,那我们就不把新方向替代旧方向,说白了我白说了,只要绝对值相等,那么就不会换方向,只要绝对值不相等,就换方向,这个值取决于你在宏定义里面的设置,就像下面的一样

//#define UP 1

//#define DOWN -1

//#define LEFT 2

//#define RIGHT -2

void * changeDir()

{

while(1){

key =getch();

switch(key){

case KEY_DOWN:

turn(DOWN);

break;

case KEY_UP:

turn(UP);

break;

case KEY_RIGHT:

turn(RIGHT);

break;

case KEY_LEFT:

turn(LEFT);

break;

}

}

}

void * gamerefresh()

{

while(1){

moveSnake();

gamepic();

refresh();

usleep(100000);

}

}

int main()

{

pthread_t th1;

pthread_t th2;

initNcurse();

initSnake();

gamepic();

pthread_create(&th2,NULL,gamerefresh,NULL);

pthread_create(&th1,NULL,changeDir,NULL);

while(1);

getch();

endwin();

return 0;

}

相关推荐
地平线开发者1 小时前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮2 小时前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者2 小时前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考2 小时前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习
HXhlx6 小时前
CART决策树基本原理
算法·机器学习
Wect6 小时前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
颜酱7 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法
Gorway13 小时前
解析残差网络 (ResNet)
算法
拖拉斯旋风13 小时前
LeetCode 经典算法题解析:优先队列与广度优先搜索的巧妙应用
算法
Wect13 小时前
LeetCode 207. 课程表:两种解法(BFS+DFS)详细解析
前端·算法·typescript