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;

}

相关推荐
纪元A梦1 小时前
贪心算法应用:化工反应器调度问题详解
算法·贪心算法
阿让啊2 小时前
C语言strtol 函数使用方法
c语言·数据结构·c++·单片机·嵌入式硬件
深圳市快瞳科技有限公司2 小时前
小场景大市场:猫狗识别算法在宠物智能设备中的应用
算法·计算机视觉·宠物
liulilittle2 小时前
OPENPPP2 —— IP标准校验和算法深度剖析:从原理到SSE2优化实现
网络·c++·网络协议·tcp/ip·算法·ip·通信
superlls5 小时前
(算法 哈希表)【LeetCode 349】两个数组的交集 思路笔记自留
java·数据结构·算法
田里的水稻5 小时前
C++_队列编码实例,从末端添加对象,同时把头部的对象剔除掉,中的队列长度为设置长度NUM_OBJ
java·c++·算法
纪元A梦5 小时前
贪心算法应用:保险理赔调度问题详解
算法·贪心算法
Florence235 小时前
计算机组成原理:GPU架构、并行计算、内存层次结构等
c语言
Ripple123126 小时前
数据结构:顺序表与链表
数据结构·链表
Jayden_Ruan6 小时前
C++逆向输出一个字符串(三)
开发语言·c++·算法