IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 基于Ncurse实现贪吃蛇 C语言 -> 正文阅读

[C++知识库]基于Ncurse实现贪吃蛇 C语言

一、编程思路

大概思路:

	1、打印出界面(40*40)
		initscr();//ncurses界面的初始化函数
		GraphInterface();//打印界面
		
		getch();//当用户按下某个字符时,函数自动读取,无需按回车
		endwin();//恢复终端机原来的状态
	2、初始化蛇身
		2.1 确定蛇身的初始位置(一个节点)
		2.2 添加蛇神的节点(总共3-4个)

	3、识别键盘,开始对进行蛇进行移动
		3.1移动蛇身

			3.1.1 如向右移动,向右添加一个节点,左边删除一个节点
			3.1.2 如向左移动,向左添加一个节点,右边删除一个节点
			3.1.3 如向上移动,向上添加一个节点,下边删除一个节点
			3.1.4 如向下移动,向下添加一个节点,上边删除一个节点
		
		3.2 移动完蛇身,要进行界面的刷新
			(1)再打印一次页面
			(2)move(0,0);加载到打印函数里面
	4、创建线程th1,让蛇身初始移动方向向右(每半秒刷一次)
	5、创建线程th2,不断检测按键来改变蛇的移动方向
	6、主函数要在程序结束之前有个while(1);防止程序退出;
	7、初始化食物位置,random()随机
	8、界面初始化中,找到食物的位置,打印食物
	9、判断食物是否被蛇碰到,碰到的话添加一个节点
	10、判断食物死亡的情况,两种:边界和碰到自己蛇身

二、代码

#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>
#include <pthread.h>

#define 	UP 		 1
#define 	DOWN 	-1
#define 	LIGHT 	 2
#define 	RIGHT 	-2

int graphLength = 0; 
int graphWide = 0;
int keyValue;
int dir = 0;

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake food;
struct Snake *head = NULL;
struct Snake *tail = NULL;

//蛇食物的位置(随机)
void initFood()
{
	int x=rand()%20;//随机位置
	int y=rand()%20;

	food.hang = x;
	food.lie  = y;
}

int judgeFoodPosition(int hang,int lie)
{
	if(food.hang == hang && food.lie == lie){
		return 1;
	}
	return 0;
}


//确定蛇身的初始位置
int  judgeSnakePositon(int j,int i)
{
	struct Snake *p;
	p = head;

	while(p != NULL){
		//致命的错误 (p->hang = j)少了个等于号
		if(p->hang == j && p->lie == i){			
			return 1;
		}
		p = p->next;	
	}
	return 0;
}

void printInterPointrt(int hang)
{
	
	for (graphWide = 0; graphWide < 40;graphWide++){
		if (graphWide == 0 || graphWide == 39){
			printw("|");
		}
		else if(judgeSnakePositon(hang,graphWide)){	
			printw("O");
		}
		else if( judgeFoodPosition(hang,graphWide)){
			printw("*");
		}
		else
			printw(" ");	
	}
	printw("\n");
}

//整个界面
void GraphInterface()
{
	//是界面一直保存在原来的位置,没有这个就会每刷新一次,界面玩下显示(显示每次的位置都在变化)
	move(0,0);
	for (graphLength = 0; graphLength  < 20; graphLength++){
		if (graphLength == 0){
			for (graphWide = 0; graphWide < 40;graphWide++){
				printw("~");
			}
			printw("\n");
			printInterPointrt(graphLength);

		}
		
		else if (graphLength == 19){
			printInterPointrt(graphLength);
			for (graphWide = 0; graphWide < 39;graphWide++){
				printw("~");
			}		
		}
		else {
			printInterPointrt(graphLength);
		}
		
	}
	printw("\n");
	printw("KEY_VALUE:%d\n",keyValue);
	printw("Food Position:%d %d\n",food.hang,food.lie);
	//printw("This is ncurses interface\n");
}

//删除蛇身的头节点
void deleteSnakeNode()
{
	struct Snake *p = head;
	head = head->next;
	free(p);
}


//添加蛇身节点
void addSnakeBody()
{
	struct Snake *new = (struct Snake*)malloc(sizeof(struct Snake));
	
	switch(dir){
			case DOWN:
				new->hang = tail->hang + 1;
				new->lie = tail->lie;
				break;
			case UP:
				new->hang = tail->hang - 1;
				new->lie = tail->lie ;
				break;
			case LIGHT:
				new->hang = tail->hang;
				new->lie = tail->lie - 1;
				break;
			case RIGHT:
				new->hang = tail->hang;
				new->lie = tail->lie + 1;
				break;//0405
		}
	
	new->next = NULL;

	//尾插法
	tail->next = new;
	tail = new;

}


//蛇的初始位置
void SnakeInitPosition()
{
	dir = RIGHT;//添加的两个节点为右节点

	head = (struct Snake *)malloc(sizeof(struct Snake));
	head->hang	= 0;
	head->lie = 1;
	head->next = NULL;

	tail = head;

	addSnakeBody();
	addSnakeBody();
}

//蛇死亡的情况
int judgeSnakedie()
{
	struct Snake *p;//struct snake p;//致命大小写
	p = head;

	if(tail->lie == 39 || tail->lie == 0 || tail->hang < 0 || tail->hang == 20){
		return 1;//碰墙后,蛇的位置回初始地
	}
	while(p->next != NULL){//(p != NULL)则每次都会重合,p从head走到tail时必定会相撞
		if(p->hang == tail->hang && p->lie == tail->lie){
			return 1;//碰到蛇身,蛇回到初始位置
		}
		p=p->next;
	}

	return 0;
}

//蛇身的变化实现
void moveSnakeBody()
{
	addSnakeBody();	
	deleteSnakeNode();
	if( judgeFoodPosition(tail->hang,tail->lie) ){
		addSnakeBody();//蛇吃到食物,添加一个节点
		initFood(); //重新刷新食物位置(改变食物的位置)
	}
	if(judgeSnakedie()){
		SnakeInitPosition();//碰墙后,蛇的位置回初始地
	}
}

//检测按键,改变蛇身的位置
void* changeSnakePosition()
{
	while(1){			
		moveSnakeBody();//添加一个节点,再删除一个节点,
		GraphInterface();//刷新界面
		usleep(300000);//每隔250ms自己向右移动一格
		//refresh 函数的作用就是刷新物理屏幕
		refresh();
	}

}

//控制蛇只能单方向转动(上下只能执行左右转,左右是只能执行上下转)
void conDirtion(int dir1)
{	
	//abs() 函数用于求整数的绝对值
	if (abs(dir) != abs(dir1)){
		dir = dir1;
	}
}

void* testButtonValue()
{
	
	while(1){
		keyValue = getch();
		switch(keyValue){
			case KEY_DOWN:
				conDirtion(DOWN);
				break;
			case KEY_UP:
				conDirtion(UP);
				break;
			case KEY_LEFT:
				conDirtion(LIGHT);
				break;
			case KEY_RIGHT:
				conDirtion(RIGHT);
				break;//0405
		}
	}
	
}

void NcurseGraphInit()
{
	initscr();//设定所有curses用到的函数的初值
	keypad(stdscr,1);//获取功能键,即上下左右键

	noecho();//oecho(),把无关的东西不要显示在界面
	
}


int main(void)
{
	pthread_t th1;
	pthread_t th2;
	NcurseGraphInit();
	SnakeInitPosition();
	initFood();
	GraphInterface();
	//changeSnakePosition();卡在这里了

	//创建两个线程
	pthread_create(&th1,NULL,changeSnakePosition,NULL);//不断移动蛇身,刷新界面
	pthread_create(&th2,NULL,testButtonValue,NULL);//不断检测键值,打印键值

	//死循环,防止退出界面
	while(1);//没有死循环,创建两个线程之后这个程序有三个资源在竞争CPU,
			//当到main竞争到资源时执行的getch();endwin();就会退出

	getch();//当用户按下某个字符时,函数自动读取,无需按回车
	endwin();//恢复终端机原来的状态

	return 0;
}
/*
	initscr();//ncurses界面的初始化函数
    printw("This is a curses window.\n");//在nucurse 模式下的printf
    getch();//等待用户输入,如果没有这句话,程序就会退出,看不到运行的结果,看不到printw("This is a curses window.\n");
    endwin();//程序退出,调用函数来恢复shell终端的显示,如果没有这句话,shell终端自就会乱码,坏掉
	

*/

三、运行效果

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-29 16:08:07  更:2021-11-29 16:10:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:59:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码