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
英文地址,請注明出處:http://en.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…