C语言·贪吃蛇游戏(下)

        上节我们将要完成贪吃蛇游戏所需的前置知识都学完了,那么这节我们就开始动手写代码了

1. 程序规划

        首先我们应该规划好我们的代码文件,设置3个文件:snack.h 用来声明游戏中实现各种功能的函数,snack.c 用来实现函数,test.c 用来测试和运行这个游戏

                        

        然后我们将游戏的大概流程在test.c文件中写出来,因为我们会用到宽字符,所以要记得适配本地中文环境

                

2. 游戏数据结构设计

2.1 蛇身数据结构(链表)

        我们设计用链表来表示蛇身,链表的每个节点中需要存这节蛇身的坐标 x、y 和下一节点的地址,然后我们给蛇身节点结构体类型改个好写一点的名字

        链表的基础知识:数据结构·单链表-CSDN博客

                

2.2 维护整个游戏的结构体

        我们还要创建一个结构体,用来存放当前游戏的种种状态

        

        

        

3. 游戏开始前的初始化

        游戏的开始前初始化都在GameStart()函数中实现,那么我们着手开始写这个函数。

        首先,我们要先创建维护贪吃蛇游戏的结构体,将它的信息传到GameStart()中去,在snack.h中声明这函数,然后再在snack.c中实现它

        

        我们把这个函数种封装的功能先都展示出来,之后就不重复展示了

3.1 控制台信息设置及光标隐藏

        控制台为了美观我们设置成100列30行的,名字就叫做贪吃蛇

        运行以下发现控制台设置好了,并且光标也很好的隐藏了起来

3.2 打印欢迎信息

        WelcomeToGame()函数内部的大部分东西我们上节其实已经写过了,下面就展示一下

3.3 打印地图

        地图大小我们上节已经说过了,要设计一个27行58列的棋盘,然后我们用一个宏把每块墙写出来,方便写打印语句

                        

        在打印墙的时候上边界和下边界挨着打印就行,左边界和右边界的时候要在每次打印之前把光标都定一下位

        展示打印地图的代码:

                

3.4 初始化蛇

        蛇身我们采用链表的结构进行管理。最开始,我们展示5个蛇身,初始的蛇尾巴从(24,5)的位置开始,向右5节之后是蛇头,这里我们采用头插的方式依次创建节点并加入蛇身中。

        同时定义蛇尾初始位置的宏和蛇身形状的宏

                        ​​​​​​​        

        最后将贪吃蛇的所有状态进行初始化

3.5 创建食物

        创建食物时不能随意创建的,要满足一下四点要求:

        1. 食物是随机出现的,就是说坐标是随机的

        2. 坐标必须在墙内    (x:2~54  y:1~25)

        3. 坐标不能在蛇身上

        4. 横坐标必须是偶数

        创建的食物其实就相当于蛇的一段身体,所以我们之间用蛇身节点的结构体类型保存食物的()(位置)信息就行,然后食物的创建要满足上面的要求,最后要注意的是,我们想要生成真随机数,就不要忘了在程序开始时给rand()函数种种子srand()

        ​​​​​​​        ​​​​​​​        ​​​​​​​        

4. 游戏的运行过程

        下面我们来完成GameRun()函数,首先将这个函数中要实现的功能理出来

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

4.1 打印帮助信息

        这个没啥好说的,定好位打印就行

        ​​​​​​​        

4.2 按键逻辑

        写一个do···while循环,当游戏状态是OK的情况下就一直循环,持续检测按键的状态,同时在这里把帮助信息也写一下。我们检测按键的时候写一个宏 KEY_PRESS  内容跟上节的一样,这里我就不展示了,最后我会把所有代码都贴出来的

        ​​​​​​​        

        pause()函数

                        

        

4.3 蛇的移动(走一步)

        这里我们的策略是在蛇头前面再创建一个节点,用来判断蛇要走的下一个位置是否有食物,这里要注意,当蛇向下走的时候不能直接向上走,向右走的时候不能像左走,以此类推。蛇的下一步的位置信息先全都存在新创建的节点中,等待接入蛇身

        

        ​​​​​​​        

4.3.1 蛇头下一步是食物

        ​​​​​​​            

4.3.2 蛇头下一步不是食物

        ​​​​​​​   ​​​​​​​        ​​​​​​​

4.3.3 检测撞墙

        撞墙简单,判断一下蛇头横纵坐标有没有跟墙重合就行

                

4.3.4 检测撞自己

        同理,蛇头的横纵坐标没有跟自身重合就行

5. 游戏结束善后的工作

        善后工作其实就是打印一下蛇的死亡原因,然后把,malloc的内存都释放掉

             ​​​​​​​

6. 复玩功能

        复玩功能我们之前已经写过很多次了,像扫雷中就有很详细的介绍,这里我就简单写一下了

        扫雷请参考:函数·扫雷游戏-CSDN博客

        ​​​​​​​        ​​​​​​​

7. 完整代码

        snack.h

#include<locale.h>
#include<stdlib.h>
#include<stdio.h>
#include<Windows.h>
#include<stdbool.h>
#include<time.h>

#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'

//蛇默认的起始坐标
#define POS_X 24
#define POS_Y 5

#define KEY_PRESS(vk) ((GetAsyncKeyState(vk) & 0x1) ? 1 : 0)

//游戏当前状态
enum GAME_STATUS
{
	OK = 1,//游戏正常运行
	ESC,//玩家按esc要退出
	KILL_BY_WALL,//蛇撞墙死
	KILL_BY_SELF //蛇撞自己死
};

//当前蛇在向哪个方向移动
enum DIRECTION
{
	UP = 1,
	DOWN,
	LEFT,
	RIGHT
};


//蛇身节点
typedef struct SnakeNode
{
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode, * pSnakeNode;



//贪吃蛇
typedef struct Snake
{
	pSnakeNode pSnake;//蛇头位置
	pSnakeNode pFood;//指向食物的指针
	int Score;//当前累计的分数
	int FoodWeight;//一个食物的分数
	//蛇休眠的时间
	//休眠时间越短,蛇移动的越块
	int SleepTime;
	enum GAME_STATUS status;//游戏当前的状态
	enum DIRECTION dir;//蛇当前走的方向
	//···
}Snake, * pSnake;


//修改光标位置
void SetPos(int x, int y);

//游戏开始前的初始化
void GameStart(pSnake ps);

//打印欢迎信息
void WelcomeToGame();
//创建地图
void CreateMap();
//初始化蛇
void InitSnake(pSnake ps);
//创建食物
void CreateFood(pSnake ps);


//游戏的运行过程
void GameRun(pSnake ps);

//打印帮助信息
void PrintHelpInfo();
//蛇的移动
void SnakeMove(pSnake ps);
//蛇头下一步要走的坐标是否是食物
int NextIsFood(pSnake ps,pSnakeNode pNext);
//是食物就吃掉
void EatFood(pSnake ps, pSnakeNode pNext);
//不是食物就走一步
void NotEatFood(pSnake ps, pSnakeNode pNext);
//检测撞墙
void KillByWall(pSnake ps);
//检测撞自己
void KillBySelf(pSnake ps);


//游戏结束善后的善后工作
void GameEnd(pSnake ps);

        snack.c

#include"snack.h"


//修改光标位置
void SetPos(int x, int y)
{
	//获得设备句柄
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	//根据句柄设置光标位置
	COORD pos = { x,y };
	SetConsoleCursorPosition(handle, pos);
}
//打印欢迎信息
void WelcomeToGame()
{
	//欢迎界面
	SetPos(38, 12);
	printf("欢迎来到贪吃蛇小游戏\n");
	SetPos(40, 20);
	system("pause");
	system("cls");//清空屏幕

	//操作介绍界面
	SetPos(20, 10);
	printf("用 ↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");
	SetPos(37, 12);
	printf("加速能得到更高的分数\n");
	SetPos(40, 20);
	system("pause");
	system("cls");//清空屏幕

}



//打印地图
void CreateMap()
{
	int i = 0;
	//上边界
	SetPos(0, 0);
	for (i = 0; i <= 56; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//下边界
	SetPos(0, 26);
	for (i = 0; i <= 56; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//左边界
	for (int i = 1; i <= 25; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc", WALL);
	}

	//右边界
	for (int i = 1; i <= 25; i++)
	{
		SetPos(56, i);
		wprintf(L"%lc", WALL);
	}
}



//初始化蛇
void InitSnake(pSnake ps)
{
	pSnakeNode cur = NULL;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)//节点创建失败
		{
			perror("InitSnake():malloc()");
			return;
		}
		cur->x = POS_X + 2 * i;
		cur->y = POS_Y;
		cur->next = NULL;

		//头插法
		if (ps->pSnake == NULL)
		{
			ps->pSnake = cur;
		}
		else
		{
			cur->next = ps->pSnake;
			ps->pSnake = cur;
		}
	}

	//打印蛇身
	cur = ps->pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}

	//贪吃蛇的其他信息初始化
	ps->dir = RIGHT;
	ps->FoodWeight = 10;
	ps->pFood = NULL;
	ps->Score = 0;
	ps->SleepTime = 200;
	ps->status = OK;
}

//创建食物
void CreateFood(pSnake ps)
{
	int x = 0, y = 0;

again:
	do
	{
		//当x不是偶数就再生成一次
		x = rand() % 53 + 2;
		y = rand() % 24 + 1;
	} while (x % 2 != 0);

	//坐标和蛇的身体的每个节点坐标比较
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		if (x == cur->x && y == cur->y)
		{
			goto again;
		}
		cur = cur->next;
	}

	//创建食物
	pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pFood == NULL)
	{
		perror("CreateFood():malloc()");
		return;
	}

	//食物其实就相当于一段蛇身,吃了之后把它接上去就行
	pFood->x = x;
	pFood->y = y;
	ps->pFood = pFood;
	SetPos(x, y);
	wprintf(L"%lc", FOOD);
}


//游戏开始前的初始化
void GameStart(pSnake ps)
{
	//控制台信息设置
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");

	//隐藏光标
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
	CursorInfo.bVisible = false;
	SetConsoleCursorInfo(handle, &CursorInfo);

	//打印欢迎信息
	WelcomeToGame();

	//打印地图
	CreateMap();

	//初始化蛇
	InitSnake(ps);
	
	//创建食物
	CreateFood(ps);
}





void PrintHelpInfo()
{
	SetPos(62,15);
	printf("1. 不能撞墙,不能咬到自己");
	SetPos(62, 16);
	printf("2. 用 ↑ ↓ ← → 控制蛇的移动"); 
	SetPos(62, 17);
	printf("3. F3为加速,F4为减速");

}

void pause()
{
	while (1)
	{
		Sleep(100);
		if (KEY_PRESS(VK_SPACE))
		{
			break;
		}
	}
}


//蛇头下一步要走的坐标是否是食物
int NextIsFood(pSnake ps, pSnakeNode pNext)
{
	if (ps->pFood->x == pNext->x && ps->pFood->y == pNext->y)
	{
		//下一个坐标是食物
		return 1;
	}
	else
	{
		//不是食物
		return 0;
	}
}

//是食物就吃掉
void EatFood(pSnake ps, pSnakeNode pNext)
{
	//是食物就把新节点头插
	pNext->next = ps->pSnake;
	ps->pSnake = pNext;

	//打印整条蛇
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}
	//得分
	ps->Score += ps->FoodWeight;
	//释放被吃掉的食物
	free(ps->pFood);
	//新建一个食物
	CreateFood(ps);
}

//不是食物就走一步
void NotEatFood(pSnake ps, pSnakeNode pNext)
{
	//先把新节点头插进去
	pNext->next = ps->pSnake;
	ps->pSnake = pNext;
	//再释放一个蛇尾
	pSnakeNode pcur = ps->pSnake;
	while (pcur->next->next)
	{
		//这里捎带着把新蛇身打印
		SetPos(pcur->x, pcur->y);
		wprintf(L"%lc", BODY);
		pcur = pcur->next;
	}
	//先将尾节点的位置打印空白字符
	SetPos(pcur->next->x, pcur->next->y);
	printf("  ");//打印两个空格

	//最后free
	free(pcur->next);
	pcur->next = NULL;
}

//检测撞墙
void KillByWall(pSnake ps)
{
	if (ps->pSnake->x == 0 || \
		ps->pSnake->x == 56 || \
		ps->pSnake->y == 0 || \
		ps->pSnake->y == 26)
	{
		ps->status = KILL_BY_WALL;
	}
}

//检测撞自己
void KillBySelf(pSnake ps) 
{
	//从蛇头的下一个节点开始判断
	pSnakeNode cur = ps->pSnake->next;

	while (cur)
	{
		if (cur->x == ps->pSnake->x && cur->y == ps->pSnake->y)
		{
			//撞到自己身上了
			ps->status = KILL_BY_SELF;
			return;
		}
		cur = cur->next;
	}
}



//蛇的移动
void SnakeMove(pSnake ps)
{
	//在蛇头前创建一个检测下一个节点是什么的节点
	pSnakeNode pNext = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pNext == NULL)
	{
		perror("SnakeMove():malloc()");
		return;
	}
	pNext->next = NULL;

	switch (ps->dir)
	{
	case UP:
		pNext->x = ps->pSnake->x;
		pNext->y = ps->pSnake->y - 1;

		break;
	case DOWN:
		pNext->x = ps->pSnake->x;
		pNext->y = ps->pSnake->y + 1;
		break;
	case LEFT:
		pNext->x = ps->pSnake->x - 2;
		pNext->y = ps->pSnake->y;
		break;
	case RIGHT:
		pNext->x = ps->pSnake->x + 2;
		pNext->y = ps->pSnake->y;
		break;
	}

	//蛇头下一步要走的坐标是否是食物
	if (NextIsFood(ps, pNext))
	{
		//是食物就吃掉
		EatFood(ps, pNext);
	}
	else
	{
		//不是食物就走一步
		NotEatFood(ps, pNext);
	}

	//检测撞墙
	KillByWall(ps);
	//检测撞自己
	KillBySelf(ps);
}

//游戏的运行过程
void GameRun(pSnake ps)
{
	//打印帮助信息
	PrintHelpInfo();

	do
	{
		//当前的分数情况
		SetPos(62, 10);
		printf("总分:%d", ps->Score);
		SetPos(62, 11);
		printf("食物的分值:%02d", ps->FoodWeight);
		
		//检测按键
		//上、下、左、右、ESC、空格、F3、F4
		if (KEY_PRESS(VK_UP) && ps->dir != DOWN)
		{
			ps->dir = UP;
		}
		else if (KEY_PRESS(VK_DOWN) && ps->dir != UP)
		{
			ps->dir = DOWN;
		}
		else if (KEY_PRESS(VK_LEFT) && ps->dir != RIGHT)
		{
			ps->dir = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && ps->dir != LEFT)
		{
			ps->dir = RIGHT;
		}
		else if (KEY_PRESS(VK_ESCAPE))
		{
			//退出游戏
			ps->status = ESC;
			break;
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			//暂停游戏
			pause();
		}
		else if (KEY_PRESS(VK_F3))
		{
			//睡眠时间不能无限减小,控制一下
			if (ps->SleepTime >= 80)
			{
				//加速,休眠时间变短
				ps->SleepTime -= 30;
				//每个食物得分增加
				ps->FoodWeight += 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			//睡眠时间不能无限减小,控制一下
			if (ps->FoodWeight > 2)
			{
				//减速,休眠时间变长
				ps->SleepTime += 30;
				//每个食物得分减少
				ps->FoodWeight -= 2;
			}
		}

		//睡眠一下
		Sleep(ps->SleepTime);
		
		//蛇的移动
		SnakeMove(ps);

	} while (ps->status == OK);
}





//游戏结束善后的善后工作
void GameEnd(pSnake ps)
{
	SetPos(20, 11);
	switch (ps->status)
	{
	case ESC:
		printf("正常退出\n");

		break;
	case KILL_BY_WALL:
		printf("很遗憾,撞墙了!游戏结束\n");
		break;
	case KILL_BY_SELF:
		printf("很遗憾,自杀了!游戏结束\n");
		break;
	}
	//释放贪吃蛇的链表资源
	pSnakeNode cur = ps->pSnake;
	pSnakeNode del = ps->pSnake;
	while (cur)
	{
		del = cur;
		cur = cur->next;
		free(del);
	}
	ps->pSnake = NULL;

	//释放食物节点
	free(ps->pFood);
	ps->pFood = NULL;

}

        test.c

#include"snack.h"

void test()
{
	int ch;//getchar()返回的是整形ASCII码值
	do
	{
		//创建贪吃蛇游戏
		Snake snake = { 0 };
		GameStart(&snake);//游戏开始前的初始化
		GameRun(&snake);//游戏的运行过程
		GameEnd(&snake);//游戏结束善后的工作

		SetPos(25, 15);
		printf("再来一局吗?(Y/N):>");
		ch = getchar();
		getchar();//清理缓冲区的\n
	} while (ch == 'Y');
}


int main()
{
	srand((unsigned int)time(NULL));

	//修改适配本地中文环境
	setlocale(LC_ALL, "");

	//贪吃蛇游戏的测试
	test();

	//控制程序退出结语的位置
	SetPos(0, 27);

	return 0;
}

8. 结语

        那么到此,贪吃蛇游戏就写好了,当然,这个游戏的功能还有美观度还有待各位共同开发,如果说想要给这个游戏图形化一下,大家可以去 easyX 看看EasyX Graphics Library for C++,把这个库下载下来应该就能在VS上用了

        同时,我们的C语言讲解就告一段落了,下一阶段我将着手数据结构的相关知识

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot--08--Mybatis 之Mapper在IDEA中自动注入警告的解决方案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 问题原因 解决方案方法1&#xff1a;为 Autowired 注解设置required false方法2&#xff1a;用 Resource 替换 Autowired方法3&#xff1a;在Mapper接口上加上Repo…

【2024美赛】C题(中英文):网球中的势头Problem C: Momentum in Tennis

【2024美赛】C题&#xff08;中英文&#xff09;&#xff1a;网球中的势头Problem C: Momentum in Tennis 写在最前面2024美赛翻译 —— 跳转链接 中文赛题问题C&#xff1a;网球中的势头使用数据来&#xff1a;提供的文件&#xff1a;词汇表关键术语/概念的词汇表&#xff1a;…

实现车规“芯”业绩突破,世强先进荣膺智芯科技2023优秀代理商奖

1月11日&#xff0c;在智芯半导体科技有限公司&#xff08;下称“智芯科技”&#xff09;举办的“代理商技术大会”上&#xff0c;智芯科技CEO易生海为世强先进&#xff08;深圳&#xff09;科技股份有限公司&#xff08;下称“世强先进”&#xff09;颁发“2023年度优秀代理商…

《Qt》Qt概述(二)

之前介绍了Qt的大致历史&#xff0c;现在我们继续 安装QT 安装软件首选官方网站 Qt 下载官⽹&#xff1a;http://download.qt.io/archive/qt/ 国内清华源&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/ 建议未来的程序员们就使用QT官网下载&#xff0c;虽…

CT图像预处理-去噪

对以下CT图片进行去噪&#xff1a; 左边是原图&#xff0c;右边是去噪后的结果。去噪的同时规避细节模糊的弊端&#xff0c;肌肉和骨头细节保存完整&#xff1a; 参数可调&#xff0c;调整参数后去噪如下&#xff1a; 对于另外的图片&#xff0c;原图如下&#xff1a; 去噪结果…

Xcode 15 及以上版本:libarclite 库缺少问题

参考链接&#xff1a;Xcode 15 libarclite 缺失问题_sdk does not contain libarclite at the path /ap-CSDN博客 报错: SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarcl…

二叉搜索树,力扣

目录 题目地址&#xff1a; 题目&#xff1a; 我们直接看题解吧&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现&#xff1a; 代码补充说明&#xff1a; 代码实现(中序遍历)&#xff1a; 题目地址&#xff1a; 98. 验证二叉搜索树 - 力扣&#xff08;LeetCod…

Web3智能合约:重新定义商业合作的未来

随着区块链技术的飞速发展&#xff0c;Web3时代正逐渐到来&#xff0c;而其中的智能合约成为推动商业合作变革的关键力量。本文将深入探讨Web3智能合约的概念、特点以及对商业合作未来的巨大影响。 什么是Web3智能合约&#xff1f; 智能合约是一种以代码形式编写、自动执行合同…

智能末世战争之机器人的反击

在遥远的未来&#xff0c;地球陷入了一场空前的战争。这场战争不同于以往的任何战争&#xff0c;因为这是由人工智能和机器人主导的战争。在战争爆发之前&#xff0c;人类一直依赖AI和机器人来提高生产效率和生活质量。然而&#xff0c;随着AI技术的飞速发展&#xff0c;机器人…

Open CASCADE学习|曲面上一点的曲率及切平面

曲率&#xff08;Curvature&#xff09;是一个几何学的概念&#xff0c;用于描述一个物体的形状在某一点上的弯曲程度。在我们日常生活中&#xff0c;曲率与我们的生活息息相关&#xff0c;如道路的弯道、建筑物的拱形结构、自然界的山脉等等。了解曲率的概念和计算方法&#x…

GM8775C——DSI 转双通道 LVDS 发送器

1 产品概述 GM8775C 型 DSI 转双通道 LVDS 发送器产品主要实现将 MIPI DSI 转单 / 双通道 LVDS 功能&#xff0c; MIPI 支持 1/2/3/4 通道可选&#xff0c;每通道最高支持 1Gbps 速率&#xff0c;最大支持 4Gbps 速率。 LVDS 时钟频率高达 154MHz &#xff…

C/C++ C++入门

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C_仍有未知等待探索的博客-CSDN博客 目录 一、C关键字 二、命名空间 1、区别 1. C语言 ​编辑 2. C 2、命名空间定义 3、命名空间的使用 三、C输入&输出 四、缺省参数 五、函数重载 六、引用 …

三步实现 Sentinel-Nacos 持久化

一、背景 版本&#xff1a;【Sentinel-1.8.6】 模式&#xff1a;【Push 模式】 参照官网介绍&#xff1a;生产环境下使用Sentinel &#xff0c;规则管理及推送模式有以下3种模式&#xff1a; 比较之后&#xff0c;目前微服务都使用了各种各样的配置中心&#xff0c;故采用Pus…

UE5 虚幻游戏报错常用解决方法(幻兽帕鲁UE5报错)

在体验使用虚幻引擎5、4&#xff08;UE5/UE4&#xff09;开发的游戏如《幻兽帕鲁》时&#xff0c;玩家可能会遇到各种报错情况&#xff0c;例如黑屏、闪退、C运行时错误等。本博客将汇集一系列有效解决方案&#xff0c;通过调整虚幻引擎内置命令行参数以及优化系统环境&#xf…

mysql 批量查询取每一组最新一条数据

AI回答 需求 根据车牌号查询最新的一条交车记录的‘合同号’ &#xff0c;与上面需要类似&#xff0c;这里只需要查询‘合同号’这个字段 方式1 直接把需要查询的字段加上contract_no&#xff0c;直接查&#xff0c;不用子查询 SELECT number_plate,id,contract_no, MAX( …

K8S-NFS-StorageClass

工作流程 K8s中部署NFS-StorageClass K8s的StorageClass提供了为集群动态创建PV的能力。 1.部署NFS服务 2.选择NFS的Provinisoner驱动 K8S中没有内置的NFS的制备器&#xff0c;而定义StorageClass的时候需要指定制备器&#xff08;Pervisioner&#xff09;,所以需要&#xf…

EtherCAT转ModbusTCP网关

一、功能概述 1.1设备简介 本产品是EtherCAT和Modbus TCP网关&#xff0c;使用数据映射方式工作。 本产品在EtherCAT侧作为EtherCAT从站&#xff0c;接TwinCAT、CodeSYS、PLC等&#xff1b;在ModbusTCP侧做为ModbusTCP主站&#xff08;Client&#xff09;或从站&#xff08;…

Windows - 防火墙 - 如何开启单个端口以供Web应用访问(以82端口为例) - 开启端口后还是访问失败了?

Windows - 防火墙 - 如何开启单个端口以供Web应用访问(以82端口为例) - 开启端口后还是访问失败了&#xff1f; 前言 在网上搜“防火墙开启某个端口”供其他机器访问&#xff0c;都是只讲到了“如何允许某个端口被访问”&#xff0c;而没有后续了。 我之前就遇到过这个问题&…

寒假用它练脑子!和AI大战几百回合,锻炼思维逻辑、专注力~

棋类游戏&#xff0c;永远是锻炼思维能力的优选。 下棋对于孩子的成长有诸多好处&#xff0c;比如会让孩子静下心来&#xff0c;锻炼洞察力和专注力。生死对决与全盘的计算&#xff0c;促使思维力扩展。棋盘上的设计和构筑&#xff0c;丰富孩子的想象力等等。 下棋过程中大量的…

docker集成 nacos/nacos-server (包括踩的坑)

tips 这边需要的数据库我已经安装好了&#xff0c;所以数据库的安装这边已经省略了 拉取镜像&#xff08;这边使用nacos1.4.1作为例子&#xff09; docker pull nacos/nacos-server:1.4.1创建映射的文件夹 (conf存放配置文件&#xff0c;logs存放日志文件) mkdir -p /data/n…