C语言从零实现贪吃蛇小游戏

制作不易,点赞关注一下呗!!!

文章目录

  • 前言
  • 一. 技术要点
  • 二、WIN32API介绍
  • 三、贪吃蛇游戏设计与分析 
  •       1.游戏开始前的初始化
  •       2.游戏运行的逻辑 
  • 总结


前言

当我们掌握链表这样的数据结构之后,我们就可以用它来做一些小项目,比如童年小游戏贪吃蛇

目标:在Windows环境中控制台上使用C语言模拟实现经典小游戏贪吃蛇


一.技术要点

C语言函数,枚举,结构体,动态内存管理,预处理指令,链表,Win32API等。

二.Win32API介绍

1.什么是Win32API

Win32 API是微软的操作系统Windows提供给开发人员的编程接口,它决定了我们开发的Windows应用程序的能力。

使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Mircrosoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。

2.控制台程序(Console)

我们平时运行起来出现的黑框框就是控制台。

我们可以通过mode命令来设置窗口大小。

例如:设置为30行,100列

mode con cols=100 lines=30 

在VS上我们可以借助system函数(头文件<windows.h>)来完成这样的命令 

 

 我们也可以通过title命令来修改控制台窗口的名称

title 贪吃蛇

 

3.控制台屏幕上的坐标 COORD

COORD是Win32API中定义的一个结构体,表示一个字符在屏幕缓冲区上的坐标,坐标为(0,0)的原点位于缓冲区的顶部最左侧单元格

typedef struct _COORD {

SHORT X; // horizontal coordinate

SHORT Y; // vertical coordinate

} COORD;

4.GetStdHandle 

GetStdHandle 是Win32API的一个函数,它用于从特定的标准设备(标准输入,标准输出,标准错误)中获取一个句柄(用于标识不同设备的数值),使用这个句柄可以操作设备。

语法

HANDLE GetStdHandle( DWORD nStdHandle );

 参数有三种取值

STD_INPUT_HANDLE

标准输入的句柄

STD_OUTPUT_HANDLE

标准输出的句柄

STD_ERROR_HANDLE

标准错误的句柄

实例:

 

 

5.GetConsoleCursorInfo

功能:检索有关指定控制台光标的大小和可见性

 BOOL WINAPI GetConsoleCursorInfo(
   HANDLE               hConsoleOutput,
   PCONSOLE_CURSOR_INFO  lpConsoleCursorInfo
);

  PCONSOLE_CURSOR_INFO是指向 CONSOLE_CURSOR_INFO这个结构体的指针,该结构接收主机光标的信息。

 

6.SetConsoleCursorInfo 

功能:设置指定控制台屏幕缓冲区的光标大小和可见性

BOOL WINAPI SetConsoleCursorInfo(
  _In_       HANDLE              hConsoleOutput,
  _In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

一般都是配合 GetConsoleCursorInfo函数使用,先用GetConsoleCursorInfo函数获取当前光标信息,再自己手动修改光标信息,最后用SetConsoleCursorInfo 函数设置进去!!!

 

 7.GetAsyncKeyState 

GetAsyncKeyState是一个用来判断函数调用时指定虚拟键的状态,确定用户当前是否按下了键盘上的一个键的函数。

返回类型为short类型,如果返回的16位short类型数据中最高位为1,则表明该键被按下,最高位为0则表示该键抬起,如果最低位为1表示该键被按过,否则为0.

函数名返回值类型备注
GetAsyncKeyStateSHORT用来判断函数调用时指定虚拟键的状态
参数类型说明
vKeyint欲测试的虚拟键的键码

每个键都对应一个虚拟键值,可以自行查找。

8.SetConsoleCursorPosition

有时我们可能不想让字符打印从(0,0)坐标处开始打印,这时就需要用这个函数来设置坐标

使用这个函数需要两个参数:第一个参数类型为HANDLE,第二个参数类型为COORD

实例:

 

三.贪吃蛇游戏设计与分析 

1.游戏开始前的初始化

数据结构的设计:

enum GameStatus
{
	OK,
	ESC,
	KILL_BYWALL,
	KILL_BYSELF,
};
enum DIRECTION
{
	LEFT,
	RIGHT,
	UP,
	DOWN,
};
//蛇身节点
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 GameStatus Status;
	enum DIRECTION dir;
}Snake,*pSnake;

 

 

接下来打印欢迎信息 ,这里我们单独分装两个函数,一个用来设置光标位置,另一个用来打印欢迎信息:

 

下一步:创建地图

 #define WALL L'□'
void CreateMap()
{
	//上
	SetPos(0, 0);
	int i = 0;
	for (i = 0; i < 69; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//下
	SetPos(0,34);
	for (i = 0; i < 69; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//左
	for (i = 0; i < 34; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc", WALL);
	}
	//右
	for (i = 0; i < 34; i++)
	{
		SetPos(68, i);
		wprintf(L"%lc", WALL);
	}
}

 

再下一步:初始化蛇

void InitSnake(pSnake ps)
{
	pSnakeNode cur = NULL;
	//创建5个蛇身节点
	for (int i = 0; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("createsnake malloc");
			exit(1);
		}
		cur->x = 32 + 2 * i;
		cur->y = 7;
		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;//200毫秒
	ps->Status = OK;
}

最后:创建食物 

void CreateFood(pSnake ps)
{
	int x = 0;
	int y = 0;
	again:
	do {
		x = rand() % 66 + 2;
		y = rand() % 33 + 1;
	} while (x % 2 != 0);
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		if (x == cur->x && y == cur->y)
		{
			goto again;
		}
		cur = cur->next;
	}
	pSnakeNode food = (pSnakeNode)malloc(sizeof(pSnake));
	if (!food)
	{
		perror("createfood malloc ");
		exit(1);
	}
	food->x = x;
	food->y = y;
	ps->pFood = food;
	SetPos(x, y);
	wprintf(L"%lc", FOOD);
}

 

最后将这些函数放在GameStart函数中,一起完成游戏开始前的工作 

 

2.游戏运行的逻辑 

第一步:打印帮助信息

 

 第二步:循环检测按键状态

 

 

3.游戏结束的善后 

 


总结

所有代码放在这里:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<string.h>
#include<stdbool.h>
#include<windows.h>
#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'
#define KEY_PRESS(vk)  ((GetAsyncKeyState(vk) & 0x1)? 1: 0)

enum GameStatus
{
	OK,
	ESC,
	KILL_BYWALL,
	KILL_BYSELF,
};
enum DIRECTION
{
	LEFT,
	RIGHT,
	UP,
	DOWN,
};
//蛇身节点
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 GameStatus Status;
	enum DIRECTION dir;
}Snake,*pSnake;

void SetPos(int x, int y);

void GameStart(pSnake snake);

void Welcome();

void CreateMap();

void InitSnake(pSnake ps);

void CreateFood(pSnake ps);

void printhelpinfo();

//游戏运行的逻辑
void GameRun(pSnake ps);
void pause();

void SnakeMove(pSnake ps);
int IsFood(pSnake ps, pSnakeNode next);
void EatFood(pSnake ps, pSnakeNode next);
void NotEatFood(pSnake ps,pSnakeNode next);

void KillByWall(pSnake ps);
void KillBySelf(pSnake ps);

void GameEnd(pSnake ps);

#include"snake.h"
void SetPos(int x, int y)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x,y };
	SetConsoleCursorPosition(handle, pos);
}
void Welcome()
{
	//打印欢迎信息
	SetPos(48, 15);
	printf("欢迎来到贪吃蛇小游戏\n");
	SetPos(50,35);
	system("pause");
	system("cls");

	//打印操作信息
	SetPos(35, 20);
	printf("用↑. ↓. ←. →来控制蛇的移动,F3是加速,F4是减速\n");
	SetPos(48, 22);
	printf("加速能获得更多分数\n");
	SetPos(50, 35);
	system("pause");
	system("cls");
}

void CreateMap()
{
	//上
	SetPos(0, 0);
	int i = 0;
	for (i = 0; i < 69; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//下
	SetPos(0,34);
	for (i = 0; i < 69; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//左
	for (i = 0; i < 34; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc", WALL);
	}
	//右
	for (i = 0; i < 34; i++)
	{
		SetPos(68, i);
		wprintf(L"%lc", WALL);
	}
}

void InitSnake(pSnake ps)
{
	pSnakeNode cur = NULL;
	//创建5个蛇身节点
	for (int i = 0; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("createsnake malloc");
			exit(1);
		}
		cur->x = 32 + 2 * i;
		cur->y = 7;
		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;//200毫秒
	ps->Status = OK;
}

void CreateFood(pSnake ps)
{
	int x = 0;
	int y = 0;
	again:
	do {
		x = rand() % 66 + 2;
		y = rand() % 33 + 1;
	} while (x % 2 != 0);
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		if (x == cur->x && y == cur->y)
		{
			goto again;
		}
		cur = cur->next;
	}
	pSnakeNode food = (pSnakeNode)malloc(sizeof(pSnake));
	if (!food)
	{
		perror("createfood malloc ");
		exit(1);
	}
	food->x = x;
	food->y = y;
	ps->pFood = food;
	SetPos(x, y);
	wprintf(L"%lc", FOOD);
}

void GameStart(pSnake ps)
{
	//修改控制台信息
	system("mode con cols=120 lines=40");
	system("title 贪吃蛇");
	//隐藏光标
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursorinfo;
	GetConsoleCursorInfo(handle, &cursorinfo);
	cursorinfo.bVisible = false;
	SetConsoleCursorInfo(handle, &cursorinfo);
	//打印欢迎信息
	Welcome();
	//绘制地图
	CreateMap();
	//初始化蛇
	InitSnake(ps);
	//创建食物
	CreateFood(ps);
	 
}

void printhelpinfo()
{
	SetPos(80, 18);
	printf("不能穿墙,不能咬到自己\n");
	SetPos(80, 19);
	printf("用↑ . ↓ . ← . →来控制蛇的移动\n");
	SetPos(80, 20);
	printf("F3是加速,F4是减速\n");
}

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


int IsFood(pSnake ps,pSnakeNode next)
{
	if (ps->pFood->x == next->x && ps->pFood->y == next->y)
	{
		return 1;//是食物
	}
	else
		return 0;
} 


void EatFood(pSnake ps, pSnakeNode next)
{
	next->next = ps->pSnake;
	ps->pSnake = next;
	//打印蛇身
	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);
	ps->pFood = NULL;
	//创建新食物
	CreateFood(ps);
}


void NotEatFood(pSnake ps, pSnakeNode next)
{
	//头插法插入
	next->next = ps->pSnake;
	ps->pSnake = next;

	//释放尾节点
	pSnakeNode cur = ps->pSnake;
	while (cur->next->next)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}
	//将尾节点的位置打印成空白字符
	SetPos(cur->next->x, cur->next->y);
	printf("  ");
	free(cur->next);
	cur->next = NULL;

}

void SnakeMove(pSnake ps)
{
	pSnakeNode pnext = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pnext == NULL)
	{
		perror("snakemove malloc");
		exit(1);
	}
	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 (IsFood(ps, pnext))
	{
		//是食物 
		EatFood(ps, pnext);
	}
	else
	{
		//不是食物
		NotEatFood(ps,pnext);
	}
}


void KillByWall(pSnake ps)
{
	if (ps->pSnake->x == 0 || ps->pSnake->x == 68 || ps->pSnake->y == 0 || ps->pSnake->y == 33)
	{
		ps->Status = KILL_BYWALL;
	}

}

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_BYSELF;
			return;
		}
		cur=cur->next;
	}
}


//游戏运行的逻辑
void GameRun(pSnake ps)
{
	//打印帮助信息
	printhelpinfo();
	
	do
	{
		//打印当前分数
		SetPos(80, 13);
		printf("总分:%d\n", ps->Score);
		SetPos(80, 14);
		printf("食物的分值:%02d\n", ps->FoodWeight);
		//检测按键
		//上下左右,空格,F3,F4, ESC
		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);

		//检测撞墙
		KillByWall(ps);

		//检测是否撞到自己
		KillBySelf(ps);
	} while (ps->Status == OK);
}


void GameEnd(pSnake ps)
{
	SetPos(35, 18);
	switch (ps->Status)
	{
	case ESC:
		printf("正常退出\n");
		break;
	case KILL_BYWALL:
		printf("很遗憾,撞到墙,游戏结束\n");
		break;
	case KILL_BYSELF:
		printf("很遗憾,咬到自己了,游戏结束\n");
		break;
	}

	//释放贪吃蛇
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		pSnakeNode next = cur->next;
		free(cur);
		cur = next;
	}
	free(ps->pFood);
	ps = NULL;
}

void test()
{
	int ch = 0;
	do
	{
		Snake snake = { 0 };
		GameStart(&snake);
		GameRun(&snake);
		GameEnd(&snake);
		SetPos(35, 18);
		printf("再来一局吗:Y/N");
		ch=getchar();
		getchar();
	} while (ch == 'y' || ch == 'Y');
}
int main()
{
	setlocale(LC_ALL, "");
    srand((unsigned int)time(NULL));
	test();
	SetPos(55, 35);
	return 0;
}

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

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

相关文章

第12集《佛说四十二章经》

请大家打开讲议第十五面&#xff0c;第三十一章、心寂欲除。 这几章都是佛陀指导我们如何修出离心。前面的经文讲到修出离心&#xff0c;这有对外境与对内心的出离。对外境的出离是指一位初学者&#xff0c;选择一个如法清净的道场安住&#xff0c;这非常重要。唯识学对这个概…

紫微斗数双星组合:天机天梁在辰戌

文章目录 前言内容总结 前言 紫微斗数双星组合&#xff1a;天机天梁在辰戌 内容 紫微斗数双星组合&#xff1a;天机天梁在辰戌 性格分析 在紫微斗数命盘中&#xff0c;天梁星是一颗“荫星”&#xff0c;能够遇难呈祥&#xff0c;化解凶危&#xff0c;主寿&#xff0c;主贵。…

四、JMS规范

JMS规范 一、JMS是什么二、MQ中间件对比三、JMS组成1.JMS Provider2.JMS Producer3.JMS Consumer4.JSM Message4.1 消息头4.2 消息体4.2.1 生产者4.2.2 消费者 4.3 消息属性 四、JMS可靠性1.PERSISTENT - 持久化1.1 参数设置1.2 Queue持久化1.3 Topic持久化1.3.1 持久的发布主题…

开关式稳压电源的工作原理

随着全球对能源问题的重视&#xff0c;电子产品的耗能问题将愈来愈突出&#xff0c;如何降低其待机功耗&#xff0c;提高供电效率成为一个急待解决的问题。传统的线性稳压电源虽然电路结构简单、工作可靠&#xff0c;但它存在着效率低&#xff08;只有40% &#xff0d;50%&…

通过写代码学习AWS DynamoDB (3)- 一致性hash

简介 在本文中&#xff0c;我们将简单介绍一致性hash&#xff08;consistent hash&#xff09;的概念&#xff0c;以及一致性hash可以解决的问题。然后我们将在模拟的DDB实现中实现一个简单版本的基于一致性harsh实现的partition。 问题 在《通过写代码学习AWS DynamoDB &am…

.NET Core MongoDB数据仓储和工作单元模式实操

前言 上一章节我们主要讲解了MongoDB数据仓储和工作单元模式的封装&#xff0c;这一章节主要讲的是MongoDB用户管理相关操作实操。如&#xff1a;获取所有用户信息、获取用户分页数据、通过用户ID获取对应用户信息、添加用户信息、事务添加用户信息、用户信息修改、用户信息删除…

适合新手注册google谷歌账号详细步骤截图演示,记录解决 “此电话号码无法用于进行验证” 问题

目录 手机号码验证问题解决方法具体注册步骤演示1、谷歌浏览器改语言2、点击注册3、选择个人用途4、输入姓名5、输入年月日6、创建登录账号7、设置登录密码8、手机号码验证&#xff08;重点&#xff09;9、手机号码验证成功界面10、关联邮箱备用登录账号设置 手机号码验证问题 …

Java与JavaScript同源不同性

Java是目前编程领域使用非常广泛的编程语言&#xff0c;相较于JavaScript&#xff0c;Java更被人们熟知。很多Java程序员想学门脚本语言&#xff0c;一看JavaScript和Java这么像&#xff0c;很有亲切感&#xff0c;那干脆就学它了&#xff0c;这也间接的帮助了JavaScript的发展…

2.1.1 摄像头

摄像头 更多内容&#xff0c;请关注&#xff1a; github&#xff1a;https://github.com/gotonote/Autopilot-Notes.git 摄像头是目前自动驾驶车中应用和研究最广泛的传感器&#xff0c;其采集图像的过程最接近人类视觉系统。基于图像的物体检测和识别技术已经相当成熟&#…

wayland(xdg_wm_base) + egl + opengles——dma_buf 作为纹理数据源(五)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、EGL dma_buf import 相关的数据结构和函数1. EGLImageKHR2. eglCreateImageKHR()3. glEGLImageTargetTexture2DOES()二、egl 中 import dma_buf 作为纹理的代码实例1. egl_wayland_dmabuf_…

Crypto-RSA2

题目&#xff1a;&#xff08;BUUCTF在线评测 (buuoj.cn)&#xff09; 已知e,n,dp/(dq),c求明文: 首先有如下公式&#xff1a; dp ≡ d mod (p-1) &#xff0c;ed ≡ 1 mod φ(n) &#xff0c;npq &#xff0c;φ(n)(p-1)(q-1) python代码实现如下&#xff1a; import libnu…

[UI5 常用控件] 09.IconTabBar,IconTabHeader,TabContainer

文章目录 前言1. IconTabBar1.1 简介1.2 基本结构1.3 用法1.3.1 颜色&#xff0c;拖放&#xff0c;溢出1.3.2 Icons Only , Inner Contents1.3.3 showAll,Count,key,IconTabSeparator 1.3.4 Only Text1.3.5 headerMode-Inline1.3.6 design,IconTabSeparator-icon1.3.7 DensityM…

云计算基础-虚拟机迁移原理

什么是虚拟机迁移 虚拟机迁移是指将正在运行的虚拟机实例从一个物理服务器&#xff08;或主机&#xff09;迁移到另一个物理服务器&#xff08;或主机&#xff09;的过程&#xff0c;而不会中断虚拟机的运行。 虚拟机拟机迁移分类虚 热迁移&#xff1a;开机状态下迁移 冷迁…

ChatGPT高效提问—prompt实践(健康助手)

ChatGPT高效提问—prompt实践&#xff08;健康助手&#xff09; ​ 随着社会经济的发展&#xff0c;人们的生活条件不断改善&#xff0c;人们对身体健康也日益重现。让ChatGPT作为健康助手也是一件不错的事。开始之前&#xff0c;还是老样子&#xff0c;先设置角色。 ​ 输入…

HTML | DOM | 网页前端 | 常见HTML标签总结

文章目录 1.前端开发简单分类2.前端开发环境配置3.HTML的简单介绍4.常用的HTML标签介绍 1.前端开发简单分类 前端开发&#xff0c;这里是一个广义的概念&#xff0c;不单指网页开发&#xff0c;它的常见分类 网页开发&#xff1a;前端开发的主要领域&#xff0c;使用HTML、CS…

基于Springboot的社区物资交易互助平台(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的社区物资交易互助平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

游戏安全组件运行时发生异常1-0-0

可能是这个服务&#xff0c;可能被禁用了。 如果是文件缺少直接修复游戏

15-k8s控制器资源-deployment/部署控制器

一、deployment部署控制器概念 在学习rc和rs控制器资源时&#xff0c;我们指导&#xff0c;这两个资源都是控制pod的副本数量的&#xff0c;但是&#xff0c;他们两个有个缺点&#xff0c;就是在部署新版本pod或者回滚代码的时候&#xff0c;需要先apply资源清单&#xff0c;然…

云计算基础-网络虚拟化

虚拟交换机 什么是虚拟交换机 虚拟交换机是一种运行在虚拟化环境中的网络设备&#xff0c;其运行在宿主机的内存中&#xff0c;通过软件方式在宿主机内部实现了部分物理交换机的功能&#xff0c;如 VLAN 划分、流量控制、QoS 支持和安全功能等网络管理特性 虚拟交换机在云平…

java8-用流收集数据-6

本章内容口用co1lectors类创建和使用收集器 口将数据流归约为一个值 口汇总:归约的特殊情况 数据分组和分区口 口 开发自己的自定义收集器 我们在前一章中学到&#xff0c;流可以用类似于数据库的操作帮助你处理集合。你可以把Java8的流看作花哨又懒惰的数据集迭代器。它们…