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;

}

相关推荐
地平线开发者2 小时前
ReID/OSNet 算法模型量化转换实践
算法·自动驾驶
地平线开发者2 小时前
开发者说|EmbodiedGen:为具身智能打造可交互3D世界生成引擎
算法·自动驾驶
星星火柴9363 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑4 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
C++、Java和Python的菜鸟5 小时前
第六章 统计初步
算法·机器学习·概率论
Cx330❀5 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
散1126 小时前
01数据结构-Prim算法
数据结构·算法·图论
起个昵称吧6 小时前
线程相关编程、线程间通信、互斥锁
linux·算法
阿巴~阿巴~6 小时前
深入解析C++ STL链表(List)模拟实现
开发语言·c++·链表·stl·list
..过云雨7 小时前
01.【数据结构-C语言】数据结构概念&算法效率(时间复杂度和空间复杂度)
c语言·数据结构·笔记·学习