Unity类银河恶魔城学习记录12-2 p124 Character Stats UI源代码
Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
UI_Statslot.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;public class UI_Statslot : MonoBehaviour
{[SerializeField] private StatType statType;[SerializeField] private TextMeshProUGUI statValueText;[SerializeField] private TextMeshProUGUI statNameText;private void OnValidate(){gameObject.name = "Stat - " + statType.ToString();if(statNameText != null){statNameText.text = statType.ToString();}}private void Start(){UpdateStatValueUI();}public void UpdateStatValueUI(){PlayerStats playerStats = PlayerManager.instance.player.GetComponent<PlayerStats>();if(playerStats != null){statValueText.text = playerStats.GetStats(statType).GetValue().ToString();}}
}
UI_equipementSlots.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class UI_equipementSlots : UI_itemSlot
{public EquipmentType slotType;//这怎么拿到的private void OnValidate(){gameObject.name = "Equipment slot -" + slotType.ToString();}public override void OnPointerDown(PointerEventData eventData){if (item == null || item.data == null)//修复点击空白处会报错的bugreturn;//点击装备槽后卸下装备Inventory.instance.AddItem(item.data as ItemData_Equipment);Inventory.instance.Unequipment(item.data as ItemData_Equipment); CleanUpSlot();}
}
UI_itemSlot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.EventSystems;public class UI_itemSlot : MonoBehaviour ,IPointerDownHandler
{[SerializeField] private Image itemImage;[SerializeField] private TextMeshProUGUI itemText;public InventoryItem item;public void UpdateSlots(InventoryItem _newItem){item = _newItem;itemImage.color = Color.white;if (item != null){itemImage.sprite = item.data.icon;if (item.stackSize > 1){itemText.text = item.stackSize.ToString();}else{itemText.text = "";}}}public void CleanUpSlot()//解决出现UI没有跟着Inventory变化的bug{item = null;itemImage.sprite = null;itemImage.color = Color.clear;itemText.text = "";}public virtual void OnPointerDown(PointerEventData eventData){if(item == null)//修复点击空白处会报错的bug{return;}if(Input.GetKey(KeyCode.LeftControl)){Inventory.instance.RemoveItem(item.data);return;}if (item.data.itemType == ItemType.Equipment)Inventory.instance.EquipItem(item.data);}
}
Buff_Effcet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;[CreateAssetMenu(fileName = "BUff effect", menuName = "Data/Item effect/Buff effect")]public class Buff_Effect :ItemEffect
{private PlayerStats stats;[SerializeField] private StatType buffType;[SerializeField] private float buffDuration;[SerializeField] private int buffAmount;public override void ExecuteEffect(Transform _respawnPosition){stats = PlayerManager.instance.player.GetComponent<PlayerStats>();stats.IncreaseStatBy(buffAmount, buffDuration, stats.GetStats(buffType));}}
Inventory.cs
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class Inventory : MonoBehaviour
{public static Inventory instance;public List<ItemData> startingItem;public List<InventoryItem> equipment;//inventoryItems类型的列表public Dictionary<ItemData_Equipment, InventoryItem> equipmentDictionary;//以ItemData为Key寻找InventoryItem的字典public List<InventoryItem> inventory;//inventoryItems类型的列表public Dictionary<ItemData, InventoryItem> inventoryDictionary;//以ItemData为Key寻找InventoryItem的字典public List<InventoryItem> stash;public Dictionary<ItemData, InventoryItem> stashDictionary;[Header("Inventory UI")][SerializeField] private Transform inventorySlotParent;[SerializeField] private Transform stashSlotParent;[SerializeField] private Transform equipmentSlotParent;[SerializeField] private Transform statSlotParent;private UI_itemSlot[] inventoryItemSlot;//UI Slot的数组private UI_itemSlot[] stashItemSlot;private UI_equipementSlots[] equipmentSlot;private UI_Statslot[] statSlot;[Header("Items cooldown")]private float lastTimeUsedFlask;private float lastTimeUsedArmor;private float flaskCooldown;private float armorCooldown;private void Awake(){if (instance == null)instance = this;elseDestroy(gameObject);//防止多次创建Inventory}public void Start(){inventory = new List<InventoryItem>();inventoryDictionary = new Dictionary<ItemData, InventoryItem>();stash = new List<InventoryItem>();stashDictionary = new Dictionary<ItemData, InventoryItem>();equipment = new List<InventoryItem>();equipmentDictionary = new Dictionary<ItemData_Equipment, InventoryItem>();inventoryItemSlot = inventorySlotParent.GetComponentsInChildren<UI_itemSlot>();//拿到的方式有点绕,显示拿到Canvas 里的 Inventory 然后通过GetComponentsInChildren拿到其下的使用UISlotstashItemSlot = stashSlotParent.GetComponentsInChildren<UI_itemSlot>();equipmentSlot = equipmentSlotParent.GetComponentsInChildren<UI_equipementSlots>();statSlot = statSlotParent.GetComponentsInChildren<UI_Statslot>();AddStartingItems();}private void AddStartingItems(){for (int i = 0; i < startingItem.Count; i++){AddItem(startingItem[i]);}}//设置初始物品public void EquipItem(ItemData _item){//解决在itemdata里拿不到子类equipment里的enum的问题ItemData_Equipment newEquipment = _item as ItemData_Equipment;//https://www.bilibili.com/read/cv15551811///将父类转换为子类InventoryItem newItem = new InventoryItem(newEquipment);ItemData_Equipment oldEquipment = null;foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//这种方法可以同时拿到key和value保存到item里面{if (item.Key.equipmentType == newEquipment.equipmentType)//将拿到的key与转换成itemdata_equipment类型的_item的type对比拿到存在的key{oldEquipment = item.Key;//此key需保存在外部的data类型里//equipment.Remove(item.Value);//equipmentDictionary.Remove(item.Key);}}//好像用foreach里的value和key无法对外部的list和字典进行操作if (oldEquipment != null){AddItem(oldEquipment);Unequipment(oldEquipment);}equipment.Add(newItem);equipmentDictionary.Add(newEquipment, newItem);RemoveItem(_item);newEquipment.AddModifiers();UpdateSlotUI();}//装备装备的函数public void Unequipment(ItemData_Equipment itemToRemove)//装备其他同类型的装备时。去除已装备的装备{if (equipmentDictionary.TryGetValue(itemToRemove, out InventoryItem value)){equipment.Remove(value);equipmentDictionary.Remove(itemToRemove);itemToRemove.RemoveModifiers();UpdateSlotUI();}}private void UpdateSlotUI(){for (int i = 0; i < equipmentSlot.Length; i++){//此步骤用于将对应类型的武器插入对应的槽内foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//这种方法可以同时拿到key和value保存到item里面{if (item.Key.equipmentType == equipmentSlot[i].slotType){equipmentSlot[i].UpdateSlots(item.Value);}}}//解决出现UI没有跟着Inventory变化的bugfor (int i = 0; i < inventoryItemSlot.Length;i++){inventoryItemSlot[i].CleanUpSlot();}for (int i = 0; i < stashItemSlot.Length; i++){stashItemSlot[i].CleanUpSlot();}for (int i = 0; i < inventory.Count; i++){inventoryItemSlot[i].UpdateSlots(inventory[i]);}for (int i = 0; i < stash.Count; i++){stashItemSlot[i].UpdateSlots(stash[i]);}for(int i = 0; i < statSlot.Length;i++){statSlot[i].UpdateStatValueUI();}}//更新UI函数public void AddItem(ItemData _item){if (_item.itemType == ItemType.Equipment){AddToInventory(_item);}else if (_item.itemType == ItemType.Material){AddToStash(_item);}UpdateSlotUI();}//添加物体的函数private void AddToStash(ItemData _item)//向stash加物体的函数{if (stashDictionary.TryGetValue(_item, out InventoryItem value))//只有这种方法才能在查找到是否存在key对应value是否存在的同时,能够同时拿到value,其他方法的拿不到value{value.AddStack();}//字典的使用,通过ItemData类型的数据找到InventoryItem里的与之对应的同样类型的数据else//初始时由于没有相同类型的物体,故调用else是为了初始化库存,使其中含有一个基本的值{InventoryItem newItem = new InventoryItem(_item);stash.Add(newItem);//填进列表里只有一次stashDictionary.Add(_item, newItem);//同上}}private void AddToInventory(ItemData _item){if (inventoryDictionary.TryGetValue(_item, out InventoryItem value))//只有这种方法才能在查找到是否存在key对应value是否存在的同时,能够同时拿到value,其他方法的拿不到value{value.AddStack();}//字典的使用,通过ItemData类型的数据找到InventoryItem里的与之对应的同样类型的数据else//初始时由于没有相同类型的物体,故调用else是为了初始化库存,使其中含有一个基本的值{InventoryItem newItem = new InventoryItem(_item);inventory.Add(newItem);//填进列表里只有一次inventoryDictionary.Add(_item, newItem);//同上}}//将物体存入Inventory的函数public void RemoveItem(ItemData _item)//将物体剔除Inventory的函数{if (inventoryDictionary.TryGetValue(_item, out InventoryItem value)){if (value.stackSize <= 1){inventory.Remove(value);inventoryDictionary.Remove(_item);}elsevalue.RemoveStack();}if (stashDictionary.TryGetValue(_item, out InventoryItem stashValue)){if (stashValue.stackSize <= 1){stash.Remove(stashValue);stashDictionary.Remove(_item);}elsestashValue.RemoveStack();}UpdateSlotUI();}public List<InventoryItem> GetEquipmentList() => equipment;public List<InventoryItem> GetStashList() => stash;public ItemData_Equipment GetEquipment(EquipmentType _Type)//通过Type找到对应的已装备装备的函数{ItemData_Equipment equipedItem = null;foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)if (item.Key.equipmentType == _Type){equipedItem = item.Key;}return equipedItem;}public void UseFlask()//使用药瓶设置冷却时间{ItemData_Equipment currentFlask = GetEquipment(EquipmentType.Flask);if (currentFlask == null)return;//使用药瓶设置冷却时间bool canUseFlask = Time.time > lastTimeUsedFlask + flaskCooldown;if(canUseFlask){flaskCooldown = currentFlask.itemCooldown;currentFlask.Effect(null);lastTimeUsedFlask = Time.time;}else{Debug.Log("Flask is Cooldown");}}//使用药瓶函数public bool CanUseArmor(){ItemData_Equipment currentArmor = GetEquipment(EquipmentType.Armor);if(Time.time > lastTimeUsedArmor + armorCooldown){lastTimeUsedArmor = Time.time;armorCooldown = currentArmor.itemCooldown;return true;}Debug.Log("Armor on cooldown");return false;}
}
CharacterStats.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting.Antlr3.Runtime.Misc;
using UnityEngine;
public enum StatType
{strength,agility,intelligence,vitality,damage,critChance,critPower,Health,armor,evasion,magicResistance,fireDamage,iceDamage,lightingDamage
}
public class CharacterStats : MonoBehaviour
{private EntityFX fx;[Header("Major stats")]public Stat strength; // 力量 增伤1点 爆伤增加 1% 物抗public Stat agility;// 敏捷 闪避 1% 闪避几率增加 1%public Stat intelligence;// 1 点 魔法伤害 1点魔抗 public Stat vitality;//加血的[Header("Offensive stats")]public Stat damage;public Stat critChance; // 暴击率public Stat critPower; //150% 爆伤[Header("Defensive stats")]public Stat Health;public Stat armor;public Stat evasion;//闪避值public Stat magicResistance;[Header("Magic stats")]public Stat fireDamage;public Stat iceDamage;public Stat lightingDamage;public bool isIgnited; // 持续烧伤public bool isChilded; // 削弱护甲 20%public bool isShocked; // 降低敌人命中率[SerializeField] private float ailmentsDuration = 4;private float ignitedTimer;private float chilledTimer;private float shockedTimer;private float igniteDamageCooldown = .3f;private float ignitedDamageTimer;private int igniteDamage;[SerializeField] private GameObject shockStrikePrefab;private int shockDamage;public System.Action onHealthChanged;//使角色在Stat里调用UI层的函数//此函数调用了更新HealthUI函数public bool isDead { get; private set; }[SerializeField] public int currentHealth;protected virtual void Start(){critPower.SetDefaultValue(150);//设置默认爆伤currentHealth = GetMaxHealthValue();fx = GetComponent<EntityFX>();}protected virtual void Update(){//所有的状态都设置上默认持续时间,持续过了就结束状态ignitedTimer -= Time.deltaTime;chilledTimer -= Time.deltaTime;shockedTimer -= Time.deltaTime;ignitedDamageTimer -= Time.deltaTime;if (ignitedTimer < 0)isIgnited = false;if (chilledTimer < 0)isChilded = false;if (shockedTimer < 0)isShocked = false;//被点燃后,出现多段伤害后点燃停止if(isIgnited)ApplyIgnitedDamage();}public virtual void IncreaseStatBy(int _modifier, float _duration,Stat _statToModify){StartCoroutine(StatModCoroutine(_modifier, _duration, _statToModify));}private IEnumerator StatModCoroutine(int _modifier, float _duration, Stat _statToModify){_statToModify.AddModifier(_modifier);yield return new WaitForSeconds(_duration);_statToModify.RemoveModifier(_modifier);}public virtual void DoDamage(CharacterStats _targetStats)//计算后造成伤害函数{if (TargetCanAvoidAttack(_targetStats))设置闪避{return;}int totleDamage = damage.GetValue() + strength.GetValue();//爆伤设置if (CanCrit()){totleDamage = CalculateCriticalDamage(totleDamage);}totleDamage = CheckTargetArmor(_targetStats, totleDamage);//设置防御_targetStats.TakeDamage(totleDamage);DoMagicaDamage(_targetStats); // 可以去了也可以不去}protected virtual void Die(){isDead = true;}public virtual void TakeDamage(int _damage)//造成伤害是出特效{fx.StartCoroutine("FlashFX");//IEnumertor本质就是将一个函数分块执行,只有满足某些条件才能执行下一段代码,此函数有StartCoroutine调用//https://www.zhihu.com/tardis/bd/art/504607545?source_id=1001DecreaseHealthBy(_damage);GetComponent<Entity>().DamageImpact();if (currentHealth < 0 && !isDead)Die();}public virtual void IncreaseHealthBy(int _amount)//添加回血函数{currentHealth += _amount;if (currentHealth > GetMaxHealthValue())currentHealth = GetMaxHealthValue();if (onHealthChanged != null)onHealthChanged();}protected virtual void DecreaseHealthBy(int _damage)//此函数用来改变当前生命值,不调用特效{currentHealth -= _damage;if (onHealthChanged != null){onHealthChanged();}}#region Magical damage and ailementsprivate void ApplyIgnitedDamage(){if (ignitedDamageTimer < 0 ){DecreaseHealthBy(igniteDamage);if (currentHealth < 0 && !isDead)Die();ignitedDamageTimer = igniteDamageCooldown;}}被点燃后,出现多段伤害后点燃停止public virtual void DoMagicaDamage(CharacterStats _targetStats)//法伤计算和造成元素效果调用的地方{int _fireDamage = fireDamage.GetValue();int _iceDamage = iceDamage.GetValue();int _lightingDamage = lightingDamage.GetValue();int totleMagicalDamage = _fireDamage + _iceDamage + _lightingDamage + intelligence.GetValue();totleMagicalDamage = CheckTargetResistance(_targetStats, totleMagicalDamage);_targetStats.TakeDamage(totleMagicalDamage);//防止循环在所有元素伤害为0时出现死循环if (Mathf.Max(_fireDamage, _iceDamage, _lightingDamage) <= 0)return;//让元素效果取决与伤害//为了防止出现元素伤害一致而导致无法触发元素效果//循环判断触发某个元素效果AttemptyToApplyAilement(_targetStats, _fireDamage, _iceDamage, _lightingDamage);}private void AttemptyToApplyAilement(CharacterStats _targetStats, int _fireDamage, int _iceDamage, int _lightingDamage){bool canApplyIgnite = _fireDamage > _iceDamage && _fireDamage > _lightingDamage;bool canApplyChill = _iceDamage > _lightingDamage && _iceDamage > _fireDamage;bool canApplyShock = _lightingDamage > _fireDamage && _lightingDamage > _iceDamage;while (!canApplyIgnite && !canApplyChill && !canApplyShock){if (Random.value < .25f){canApplyIgnite = true;Debug.Log("Ignited");_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);return;}if (Random.value < .35f){canApplyChill = true;Debug.Log("Chilled");_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);return;}if (Random.value < .55f){canApplyShock = true;Debug.Log("Shocked");_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);return;}}if (canApplyIgnite){_targetStats.SetupIgniteDamage(Mathf.RoundToInt(_fireDamage * .2f));}if (canApplyShock)_targetStats.SetupShockStrikeDamage(Mathf.RoundToInt(_lightingDamage * .1f));//给点燃伤害赋值_targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);}//造成元素效果public void ApplyAilments(bool _ignite, bool _chill, bool _shock)//判断异常状态{bool canApplyIgnite = !isIgnited && !isChilded && !isShocked;bool canApplyChill = !isIgnited && !isChilded && !isShocked;bool canApplyShock = !isIgnited && !isChilded;//使当isShock为真时Shock里的函数仍然可以调用if (_ignite && canApplyIgnite){isIgnited = _ignite;ignitedTimer = ailmentsDuration;fx.IgniteFxFor(ailmentsDuration);}if (_chill && canApplyChill){isChilded = _chill;chilledTimer = ailmentsDuration;float slowPercentage = .2f;GetComponent<Entity>().SlowEntityBy(slowPercentage, ailmentsDuration);fx.ChillFxFor(ailmentsDuration);}if (_shock && canApplyShock){if(!isShocked){ApplyShock(_shock);}else{if (GetComponent<Player>() != null)//防止出现敌人使玩家进入shock状态后也出现闪电return;HitNearestTargetWithShockStrike();}//isShock为真时反复执行的函数为寻找最近的敌人,创建闪电实例并传入数据}}public void ApplyShock(bool _shock){if (isShocked)return;isShocked = _shock;shockedTimer = ailmentsDuration;fx.ShockFxFor(ailmentsDuration);}//触电变色效果private void HitNearestTargetWithShockStrike(){Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 25);//找到环绕自己的所有碰撞器float closestDistance = Mathf.Infinity;//正无穷大的表示形式(只读)Transform closestEnemy = null;//https://docs.unity3d.com/cn/current/ScriptReference/Mathf.Infinity.htmlforeach (var hit in colliders){if (hit.GetComponent<Enemy>() != null && Vector2.Distance(transform.position, hit.transform.position) > 1)// 防止最近的敌人就是Shock状态敌人自己{float distanceToEnemy = Vector2.Distance(transform.position, hit.transform.position);//拿到与敌人之间的距离if (distanceToEnemy < closestDistance)//比较距离,如果离得更近,保存这个敌人的位置,更改最近距离{closestDistance = distanceToEnemy;closestEnemy = hit.transform;}}if (closestEnemy == null)closestEnemy = transform;}if (closestEnemy != null){GameObject newShockStrike = Instantiate(shockStrikePrefab, transform.position, Quaternion.identity);newShockStrike.GetComponent<ShockStrike_Controller>().Setup(shockDamage, closestEnemy.GetComponent<CharacterStats>());}}//给最近的敌人以雷劈public void SetupIgniteDamage(int _damage) => igniteDamage = _damage;//给点燃伤害赋值public void SetupShockStrikeDamage(int _damage) => shockDamage = _damage;//雷电伤害赋值#endregion#region Stat calculationsprivate int CheckTargetResistance(CharacterStats _targetStats, int totleMagicalDamage)//法抗计算{totleMagicalDamage -= _targetStats.magicResistance.GetValue() + (_targetStats.intelligence.GetValue() * 3);totleMagicalDamage = Mathf.Clamp(totleMagicalDamage, 0, int.MaxValue);return totleMagicalDamage;}private static int CheckTargetArmor(CharacterStats _targetStats, int totleDamage)//防御计算{//被冰冻后,角色护甲减少if (_targetStats.isChilded)totleDamage -= Mathf.RoundToInt(_targetStats.armor.GetValue() * .8f);elsetotleDamage -= _targetStats.armor.GetValue();totleDamage = Mathf.Clamp(totleDamage, 0, int.MaxValue);return totleDamage;}private bool TargetCanAvoidAttack(CharacterStats _targetStats)//闪避计算{int totleEvation = _targetStats.evasion.GetValue() + _targetStats.agility.GetValue();//我被麻痹后//敌人的闪避率提升if (isShocked)totleEvation += 20;if (Random.Range(0, 100) < totleEvation){return true;}return false;}private bool CanCrit()//判断是否暴击{int totleCriticalChance = critChance.GetValue() + agility.GetValue();if (Random.Range(0, 100) <= totleCriticalChance){return true;}return false;}private int CalculateCriticalDamage(int _damage)//计算暴击后伤害{float totleCirticalPower = (critPower.GetValue() + strength.GetValue()) * .01f;float critDamage = _damage * totleCirticalPower;return Mathf.RoundToInt(critDamage);//返回舍入为最近整数的}public int GetMaxHealthValue(){return Health.GetValue() + vitality.GetValue() * 10;}//统计生命值函数public Stat GetStats(StatType _statType){if (_statType == StatType.strength) return strength;else if (_statType == StatType.agility) return agility;else if (_statType == StatType.intelligence) return intelligence;else if (_statType == StatType.vitality) return vitality;else if (_statType == StatType.damage) return damage;else if (_statType == StatType.critChance) return critChance;else if (_statType == StatType.critPower) return critPower;else if (_statType == StatType.Health) return Health;else if (_statType == StatType.armor) return armor;else if (_statType == StatType.evasion) return evasion;else if (_statType == StatType.magicResistance) return magicResistance;else if (_statType == StatType.fireDamage) return fireDamage;else if (_statType == StatType.iceDamage) return iceDamage;else if (_statType == StatType.lightingDamage) return lightingDamage;return null;}#endregion
}
相关文章:
Unity类银河恶魔城学习记录12-2 p124 Character Stats UI源代码
Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili UI_Statslot.cs using System.Collections; using System.Collections.Gen…...
技术揭秘:如何打造完美互动的充电桩硬件与服务平台?
充电桩平台全套源码地址 https://gitee.com/chouleng/cdzkjjh.git 这张图像是一个系统或服务的架构图。以下是对图中各个部分的描述: 前端: 位于图像的顶部,颜色为浅绿色。用户服务端: 紧邻前端,颜色为淡黄色。设备服…...
【Django学习笔记(四)】JavaScript 语言介绍
JavaScript 语言介绍 前言正文1、JavaScript 小案例2、代码位置2.1 在当前 HTML 文件中2.2 在其他 js 文件中 3、代码注释3.1 HTML的注释3.2 CSS的注释3.3 Javascript的注释 4、变量 & 输出4.1 字符串4.2 数组4.3 对象(python里的字典) 5、条件语句6、函数7、DOM7.1 根据 I…...
IO和NIO的主要区别在哪里?
Java 中的 IO(输入/输出)和 NIO(新输入/输出)都是处理输入和输出操作的方式,它们的主要区别在于如何处理数据的读写。 阻塞与非阻塞: IO是阻塞的,这意味着当一个线程调用read()或write()时,该线…...
爬虫部署平台crawlab使用说明
Crawlab 是一个基于 Go 语言的分布式网络爬虫管理平台,它支持 Python、Node.js、Jar、EXE 等多种类型的爬虫。 Crawlab 提供了一个可视化的界面,并且可以通过简单的配置来管理和监控爬虫程序。 以下是 Crawlab 的一些主要优点: 集中管理&am…...
uniapp uni.scss中使用@mixin混入,在文件引入@include 样式不生效 Error: Undefined mixin.(踩坑记录一)
问题: 在uni.scss文件定义mixin 2. 在vue文件引入: 3. 出现报错信息: 4. 问题思考: 是不是需要引入uni.scss ? 答案不需要 uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的…...
Redis的5大常见数据类型的用法
上一篇文章我们讲了Redis的10大应用场景,这一篇文章就针对Redis的常用数据结构进行一个说明,通过示例的形式演示每一种数据结构如何使用。 当涉及Redis的数据操作时,不同数据类型对应的不同数据结构,如下就对5大常用的数据类型进行…...
刘小光本就疑心赵本山与他媳妇李琳有染,赵本山为证实清白便想起蛋糕上的字,结果呢?
刘小光本就疑心赵本山与他媳妇李琳有染,赵本山为证实清白便想起蛋糕上的字,结果呢? ——小品《生日快乐》(中5)的台词 (接上) 赵本山:噢!对对!那谁,老四,是…...
Unity之PUN实现多人联机射击游戏的优化(Section 2)
目录 🎮一、准备工作 🎮二、实现手雷投掷动作 🎮三、手雷投掷同步 💤3.1 photonView.RPC 🎮四、同步手雷伤害 这几周都给我布置任务了,最近可忙。现在终于有机会更新了,也谢谢大家的阅读&a…...
多叉树题目:N 叉树的层序遍历
文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:N 叉树的层序遍历 出处:429. N 叉树的层序遍历 难度 4 级 题目描述 要求 给定一个 N 叉树的根结点 root \texttt{root} root…...
时序数据库IoTDB:功能详解与行业应用
一文读懂时序数据库 IoTDB。 01 为什么需要时序数据库 解释时序数据库前,先了解一下何谓时序数据。 时序数据,也称为时间序列数据,是指按时间顺序记录的同一统计指标的数据集合。这类数据的来源主要是能源、工程、交通等工业物联网强关联行业…...
信息系统项目管理师——第18章项目绩效域管理(一)
本章节内容属于第四版新增知识,为PMBOK第七版专有,选择、案例、论文都会考,属于比较重要的章节。 选择题,稳定考3分左右,新教材基本考课本原话,需要多读课本,多刷题。 案例题,考的概…...
WebSocket用户验证
在WebSocket中,如何携带用户的验证信息 一、在OnMessage中进行验证 客户端在连接到服务器后,客户端通过发送消息,服务器端在OnMessage方法中,进行信息验证,这种方式需要将用户身份验证及接收用户消息进行混合处理&am…...
NOSQL(非关系型数据库)的优缺点有哪些?
优点: 高度灵活且可扩展:NoSQL数据库不受固定数据模型的限制,可以根据应用需求灵活设计数据结构,轻松应对大规模数据集。此外,它支持分布式架构,具有出色的水平扩展能力,能够高效地处理大量数据…...
个人推荐Redis比较好的一种使用规范
随着对个人项目的不断开发、迭代和重构,博主在这个过程中总结出了一套使用redis的较好的规范。主要包含Redis的key命名规范和Redis代码规范。 主要内容 主要包含以下几个内容: 同一应用的key在最前面添加统一的前缀,如应用名; 案…...
【教程】宝塔default.db占用空间几十g解决方法|宝塔占用磁盘空间特别大解决方法|宝塔磁盘被占满怎么清理
目录 一、前言二、排查问题三、解决方法 一、前言 用过宝塔创建网站,大家应该都非常熟悉,但是用随着用的时间越来越多,宝塔所占用的空间也越来越多,不停的加大数据盘都没有用,我原先买了30G够用了,随着时间…...
Unity类银河恶魔城学习记录11-15 p117 Ice and Fire item Effect源代码
Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili IceAndFire_Controller.cs using System.Collections; using System.Coll…...
Qt QML的枚举浅用
QML的枚举用法 序言概念命名规则在QML定义枚举的规范 用法QML的枚举定义方法供QML调用的,C的枚举定义方法 序言 概念 QML的枚举和C的其实差不多,但是呢,局限比较多,首先不能在main.qml里定义,也不能在子项中定义。 …...
设计模式:单例模式六种实现
单例模式有多种实现方式,每种方式都有其设计思想、优缺点以及适用的使用场景。以下是一些常见的单例实现方式: 1. 懒汉式(线程不安全) 设计思想 这种实现方式采用了类加载的懒加载机制来保证单例只在第一次使用时被创建。 实现代码 public class Singleton {private s…...
Mybatis-Plus05(分页插件)
分页插件 MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能 1. 添加配置类 Configuration MapperScan("com.atguigu.mybatisplus.mapper") //可以将主类中的注解移到此处 public class MybatisPlusConfig {Bean public MybatisPlusIntercepto…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...
