【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示

这篇具有很好参考价值的文章主要介绍了【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Ncueses库的贪吃蛇小游戏

1、项目简介

  • 视频演示:
    https://www.bilibili.com/video/BV1pt421a7Nu/?spm_id_from=333.999.0.0&vd_source=82b65865be0947de29bd55efc8cdb40a

  • 编译环境:linux(Vmware16.2.4 + Ubantu20.04.3);

  • 小蛇🐍只能在固定的范围内活动;

  • 可以利用键盘方向键控制小蛇🐍的前进方向;

  • 活动范围内会随机生成食物;

  • 小蛇🐍吃到食物,身体将会变长;

  • 小蛇🐍咬到自己或者碰到墙壁将会死亡,重新开始游戏;

完整代码文末奉上,欢迎大家一起交流谈论!

2、项目演示&整体框架

  • 【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示,开源,嵌入式硬件,linux,游戏程序,课程设计

  • 框架
    【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示,开源,嵌入式硬件,linux,游戏程序,课程设计

3、项目介绍

为了方便理解,我将从main() 函数程序的顺序开始讲起,慢慢将各各函数扩展开;

  • main()函数主要分为4块
    • initNcuse() //初始化ncuses,页面以及按键;
    • initSnake()//小蛇🐍的初始化和食物🍔的初始化
    • gamePic()//初始化地形、遍历各各点、打印边界、小蛇🐍 和食物🍔
    • pthread两个进程
      • refreshJieMian()//不断刷新页面
      • changeDir() //不断的检测按键
    • else

3.1、头文件&宏定义&全局变量

  • 本项目所需的头文件、宏定义和全局变量程序如下
    //头文件&宏定义&全局变量
    #include<curses.h>   //图形库
    #include<stdlib.h>
    #include<unistd.h>   //sheep(1)
    #include<pthread.h>  //多线程的头文件
    /*
    #define UP 1
    #define DOWN 2
    #define LEFT 3
    #define RIGHT 4
    *///利用正负的差别,方便为后面控制蛇,不能往倒着走
    #define UP 1
    #define DOWN -1
    #define LEFT 2
    #define RIGHT -2
    
    struct Snake
    {
    	int hang;
    	int lie;
    	struct Snake *next;
    };
    int key;
    int dir;
    struct Snake *head = NULL;
    struct Snake *tail = NULL;
    
    struct Snake food;
    

3.2、初始化ncuses,页面以及按键initNcuse()

  • 分为两步,均是ncurse库的函数
    • 第一:初始化ncurse页面
    • 第二:允许按键的使用

【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示,开源,嵌入式硬件,linux,游戏程序,课程设计

  • initNcuse()

    void initNcuse()
    {
    	initscr();  //初始化ncurse页面
    	keypad(stdscr,1);//允许使用功能键
    //	noecho();//不把无关的信息,功能类的信息显示在页面上
    }
    

3.3、小蛇🐍的初始化和食物🍔的初始化initSnake()

  • 分为5步
    • 第一:初始化小蛇的运动方向;
    • 第二:清空节点,仅留一个头;
    • 第三:随机生成食物;
    • 第四:设置小蛇起始位置;
    • 第五:初始化小蛇长度;

【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示,开源,嵌入式硬件,linux,游戏程序,课程设计

  • initSnake()

    void initFood() //随机生成食物//子函数
    {
           	int x = rand()%20;
    	int y = rand()%20;
    
    	food.hang = x;
    	food.lie = y;
    }
    
    void addNode() //根据方向添加节点,一节🐍//子函数
    {
    	struct Snake *new = (struct Snake*)malloc(sizeof(struct Snake));
    
    	new->next =  NULL;
    	switch(dir)
    	{
    		case UP:
    			new->hang = tail->hang-1;
    			new->lie = tail->lie;
    			break;
    		case DOWN:
    			new->hang = tail->hang+1;
    			new->lie = tail->lie;
    			break;
    		case LEFT:
    			new->hang = tail->hang;
    			new->lie = tail->lie-1;
    			break;
    		case RIGHT:
    			new->hang = tail->hang;
    			new->lie = tail->lie+1;
    			break;
    	}
    	tail->next = new;
    	tail = new;
    }
    
    void initSnake()//初始化
    {
    	struct Snake *p;
    	dir = RIGHT;//刚开始的方向是向右边
    
    	while(head!=NULL)
    	{
    		p = head;   //head向下一个结点移一下,直到最后一个,将所有结点清空,只留一个 head=NULL
    		head = head->next;
    		free(p);
    	}	
    	initFood();//随机生成食物
     	head = (struct Snake*)malloc(sizeof(struct Snake));
    	head->hang = 1; //🐍的起始位子
    	head->lie = 1;  
    	head->next = NULL;
    
    	tail = head; 
    	addNode();
    	addNode();
    	addNode();
    	addNode();
    }
    
    
    

3.4、初始化地形、遍历各各点、打印边界、小蛇🐍 和食物🍔gamePic()

  • 分为三步:
    • 第一:初始化光标;
    • 第二:遍历各点,打印所需;
    • 第三:打印作者及食物位置;

【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示,开源,嵌入式硬件,linux,游戏程序,课程设计

  • gamePic()

    int hasSnakeNode(int i,int j) //这个点有🐍吗?有返回1, 没有返回0
    {
    	struct Snake *p;
    	p = head;
    
    	while(p != NULL) //遍历🐍的身子,是不是这个点
    	{
    		if(p->hang==i && p->lie==j)
    		{
    			return 1;
    		}
    		p = p->next;
    	}	
    	return 0;
    }
    
    int hasFood(int i,int j)//这个点是不是食物所在的点,有的返回1;
    {
    	if(food.hang == i && food.lie == j)//吃到了返回1
    	{
    		return 1;
    	}
    	return 0;//没吃到,返回0
    }
    
    void gamePic()
    {
    	int hang,lie;
    
    	move(0,0);//将光标设定在(0,0)
    	for(hang=0;hang<20;hang++)
    	{
    		if(hang==0)//第一行,打印“------”
    		{
    			for(lie=0;lie<20;lie++)
    			{
    				printw("--");
    			}
    		}
    		if(hang>0 && hang<=19) //打印左右界限
    		{
    			printw("\n");
    			for(lie=0;lie<=20;lie++)
    			{
    				if(lie==0 || lie==20)
    				{
    					printw("|");
    				}
    				else if(hasSnakeNode(hang,lie))//🐍的位置是不是这个点,打印身子
    				{
    					printw("[]");
    				}
    				else if(hasFood(hang,lie))//打印食物的位置
    				{
    					printw("##");
    				}
    				else
    				{
    					printw("  ");
    				}
    			}
    		}
    		if(hang == 19)//最后一行,打印边界“------”
    		{
    			printw("\n");
    			for(lie=0;lie<20;lie++)
    			{
    				printw("--");
    			}
    		}
    	}
    	printw("\nBy TP, food.hang=%d,food.lie=%d\n\n",food.hang,food.lie);
    }
    

3.5 两个进程pthread

  • refreshJieMian()//不断刷新页面

    • moveSnake()
      • 添加蛇头节点;
      • hasFood()//有没有吃到食物
      • ifSnakeDie//小蛇的死亡条件
    • gamePic()//同3.4;
    • refresh() //ncurses库的文件内置函数,只有某次缓存与上次不一样,才输出缓冲区的值;
    • usleep() //让该进程休眠指定us;
  • changeDir() //不断的检测按键

    • getch()//获取键盘输入;
    • 根据键盘输入,改变方向;
  • 其他

    • while(1)//锁定程序,别退了;
    • getch()//等待键盘输入不让程序推出;
    • endwin()//恢复终端
      【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示,开源,嵌入式硬件,linux,游戏程序,课程设计
  • pthread

    void deleNode()//删除🐍尾巴的节点,动起来
    {
    	struct Snake *p;
    	p =head;
    	head = head->next;
    	
    	free(p);
    }
    
    void moveSnake()  //吃到了食物与没吃到食物,蛇的长度和位置的变化;蛇死了怎么办;
    {
    	addNode(); //添加节点
    	if(hasFood(tail->hang,tail->lie)) // 尾结点(头),是不是食物所在的点
    	{                                 
    		initFood(); 	          // 是--重新创建食物--且不删除head(蛇尾) 结点
    	}
    	else
    	{	
    		deleNode();//删除
    	}
    	if(ifSnakeDie()) //如果🐍死了
    	{
    		refresh();//Curses库,屏幕刷新
    		usleep(100000);//暂停100000us
    		initSnake();//小蛇🐍初始化和食物🍔初始化
    	}
    }
    
    int ifSnakeDie()//🐍的死亡条件
    {
    	struct Snake *p;
    	p = head;
    
    	if(tail->hang==0 || tail->lie==0 || tail->hang==20 || tail->lie==20)//撞墙
    	{  
    		return 1;
    	}
    	while(p->next != NULL)//从到了自己吗
    	{
    		if(p->hang == tail->hang && p->lie == tail->lie)
    		{
    			return 1;
    		}
    		p = p->next;
    	}
    	return 0;
    }
    
    void turn(int direction)//防止🐍上下往回走,左右走;
    {
    	if(abs(dir) != abs(direction))//绝对值不一样,才可以转变方向
    	{
    		dir = direction;
    	}
    }
    
    void *refreshJieMian()//进程1  刷新界面
    {
    	while(1)
    	{
    		moveSnake(); //前进一格,
    		gamePic();
    		refresh();
    		usleep(100000);  //0.1s,通过多线程,刷新界面,也起到了调速的作用;
    	}
    }
    
    void *changeDir() //进程2  通过按键改方向
    {
    	while(1)
    	{
    		key = getch();
    		switch(key)
    			{
    				case KEY_DOWN:
    					turn(DOWN);
    					break;
    				case KEY_UP:
    					turn(UP);
    					break;
    				case KEY_LEFT:
    					turn(LEFT);
    					break;
    				case KEY_RIGHT:
    					turn(RIGHT);
    					break;
    			}
    	}
    }
    
    *///将这些放在main函数里面
    pthread_t t1; //定义进程 1
    pthread_t t2; //定义进程 2
    
    pthread_create(&t1,NULL,refreshJieMian,NULL);//不断的刷新界面
    pthread_create(&t2,NULL,changeDir,NULL);     //不断的检测按键输入
    
    while(1);
    
    getch();   //等待键盘输入,不让程序退出
    endwin(); //恢复终端
    */
    

3.6、main()

int main()
{
	pthread_t t1; //定义进程 1
	pthread_t t2; //定义进程 2

	initNcuse(); //初始化ncuses,页面以及按键
	initSnake(); //🐍的初始化和食物
 
	gamePic();   //初始化地形,遍历各各点,打印边界、🐍、和食物
	
	pthread_create(&t1,NULL,refreshJieMian,NULL);//不断的刷新界面
	pthread_create(&t2,NULL,changeDir,NULL);     //不断的检测按键输入

	while(1);

	getch();   //等待键盘输入,不让程序退出
	endwin(); //恢复终端
	return 0;
}

4、代码整合

  • 283行
//snake.c
#include<curses.h>   //图形库
#include<stdlib.h>
#include<unistd.h>   //sheep(1)
#include<pthread.h>
/*
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
*/
#define UP 1
#define DOWN -1
#define LEFT 2
#define RIGHT -2

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};
int key;
int dir;
struct Snake *head = NULL;
struct Snake *tail = NULL;

struct Snake food;

void initFood() //随机生成食物
{
       	int x = rand()%20;
	int y = rand()%20;

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


void initNcuse()
{
	initscr();  //初始化ncurse页面
	keypad(stdscr,1);//允许使用功能键
//	noecho();//不把无关的信息,功能类的信息显示在页面上
}

int hasSnakeNode(int i,int j) //这个点有🐍吗?有返回1, 没有返回0
{
	struct Snake *p;
	p = head;

	while(p != NULL) //遍历🐍的身子,是不是这个点
	{
		if(p->hang==i && p->lie==j)
		{
			return 1;
		}
		p = p->next;
	}	
	return 0;
}

int hasFood(int i,int j)//这个点是不是食物所在的点,有的返回1;
{
	if(food.hang == i && food.lie == j)//吃到了返回1
	{
		return 1;
	}
	return 0;//没吃到,返回0
}


void gamePic()
{
	int hang,lie;

	move(0,0);//将光标设定在(0,0)
	for(hang=0;hang<20;hang++)
	{
		if(hang==0)//第一行,打印“------”
		{
			for(lie=0;lie<20;lie++)
			{
				printw("--");
			}
		}
		if(hang>0 && hang<=19) //打印左右界限
		{
			printw("\n");
			for(lie=0;lie<=20;lie++)
			{
				if(lie==0 || lie==20)
				{
					printw("|");
				}
				else if(hasSnakeNode(hang,lie))//🐍的位置是不是这个点,打印身子
				{
					printw("[]");
				}
				else if(hasFood(hang,lie))//打印食物的位置
				{
					printw("##");
				}
				else
				{
					printw("  ");
				}
			}
		}
		if(hang == 19)//最后一行,打印边界“------”
		{
			printw("\n");
			for(lie=0;lie<20;lie++)
			{
				printw("--");
			}
		}
	}
	printw("\nBy TP, food.hang=%d,food.lie=%d\n\n",food.hang,food.lie);
}

void addNode() //根据方向添加节点,一节🐍
{
	struct Snake *new = (struct Snake*)malloc(sizeof(struct Snake));

	new->next =  NULL;
	switch(dir)
	{
		case UP:
			new->hang = tail->hang-1;
			new->lie = tail->lie;
			break;
		case DOWN:
			new->hang = tail->hang+1;
			new->lie = tail->lie;
			break;
		case LEFT:
			new->hang = tail->hang;
			new->lie = tail->lie-1;
			break;
		case RIGHT:
			new->hang = tail->hang;
			new->lie = tail->lie+1;
			break;
	}
	tail->next = new;
	tail = new;
}

void initSnake()//初始化
{
	struct Snake *p;
	dir = RIGHT;//刚开始的方向是向右边

	while(head!=NULL)
	{
		p = head;   //head向下一个结点移一下,直到最后一个,将所有结点清空,只留一个 head=NULL
		head = head->next;
		free(p);
	}	
	initFood();//随机生成食物
 	head = (struct Snake*)malloc(sizeof(struct Snake));
	head->hang = 1; //🐍的起始位子
	head->lie = 1;  
	head->next = NULL;

	tail = head; 
	addNode();
	addNode();
	addNode();
	addNode();
}

void deleNode()//删除🐍尾巴的节点,动起来
{
	struct Snake *p;
	p =head;
	head = head->next;
	
	free(p);
}

int ifSnakeDie()//🐍的死亡条件
{
	struct Snake *p;
	p = head;

	if(tail->hang==0 || tail->lie==0 || tail->hang==20 || tail->lie==20)//撞墙
	{  
		return 1;
	}
	while(p->next != NULL)//从到了自己吗
	{
		if(p->hang == tail->hang && p->lie == tail->lie)
		{
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void moveSnake()  //吃到了食物与没吃到食物,蛇的长度和位置的变化;蛇死了怎么办;
{
	addNode(); //添加节点
	if(hasFood(tail->hang,tail->lie)) // 尾结点(头),是不是食物所在的点
	{                                 
		initFood(); 	          // 是--重新创建食物--且不删除head(蛇尾) 结点
	}
	else
	{	
		deleNode();//删除
	}
	if(ifSnakeDie()) //如果🐍死了
	{
		refresh();//Curses库,屏幕刷新
		usleep(100000);//暂停100000us
		initSnake();//小蛇🐍初始化和食物🍔初始化
	}
}

void *refreshJieMian()//进程1  刷新界面
{
	while(1)
	{
		moveSnake(); //前进一格,
		gamePic();
		refresh();
		usleep(100000);  //0.1s,通过多线程,刷新界面,也起到了调速的作用;
	}
}

void turn(int direction)//防止🐍上下往回走,左右走;
{
	if(abs(dir) != abs(direction))//绝对值不一样,才可以转变方向
	{
		dir = direction;
	}
}


void *changeDir() //进程2  通过按键改方向
{
	while(1)
	{
		key = getch();
		switch(key)
			{
				case KEY_DOWN:
					turn(DOWN);
					break;
				case KEY_UP:
					turn(UP);
					break;
				case KEY_LEFT:
					turn(LEFT);
					break;
				case KEY_RIGHT:
					turn(RIGHT);
					break;
			}
	}
}

int main()
{
	pthread_t t1; //定义进程 1
	pthread_t t2; //定义进程 2

	initNcuse(); //初始化ncuses,页面以及按键
	initSnake(); //🐍的初始化和食物
 
	gamePic();   //初始化地形,遍历各各点,打印边界、🐍、和食物
	
	pthread_create(&t1,NULL,refreshJieMian,NULL);//不断的刷新界面
	pthread_create(&t2,NULL,changeDir,NULL);     //不断的检测按键输入

	while(1);

	getch();   //等待键盘输入,不让程序退出
	endwin(); //恢复终端
	return 0;
}


欢迎大家一起交流讨论!文章来源地址https://www.toymoban.com/news/detail-832938.html

到了这里,关于【C语言】做一个贪吃蛇小游戏,完整代码&附带视频演示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ❤️创意网页:贪吃蛇游戏 - 创造一个经典的小游戏

    ✨ 博主: 命运之光   🌸 专栏: Python星辰秘典 🐳 专栏: web开发(简单好用又好看) ❤️ 专栏: Java经典程序设计 ☀️ 博主的其他文章: 点击进入博主的主页 前言: 欢迎踏入我的Web项目专栏,一段神奇而令人陶醉的数字世界! 🌌 在这里,我将带您穿越时空,揭开属于

    2024年02月14日
    浏览(61)
  • 【用python做一个贪吃蛇小游戏】

    引言: 贪吃蛇是一款经典的小游戏,它既简单又有趣。在本文中,我们将使用Python编写一个贪吃蛇小游戏,通过这个项目来学习如何利用Python的基础知识和图形界面库来创建一个简单的游戏。 介绍: 贪吃蛇游戏的目标是控制一条蛇在屏幕上移动并吃掉食物,每吃掉一块食物

    2024年02月08日
    浏览(36)
  • 基于C#制作一个贪吃蛇小游戏

    基于C#制作一个贪吃蛇小游戏,简单耐玩,操作简单。

    2024年02月08日
    浏览(41)
  • 【C语言小游戏】贪吃蛇

      使⽤C语⾔在Windows环境的控制台中模拟实现经典⼩游戏贪吃蛇 实现基本的功能: 贪吃蛇地图绘制 蛇吃⻝物的功能 (上、下、左、右⽅向键控制蛇的动作) 蛇撞墙死亡 蛇撞⾃⾝死亡 计算得分 蛇⾝加速、减速 暂停游戏 游戏指引页面 游戏页面 指针; 动态内存; 结构体;

    2024年01月19日
    浏览(30)
  • C语言——贪吃蛇小游戏

    目录 一、ncurse 1.1 为什么需要用ncurse: 1.2 ncurse的输入输出: 1.2.1 如何使用ncurse: 1.2.2 编译ncurse的程序: 1.2.3 测试输入一个按键ncurse的响应速度: 1.3 ncurse上下左右键获取: 1.3.1 如何查看宏定义的.h文件: 1.3.2 ncurse上下左右键获取: 二、地图规划 2.1 地图规划算法显示第一

    2024年02月07日
    浏览(35)
  • C语言-------实现贪吃蛇小游戏

    Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序

    2024年04月29日
    浏览(39)
  • 使用Java实现一个简单的贪吃蛇小游戏

    基于java实现贪吃蛇小游戏,主要通过绘制不同的图片并以一定速度一帧一帧地在窗体上进行展示。 开发工具:eclipse java工具包:jdk1.8 代码地址:https://gitee.com/jay_musu/games-and-tools.git 创建一个新的项目,并命名。创建一个名为images的文件夹用来存放游戏相关图片。然后再在项

    2024年02月11日
    浏览(42)
  • C语言实战项目-贪吃蛇小游戏

    1.定义蛇对象、食物对象 2.初始化蛇、初始化食物 3.控制流程: ( 1)蛇头和墙壁的碰撞 (2)蛇头和蛇身体碰撞 (3)蛇头和食物碰撞 (4)移动速度增大 4.游戏效果: ( 1)蛇身增长 (2)食物消失 -- 新食物产生 (3)分数累加 (4)移动速度增大 (5)蛇的移动 (6)显示分

    2024年02月19日
    浏览(38)
  • python贪吃蛇最简单代码,python代码贪吃蛇小游戏

    大家好,小编来为大家解答以下问题,python贪吃蛇游戏代码详解外加中文,python贪吃蛇最简单代码,现在让我们一起来看看吧! Source code download: 本文相关源码 import pygame import sys import random SCREEN_X=600 SCREEN_Y=600 class Snake(object): def __init__(self): self.direction=pygame.K_RIGHT self.body = []

    2024年02月21日
    浏览(39)
  • 用java写一个贪吃蛇小游戏(源码在最后)

    涉及技能: 循环、分支 方法的抽取 数组的使用 面向对象 继承,子类方法的重写 接口,接口的实现 GUI(图像化界面编程) GUI中的组件: 7.1 窗口 7.2 弹窗 7.3 面板 7.4 文本框 7.5 列表框 7.6 按钮 7.7 图片 7.8 交互的事件:监听事件(鼠标事件,键盘事件) GUI技术,不流行了!!

    2024年02月03日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包