MonoGame 游戏开发框架日记 -06

第六章:动画类以及动画精灵

好久不见家人们好久没更新MonoGame系列了,不是主包弃坑了,主要是主包最近忙着搞项目学科一找暑假工打,这不一闲下来就立刻马不停蹄的来给大家更新了,今天的教程代码部分比较多接下来我们正式开始!!!


动画类:

我们知道现在许多像素独立游戏都是使用帧动画的方式来处理以及修改动画,当然了也不乏有使用骨骼动画来实现的独立游戏,但我们这个教程使用的是帧动画来实现一个最简单的动画,在学习Animation类之前我们得先学习一下什么是帧动画,在1907年逐帧动画由一位无名的技师发明,一开始作为一种实验性视频在早期的影视作品中大显风头。 起初这个技术并不被世人了解,后来,法国艾米尔科尔发现了这个独特的技术并制作了很多优秀的早期逐帧动画代表作,如逐帧定格木偶剧《小浮士德 Les Allumettes》 (1908)。 “生命之轮”(Zoerope)1867年作为玩具出现在美国,转动圆盘,透过缝隙就能看到运动形象。这个就是帧动画的前身,那么我们该如何实现这个类容呢。

第一步:创建文件并定义

我们书接上回,上次我们创建了Texture,Sprite等等的类,那么这次我们同样在Graphics文件夹下创建文件 Animation.cs

接着写入下面代码:

using System;
using System.Collections.Generic;namespace SlimeGame.Graphics;public class Animation
{/// <summary>/// 帧序列:存储所有帧图片/// </summary> /// <value></value>public List<TextureRegion> Frames { get; set; }/// <summary>/// 帧间隔:存储每帧的时间间隔/// </summary> /// <value></value>public TimeSpan Delay { get; set; }/// <summary>/// 无参构造/// </summary>public Animation(){Frames = new List<TextureRegion>();Delay = TimeSpan.FromMilliseconds(100);}/// <summary>/// 有参构造/// </summary>public Animation(List<TextureRegion> frames, TimeSpan delay){Frames = frames;Delay = delay;}
}

第二步:修改TextureAtlas.cs使其适配Animation组件

我们回到Atlas文件的设置,我们需要修改非常多的内容接下来我们一起来修改

我们在代码中增加一个字典,用来存储所有有的动画
private Dictionary<string, Animation> Animations;
我们修改定义文件在定义中添加以下代码,为动画字典申请空间
/// <summary>
/// 无参构造
/// </summary>
public TextureAtlas()
{Regions = new Dictionary<string, TextureRegion>();Animations = new Dictionary<string, Animation>();
}/// <summary>
/// 有参构造
/// </summary>
public TextureAtlas(Texture2D texture)
{TotalTexture = texture;Regions = new Dictionary<string, TextureRegion>();Animations = new Dictionary<string, Animation>();
}
再然后就是我们最熟悉的增删查该环节了
	/// <summary>/// 在字典中增加动画/// </summary>/// <param name="animationName">动画对应名称/键</param>/// <param name="animation">动画本体</param>public void AddAnimation(string animationName, Animation animation){Animations.Add(animationName, animation);}/// <summary>/// 得到当前动画/// </summary>/// <param name="animationName">动画名称</param>/// <returns>动画本体</returns>public Animation GetAnimation(string animationName){return Animations[animationName];}/// <summary>/// 从字典中移除动画/// </summary>/// <param name="animationName">动画名称/键</param>/// <returns>是否移除</returns>public bool RemoveAnimation(string animationName){return Animations.Remove(animationName);}// 清空字典public void AnimationsClear(){Animations.Clear();}
最后一步,修改文件加载方式

还记得我们上次使用XML文件加载的那个内容吗,这次我们一次性搞定,可能包括以后这部分模板部分的代码我们都不会再次修改了我们一起加油哦

	/// <summary>/// 从文件中加载纹理/// </summary>/// <param name="content">文件资源管理</param>/// <param name="fileName">文件名称</param>/// <returns></returns>public static TextureAtlas FromFile(ContentManager content, string fileName){TextureAtlas atlas = new TextureAtlas();// 合并文件名成完整项目路径string filePath = Path.Combine(content.RootDirectory, fileName);//文件流式存储using (Stream stream = TitleContainer.OpenStream(filePath)){// Xml读取器的获得using (XmlReader reader = XmlReader.Create(stream)){// 读XMl的文件内容XDocument doc = XDocument.Load(reader);XElement root = doc.Root;// <Texture> 该元素包含要加载的 Texture2D 的内容路径.// 因此,我们将检索该值,然后使用内容管理器加载纹理.string texturePath = root.Element("Texture").Value;atlas.TotalTexture = content.Load<Texture2D>(texturePath);// <Regions> 该元素包含单独的<Region>元素,每个元素描述// 图集中的其他纹理区域.  //// 例子:// <Regions>//      <Region name="spriteOne" x="0" y="0" width="32" height="32" />//      <Region name="spriteTwo" x="32" y="0" width="32" height="32" />// </Regions>//// 因此,我们检索所有<Region>元素,然后遍历每个元素,从中生成一个新的 TextureRegion 实例,并将其添加到此图集.var regions = root.Element("Regions")?.Elements("Region");if (regions != null){foreach (var region in regions){string name = region.Attribute("name")?.Value;int x = int.Parse(region.Attribute("x")?.Value ?? "0");int y = int.Parse(region.Attribute("y")?.Value ?? "0");int width = int.Parse(region.Attribute("width")?.Value ?? "0");int height = int.Parse(region.Attribute("height")?.Value ?? "0");if (!string.IsNullOrEmpty(name)){atlas.AddRegion(name, x, y, width, height);}}}// <Animations> 该元素包含单独的<Animation>元素,每个元素描述// 在图集中的不同动画//// Example:// <Animations>//      <Animation name="animation" delay="100">//          <Frame region="spriteOne" />//          <Frame region="spriteTwo" />//      </Animation>// </Animations>//// 因此,我们检索所有<Animation>元素,然后遍历每个元素// 并从中生成新的 Animation 实例并将其添加到此图集.var animationElements = root.Element("Animations").Elements("Animation");if (animationElements != null){foreach (var animationElement in animationElements){string name = animationElement.Attribute("name")?.Value;float delayInMilliseconds = float.Parse(animationElement.Attribute("delay")?.Value ?? "0");TimeSpan delay = TimeSpan.FromMilliseconds(delayInMilliseconds);List<TextureRegion> frames = new List<TextureRegion>();var frameElements = animationElement.Elements("Frame");if (frameElements != null){foreach (var frameElement in frameElements){string regionName = frameElement.Attribute("region").Value;TextureRegion region = atlas.GetRegion(regionName);frames.Add(region);}}Animation animation = new Animation(frames, delay);atlas.AddAnimation(name, animation);}}return atlas;}}}

至此我们Atlas的修改到此结束


第三步:创建AnimationSprite.cs

这个类是什么呢,这个就是用来在场景中渲染出这个动画的类效果,也就是每帧他会渲染出不同的Sprite而上面哪个Ainmation只起到存储的作用,Ok我们直接开始

using System;
using Microsoft.Xna.Framework;namespace SlimeGame.Graphics;public class AnimatedSprite : Sprite
{/// <summary>/// 当前帧下标/// </summary>private int CurrentFrame;/// <summary>/// 时间间隔/// </summary> private TimeSpan Elapsed;/// <summary>/// 所用动画/// </summary>private Animation animation;public Animation Animation{get => animation;set{animation = value;Region = animation.Frames[0];}}/// <summary>/// 无参构造/// </summary>public AnimatedSprite() { }/// <summary>/// 有参构造/// </summary>/// <param name="animation">动画</param> public AnimatedSprite(Animation animation){Animation = animation;}/// <summary>/// 循环播放当前动画组件/// </summary>/// <param name="gameTime"></param> public void Update(GameTime gameTime){Elapsed += gameTime.ElapsedGameTime;if (Elapsed >= animation.Delay){Elapsed -= animation.Delay;CurrentFrame++;if (CurrentFrame >= animation.Frames.Count){CurrentFrame = 0;}Region = animation.Frames[CurrentFrame];}}
}

然后我们再次返回Atlas在最后完成这个操作

	public AnimatedSprite CreateAnimatedSprite(string animationName){Animation animation = GetAnimation(animationName);return new AnimatedSprite(animation);}

那么接写下来我们所要做的工作就全部完成了那么我们接下来给出我们本章所有修改的代码:

Animation.cs

using System;
using System.Collections.Generic;namespace SlimeGame.Graphics;public class Animation
{/// <summary>/// 帧序列:存储所有帧图片/// </summary> /// <value></value>public List<TextureRegion> Frames { get; set; }/// <summary>/// 帧间隔:存储每帧的时间间隔/// </summary> /// <value></value>public TimeSpan Delay { get; set; }/// <summary>/// 无参构造/// </summary>public Animation(){Frames = new List<TextureRegion>();Delay = TimeSpan.FromMilliseconds(100);}/// <summary>/// 有参构造/// </summary>public Animation(List<TextureRegion> frames, TimeSpan delay){Frames = frames;Delay = delay;}
}

TextureAtlas.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;namespace SlimeGame.Graphics;/// <summary>
/// 图集类:存储纹理集和
/// </summary> 
public class TextureAtlas
{/// <summary>/// 存储每个纹理的字典/// </summary>private Dictionary<string, TextureRegion> Regions;/// <summary>/// 存储每个动画的字典/// </summary>private Dictionary<string, Animation> Animations;/// <summary>/// 所需总体的纹理图片/// </summary>public Texture2D TotalTexture { get; set; }/// <summary>/// 无参构造/// </summary>public TextureAtlas(){Regions = new Dictionary<string, TextureRegion>();Animations = new Dictionary<string, Animation>();}/// <summary>/// 有参构造/// </summary>/// <param name="texture">所需总体纹理</param>public TextureAtlas(Texture2D texture){TotalTexture = texture;Regions = new Dictionary<string, TextureRegion>();Animations = new Dictionary<string, Animation>();}/// <summary>/// 在图集里增加纹理/// </summary>/// <param name="name">纹理对应名称/键</param>/// <param name="x">纹理切割X坐标</param>/// <param name="y">纹理切割Y坐标</param>/// <param name="width">纹理切割宽度</param>/// <param name="height">纹理切割高度</param>public void AddRegion(string name, int x, int y, int width, int height){TextureRegion region = new TextureRegion(TotalTexture, x, y, width, height);Regions.Add(name, region);}/// <summary>/// 在字典中增加动画/// </summary>/// <param name="animationName">动画对应名称/键</param>/// <param name="animation">动画本体</param>public void AddAnimation(string animationName, Animation animation){Animations.Add(animationName, animation);}/// <summary>/// 从字典中查询纹理/// </summary>/// <param name="name">对应字典名字/键</param>/// <returns>纹理</returns>public TextureRegion GetRegion(string name){return Regions[name];}/// <summary>/// 得到当前动画/// </summary>/// <param name="animationName">动画名称</param>/// <returns>动画本体</returns>public Animation GetAnimation(string animationName){return Animations[animationName];}/// <summary>/// 从字典中移除纹理/// </summary>/// <param name="name">对应字典名字/键</param>/// <returns>是否删除</returns>public bool RemoveRegion(string name){return Regions.Remove(name);}/// <summary>/// 从字典中移除动画/// </summary>/// <param name="animationName">动画名称/键</param>/// <returns>是否移除</returns>public bool RemoveAnimation(string animationName){return Animations.Remove(animationName);}/// <summary>/// 清空此字典/// </summary>public void RegionsClear(){Regions.Clear();}public void AnimationsClear(){Animations.Clear();}/// <summary>/// 从文件中加载纹理/// </summary>/// <param name="content">文件资源管理</param>/// <param name="fileName">文件名称</param>/// <returns></returns>public static TextureAtlas FromFile(ContentManager content, string fileName){TextureAtlas atlas = new TextureAtlas();// 合并文件名成完整项目路径string filePath = Path.Combine(content.RootDirectory, fileName);//文件流式存储using (Stream stream = TitleContainer.OpenStream(filePath)){// Xml读取器的获得using (XmlReader reader = XmlReader.Create(stream)){// 读XMl的文件内容XDocument doc = XDocument.Load(reader);XElement root = doc.Root;// <Texture> 该元素包含要加载的 Texture2D 的内容路径.// 因此,我们将检索该值,然后使用内容管理器加载纹理.string texturePath = root.Element("Texture").Value;atlas.TotalTexture = content.Load<Texture2D>(texturePath);// <Regions> 该元素包含单独的<Region>元素,每个元素描述// 图集中的其他纹理区域.  //// 例子:// <Regions>//      <Region name="spriteOne" x="0" y="0" width="32" height="32" />//      <Region name="spriteTwo" x="32" y="0" width="32" height="32" />// </Regions>//// 因此,我们检索所有<Region>元素,然后遍历每个元素,从中生成一个新的 TextureRegion 实例,并将其添加到此图集.var regions = root.Element("Regions")?.Elements("Region");if (regions != null){foreach (var region in regions){string name = region.Attribute("name")?.Value;int x = int.Parse(region.Attribute("x")?.Value ?? "0");int y = int.Parse(region.Attribute("y")?.Value ?? "0");int width = int.Parse(region.Attribute("width")?.Value ?? "0");int height = int.Parse(region.Attribute("height")?.Value ?? "0");if (!string.IsNullOrEmpty(name)){atlas.AddRegion(name, x, y, width, height);}}}// <Animations> 该元素包含单独的<Animation>元素,每个元素描述// 在图集中的不同动画//// Example:// <Animations>//      <Animation name="animation" delay="100">//          <Frame region="spriteOne" />//          <Frame region="spriteTwo" />//      </Animation>// </Animations>//// 因此,我们检索所有<Animation>元素,然后遍历每个元素// 并从中生成新的 Animation 实例并将其添加到此图集.var animationElements = root.Element("Animations").Elements("Animation");if (animationElements != null){foreach (var animationElement in animationElements){string name = animationElement.Attribute("name")?.Value;float delayInMilliseconds = float.Parse(animationElement.Attribute("delay")?.Value ?? "0");TimeSpan delay = TimeSpan.FromMilliseconds(delayInMilliseconds);List<TextureRegion> frames = new List<TextureRegion>();var frameElements = animationElement.Elements("Frame");if (frameElements != null){foreach (var frameElement in frameElements){string regionName = frameElement.Attribute("region").Value;TextureRegion region = atlas.GetRegion(regionName);frames.Add(region);}}Animation animation = new Animation(frames, delay);atlas.AddAnimation(name, animation);}}return atlas;}}}public Sprite CreatSprite(string regionName){TextureRegion region = GetRegion(regionName);return new Sprite(region);}public AnimatedSprite CreateAnimatedSprite(string animationName){Animation animation = GetAnimation(animationName);return new AnimatedSprite(animation);}
}

AnimationSprite.cs

using System;
using Microsoft.Xna.Framework;namespace SlimeGame.Graphics;public class AnimatedSprite : Sprite
{/// <summary>/// 当前帧下标/// </summary>private int CurrentFrame;![请添加图片描述](https://i-blog.csdnimg.cn/direct/366178daee0142a281f38ec525f0be24.gif)/// <summary>/// 时间间隔/// </summary> private TimeSpan Elapsed;/// <summary>/// 所用动画/// </summary>private Animation animation;public Animation Animation{get => animation;set{animation = value;Region = animation.Frames[0];}}/// <summary>/// 无参构造/// </summary>public AnimatedSprite() { }/// <summary>/// 有参构造/// </summary>/// <param name="animation">动画</param> public AnimatedSprite(Animation animation){Animation = animation;}/// <summary>/// 循环播放当前动画组件/// </summary>/// <param name="gameTime"></param> public void Update(GameTime gameTime){Elapsed += gameTime.ElapsedGameTime;if (Elapsed >= animation.Delay){Elapsed -= animation.Delay;CurrentFrame++;if (CurrentFrame >= animation.Frames.Count){CurrentFrame = 0;}Region = animation.Frames[CurrentFrame];}}
}

第四步:使用动画组件

上面就是我们本次教程修改的全部代码了那么接下来我们来介绍如何使用这个组件:
修改·XML

<?xml version="1.0" encoding="utf-8"?>
<TextureAtlas><Texture>images/atlas</Texture><Regions><Region name="slime-1" x="340" y="0" width="20" height="20" /><Region name="slime-2" x="340" y="20" width="20" height="20" /><Region name="bat-1" x="340" y="40" width="20" height="20" /><Region name="bat-2" x="340" y="60" width="20" height="20" /><Region name="bat-3" x="360" y="0" width="20" height="20" /><Region name="unfocused-button" x="259" y="80" width="65" height="14" /><Region name="focused-button-1" x="259" y="94" width="65" height="14" /><Region name="focused-button-2" x="259" y="109" width="65" height="14" /><Region name="panel-background" x="324" y="97" width="15" height="15" /><Region name="slider-off-background" x="341" y="96" width="11" height="10" /><Region name="slider-middle-background" x="345" y="81" width="3" height="3" /><Region name="slider-max-background" x="354" y="96" width="11" height="10" /></Regions><Animations><Animation name="slime-animation" delay="200"><Frame region="slime-1" /><Frame region="slime-2" /></Animation><Animation name="bat-animation" delay="200"><Frame region="bat-1" /><Frame region="bat-2" /><Frame region="bat-1" /><Frame region="bat-3" /></Animation><Animation name="focused-button-animation" delay="300"><Frame region="focused-button-1" /><Frame region="focused-button-2" /></Animation></Animations>
</TextureAtlas>

加下来将GameMain函数修改至如下所示

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SlimeGame.Graphics;
using SlimeGameLibrary;namespace SlimeGame;public class GameMain : Core
{private AnimatedSprite _slime;private AnimatedSprite _bat;public GameMain() : base("SlimeGame", 1280, 720, false){}protected override void Initialize(){// TODO: 增加你的初始化逻辑base.Initialize();}protected override void LoadContent(){TextureAtlas atlas = TextureAtlas.FromFile(Content, "configs/atlas_slice.xml");_slime = atlas.CreateAnimatedSprite("slime-animation");_slime.Scale = new Vector2(4.0f, 4.0f);_bat = atlas.CreateAnimatedSprite("bat-animation");_bat.Scale = new Vector2(4.0f, 4.0f);}protected override void Update(GameTime gameTime){if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))Exit(); // 退出游戏:按下Esc键或是手柄上的一个啥键// TODO: 在此处增加你的游戏主循环逻辑_slime.Update(gameTime);_bat.Update(gameTime);base.Update(gameTime);}protected override void Draw(GameTime gameTime){GraphicsDevice.Clear(Color.CornflowerBlue);SpriteBatch.Begin(samplerState: SamplerState.PointClamp);_slime.Draw(SpriteBatch, Vector2.One);_bat.Draw(SpriteBatch, new Vector2(_slime.Width + 10, 0));SpriteBatch.End();base.Draw(gameTime);}
}

老方法运行这个代码我们看看效果
在这里插入图片描述

结语:

最近不是打算弃坑的,只是我最近忙东西忘记更新,再加上没过几天都要学车了,我最近也是着急忙慌的看科一,当然了我这里有一个新项目给大家学习参考,也是我缺席着十几天来的成果:
https://gitee.com/qiu-tutu/eclipse-game
https://gitee.com/qiu-tutu/eclipse
这两个是我最近今天开发的项目:
线上多人射击游戏,可创建或者加入房间每个房间最多两人,由于素材不完整角色动画步完全我们接下来得不断完善整体游戏逻辑,当然是完全免费开源的,由于项目工程文件太大了,大家可以看第二个仓库的内容,里面有所有的完整代码。但是如果想要开发的话还是得自己动手学,我是用的服务器是Photon服务器,当然我会专门写一篇来处理这些内容地。
接下来是照例地几个问题

什么是Animation?

为什么要创建AnimationSprite?

创建好后地Animation我们该如何使用?

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

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

相关文章

LVS四种工作模式深度解析

LVS&#xff08;linux virual server&#xff09;LVS四种工作模式深度解析 LVS-NAT模式 四台虚拟机 火墙关闭 关闭火墙 systemctl stop firewalldsystemctl disable firewalld关闭开机自启火墙1.clienteth0 IP&#xff1a;172.25.254.1002.lvs eth0ip :172.25.254.200; eth1ip:…

[设计模式]C++单例模式的几种写法以及通用模板

之前在这篇文章中简单的介绍了一下单例模式的作用和应用C中单例模式详解_c单例模式的作用-CSDN博客&#xff0c;今天我将在在本文梳理单例模式从C98到C11及以后的演变过程&#xff0c;探讨其不同实现方式的优劣&#xff0c;并介绍在现代C中的最佳实践。 什么是单例模式&#x…

小架构step系列19:请求和响应

1 概述作为Web程序&#xff0c;通用形式是发起HTTP请求并获取返回的结果&#xff0c;在这个过程中&#xff0c;需要把请求映射到代码的接口上&#xff0c;提供这种接口的类一般称为Controller&#xff0c;也就是需要把请求映射到Controller的接口方法上&#xff0c;把请求的参数…

论文分享 | LABRADOR:响应引导的针对物联网设备的黑盒模糊测试

由于固件仿真以及重托管的技术挑战&#xff0c;部分企业级 IoT 设备只能在黑盒环境下进行模糊测试。分享一篇发表于 2024 年 S&P 会议的论文 Labrador&#xff0c;它利用响应来引导请求变异&#xff0c;实现了针对 IoT 设备的高效黑盒模糊测试。 猴先生说&#xff1a;这篇论…

WPF为启动界面(Splash Screen)添加背景音乐

1. 添加音频文件到项目 将音频文件&#xff08;如.mp3/.wav&#xff09;放入项目文件夹&#xff08;如Resources&#xff09;在解决方案资源管理器中右键文件 → 属性&#xff1a; 生成操作&#xff1a;选择Resource&#xff08;嵌入资源&#xff09;或Content&#xff08;内容…

【Jmeter】报错:An error occured:Unknown arg

问题 调试Jmeter时&#xff0c;报错&#xff1a;‘An error occurred: Unknown arg: l’&#xff0c;脚本如下&#xff1a; $JMETER_PATH -n -t "$target_jmx" -l "$SCENARIO_REPORT_DIR/result_${threads}.jtl" -e -o "$SCENARIO_REPORT_DIR/htm…

vue3使用KeepAlive组件及一些注意事项

目录 一、KeepAlive的作用 二、缓存组件配置 2.1、过滤缓存组件 2.2、最大缓存实例数 三、KeepAlive组件的生命周期 四、错误用法 4.1、缓存v-if包裹的动态组件 4.2、拼写错误 一、KeepAlive组件的作用 首先&#xff0c;keep-alive是一个vue的内置组件&#xff0c;官网…

辛普森悖论

辛普森悖论第一步&#xff1a;概念拆解想象你在比较两个班级的考试成绩&#xff1a;​第一天​&#xff1a;实验组&#xff08;1个学生考了90分&#xff09;&#xff0c;对照组&#xff08;99个学生平均考了80分&#xff09;​第二天​&#xff1a;实验组&#xff08;50个学生平…

有效的括号数据结构oj题(力口20)

目录 目录 题目描述 题目分析解析 解决代码 写题感悟&#xff1a; 题目描述 还有实例 题目分析解析 对于这个题目&#xff0c;我们首先有效字符串需要满足什么&#xff0c;第一个左右括号使用相同类型的括号&#xff0c;这好理解&#xff0c;无非就是小括号和小括号大括号…

Mock 单元测试

作者&#xff1a;小凯 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01; 本文的宗旨在于通过简单干净实践的方式教会读者&#xff0c;如何使用 Mock (opens new window)进行工程的单元测试&#xff0c;以便于验证系统中的独立模块功能的健壮性。 从整个工程所…

MySQL 深度性能优化配置实战指南

🔧 一、硬件与系统层优化:夯实性能基石 ​​硬件选型策略​​ ​​CPU​​:读密集型场景选择多核CPU(如32核);写密集型场景选择高主频CPU(如3.5GHz+)。 ​​内存​​:建议≥64GB,​​缓冲池命中率≥99%​​ 是性能关键指标。 ​​存储​​:​​必用NVMe SSD​​,I…

Visual Studio Code(VSCode)中设置中文界面

在VS Code中设置中文界面主要有两种方法&#xff1a;通过扩展市场安装中文语言包或通过命令面板直接切换语言。‌方法一&#xff1a;通过扩展市场安装中文语言包‌打开VS Code&#xff0c;点击左侧活动栏的"扩展"图标&#xff08;或按CtrlShiftX&#xff09;。在搜索…

叉车机器人如何实现托盘精准定位?这项核心技术的原理和应用是什么?

随着智慧物流和智能制造的加速发展&#xff0c;智能化转型成为提升效率、降低成本的关键路径&#xff0c;叉车机器人&#xff08;AGV/AMR叉车&#xff09;在仓储、制造、零售等行业中的应用日益广泛。 其中&#xff0c;托盘定位技术是实现其高效、稳定作业的核心环节之一&…

NO.6数据结构树|二叉树|满二叉树|完全二叉树|顺序存储|链式存储|先序|中序|后序|层序遍历

树与二叉树的基本知识 树的术语结点&#xff1a; 树中的每个元素都称为结点&#xff0c; 例如上图中的 A,B,C…根结点&#xff1a; 位于树顶部的结点&#xff0c; 它没有父结点,比如 A 结点。父结点&#xff1a; 若一个结点有子结点&#xff0c; 那么这个结点就称为其子结点的父…

数据集下载网站

名称简介链接Kaggle世界上最大的数据科学竞赛平台之一&#xff0c;有大量结构化、图像、文本等数据集可直接下载✅支持一键下载、APIPapers with Code可按任务&#xff08;如图像分类、文本生成等&#xff09;查找模型与数据集&#xff0c;标注 SOTA✅与论文强关联Hugging Face…

Tomcat 生产 40 条军规:容量规划、调优、故障演练与安全加固

&#xff08;一&#xff09;容量规划 6 条 军规 1&#xff1a;线程池公式 maxThreads ((并发峰值 平均 RT) / 1000) 冗余 20 %&#xff1b; 踩坑&#xff1a;压测 2000 QPS、RT 200 ms&#xff0c;理论 maxThreads500&#xff0c;线上却设 150 导致排队。军规 2&#xff1a;…

深入解析 Amazon Q:AWS 推出的企业级生成式 AI 助手

在人工智能助手竞争激烈的当下&#xff0c;AWS 重磅推出的 Amazon Q 凭借其强大的企业级整合能力&#xff0c;正成为开发者提升生产力的新利器。随着生成式 AI 技术席卷全球&#xff0c;各大云厂商纷纷布局智能助手领域。在 2023 年 re:Invent 大会上&#xff0c;AWS 正式推出了…

物流自动化WMS和WCS技术文档

导语大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。欢迎大家使用我们的仓储物流技术AI智能体。新书《智能物流系统构成与技术实践》新书《智能仓储项目出海-英语手册&#xff0c;必备&#xff01;》完整版文件和更多学习资料&#xff0c;…

Web3.0 实战项目、简历打造、精准投递+面试准备

目录 一、获取真实企业级 Web3.0 项目的 5 种方式 1. 参与开源项目&#xff08;推荐指数&#xff1a;⭐⭐⭐⭐⭐&#xff09; 2. 参与黑客松&#xff08;Hackathon&#xff09; 3. 远程实习 & DAO 协作项目&#xff08;兼职也可&#xff09; 4. Web3 Startup 实战项目合…

pymongo库:简易方式存取数据

文档 基础使用 前提&#xff1a;开发机器已安装mongo配置环境&#xff0c;已启动服务。 macOS启动服务&#xff1a;brew services start mongodb-community8.0 macOS停止服务&#xff1a;brew services stop mongodb-community8.0安装&#xff1a;python3 -m pip install pym…