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;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/83055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

django的权限角色管理(RBAC)

在 Django 中&#xff0c;User、Group 和 Permission 是权限系统的核心组件。下面通过代码示例演示它们的 CRUD&#xff08;创建、读取、更新、删除&#xff09; 操作&#xff1a; 一、User 模型 CRUD from django.contrib.auth.models import User# 创建用户 user User.obje…

解决docker alpine缺少字体的问题 Could not initialize class sun.awt.X11FontManager

制作的springboot项目镜像&#xff0c;缺少字体报错Could not initialize class sun.awt.X11FontManager 原因镜像中缺少字体 解决&#xff1a; 制作镜像时&#xff0c;添加字体库&#xff0c;Dockerfile文件 中添加如下内容 注意&#xff1a; jdk版本一定要使用&#xff0…

MQTT 在Spring Boot 中的使用

在 Spring Boot 中使用 MQTT 通常会借助 Spring Integration 项目提供的 MQTT 支持。这使得 MQTT 的集成可以很好地融入 Spring 的消息驱动和企业集成模式。 以下是如何在 Spring Boot 中集成和使用 MQTT 的详细步骤&#xff1a; 前提条件&#xff1a; MQTT Broker&#xff…

养生:为健康生活注入活力

在快节奏的现代生活中&#xff0c;养生不再是老年人的专属&#xff0c;而是每个人维持身心健康的必修课。从饮食到运动&#xff0c;从睡眠到心态&#xff0c;全方位的养生方式能帮助我们抵御压力&#xff0c;拥抱充满活力的生活。 饮食养生&#xff1a;合理搭配&#xff0c;滋…

Axure设计之内联框架切换页面、子页面间跳转问题

在Axure中&#xff0c;你可以通过以下步骤实现主页面中的内联框架在点击按钮时切换页面内容&#xff0c;从A页面切换到B页面。&#xff08;误区&#xff1a;子页面之间切换不要设置“框架中打开链接”然后选“父级框架”这个交互&#xff09; 主框架页面&#xff08;左侧导航展…

[思维模式-38]:看透事物的关系:什么是事物的关系?事物之间的关系的种类?什么是因果关系?如何通过数学的方式表达因果关系?

一、什么是事物的关系&#xff1f; 事物的关系是指不同事物之间存在的各种联系和相互作用&#xff0c;它反映了事物之间的相互依存、相互影响、相互制约等特性。以下从不同维度为你详细阐述&#xff1a; 1、关系的类型 因果关系 定义&#xff1a;一个事件&#xff08;原因&a…

OJ判题系统第6期之判题逻辑开发——设计思路、实现步骤、代码实现(策略模式)

在看这期之前&#xff0c;建议先看前五期&#xff1a; Java 原生实现代码沙箱&#xff08;OJ判题系统第1期&#xff09;——设计思路、实现步骤、代码实现-CSDN博客 Java 原生实现代码沙箱之Java 程序安全控制&#xff08;OJ判题系统第2期&#xff09;——设计思路、实现步骤…

行业趋势与技术创新:驾驭工业元宇宙与绿色智能制造

引言 制造业发展的新格局&#xff1a;创新势在必行 当今制造业正经历深刻变革&#xff0c;面临着供应链波动、个性化需求增长、可持续发展压力以及技能人才短缺等多重挑战。在这样的背景下&#xff0c;技术创新不再是可有可无的选项&#xff0c;而是企业保持竞争力、实现可持…

高效Python开发:uv包管理器全面解析

目录 uv简介亮点与 pip、pip-tools、pipx、poetry、pyenv、virtualenv 对比 安装uv快速开始uv安装pythonuv运行脚本运行无依赖的脚本运行有依赖的脚本创建带元数据的 Python 脚本使用 shebang 创建可执行文件使用其他package indexes锁定依赖提高可复现性指定不同的 Python 版本…

鸿蒙OSUniApp开发富文本编辑器组件#三方框架 #Uniapp

使用UniApp开发富文本编辑器组件 富文本编辑在各类应用中非常常见&#xff0c;无论是内容创作平台还是社交软件&#xff0c;都需要提供良好的富文本编辑体验。本文记录了我使用UniApp开发一个跨平台富文本编辑器组件的过程&#xff0c;希望对有类似需求的开发者有所启发。 背景…

字符串检索算法:KMP和Trie树

目录 1.引言 2.KMP算法 3.Trie树 3.1.简介 3.2.Trie树的应用场景 3.3.复杂度分析 3.4.Trie 树的优缺点 3.5.示例 1.引言 字符串匹配&#xff0c;给定一个主串 S 和一个模式串 P&#xff0c;判断 P 是否是 S 的子串&#xff0c;即找到 P 在 S 中第一次出现的位置。暴力匹…

计算机组成原理:I/O

计算机组成:I/O I/O概述I/O系统构成I/O接口I/O端口两种编址区分I/O数据传送控制方式程序查询方式独占查询中断控制方式硬件判优法(向量中断法)多重中断嵌套DMA控制方式三种DMA方式DMA操作步骤内部异常和中断异常和中断的关系I/O概述 I/O系统构成 一个最基础I/O系统的构成:CPU…

ssti模板注入学习

ssti模板注入原理 ssti模板注入是一种基于服务器的模板引擎的特性和漏洞产生的一种漏洞&#xff0c;通过将而已代码注入模板中实现的服务器的攻击 模板引擎 为什么要有模板引擎 在web开发中&#xff0c;为了使用户界面与业务数据&#xff08;内容&#xff09;分离而产生的&…

NVMe简介2

共分2部分&#xff0c;这里是第2部分。 NVMe数据结构 NVMe协议中规定每个提交命令的大小为64字节&#xff0c;完成命令大小为16字节&#xff0c;NVMe命令分为Admin和IO两类&#xff0c;NVMe的数据块组织方式有PRP和SGL两种。提交命令的格式如图5所示。 图5 提交命令数据格 N…

高压启动电路--学习记录

常见反激的启动电路 优点&#xff1a;电路设计简单&#xff0c;价格便宜 缺点&#xff1a;损坏大&#xff0c;输入宽范围的时候&#xff0c;为了保证低压能正常启动&#xff0c;启动电阻阻值需要选小&#xff0c;那么高压时损耗会非常大&#xff0c;设计的不好很容易在高压时损…

VS打印printf、cout或者Qt的qDebug等传出的打印信息

在vs中打印printf、cout或者Qt的qDebug等常见的打印信息有时也是必要的&#xff0c;简单的叙述一下过程&#xff1a; 1、在vs中打开你的解决方案。 2、鼠标移动到你的项目名称上&#xff0c;点击鼠标右键&#xff0c;再点击属性&#xff0c;此刻会此项目的属性页。 3、在配置…

苍穹外卖--新增菜品

1.需求分析和设计 产品原型 业务规则&#xff1a; 菜品名称必须是唯一的 菜品必须属于某个分类下&#xff0c;不能单独存在 新增菜品时可以根据情况选择菜品的口味 每个菜品必须对应一张图片 接口设计&#xff1a; 根据类型查询分类(已完成) 文件上传 新增菜品 根据类型…

如何高效集成MySQL数据到金蝶云星空

MySQL数据集成到金蝶云星空&#xff1a;SC采购入库-深圳天一-OK案例分享 在企业信息化建设中&#xff0c;数据的高效流转和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例——“SC采购入库-深圳天一-OK”&#xff0c;详细探讨如何通过轻易云数据…

【springcloud学习(dalston.sr1)】使用Feign实现接口调用(八)

该系列项目整体介绍及源代码请参照前面写的一篇文章【springcloud学习(dalston.sr1)】项目整体介绍&#xff08;含源代码&#xff09;&#xff08;一&#xff09; &#xff08;一&#xff09;Feign的理解 前面文章【springcloud学习(dalston.sr1)】服务消费者通过restTemplat…

SpringbBoot nginx代理获取用户真实IP

为了演示多级代理场景&#xff0c;我们分配了以下服务器资源&#xff1a; 10.1.9.98&#xff1a;充当客户端10.0.3.137&#xff1a;一级代理10.0.4.105&#xff1a;二级代理10.0.4.129&#xff1a;三级代理10.0.4.120&#xff1a;服务器端 各级代理配置 以下是各级代理的基本配…