Unity类银河恶魔城学习记录12-13 p135 Merge Skill Tree with Dogge skill源代码

 Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili​​​​​​​

Inventory.cs
using System.Collections.Generic;
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()//更新槽UI的函数{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]);}UpdateStatsUI();}public void UpdateStatsUI()//更新状态UI函数{for (int i = 0; i < statSlot.Length; i++){statSlot[i].UpdateStatValueUI();}}public void AddItem(ItemData _item)//添加物体的函数{if (_item.itemType == ItemType.Equipment && CanAddItem())//修复Inventory数量大于Slot能存放的数量时报错的Bug{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);//同上}UpdateSlotUI();}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数量大于Slot能存放的数量时报错的Bug{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 bool CanAddItem()//通过Inventory数量和Slot能存放的数量进行对比,确定是否可以添加新的装备到装备槽{if (inventory.Count >= inventoryItemSlot.Length){return false;}return true;}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;}public bool CanCraft(ItemData_Equipment _itemToCraft, List<InventoryItem> _requiredMaterials){List<InventoryItem> materialsToRemove = new List<InventoryItem>();for (int i = 0; i < _requiredMaterials.Count; i++){if (stashDictionary.TryGetValue(_requiredMaterials[i].data, out InventoryItem stashValue))//判断数量是否足够{if (stashValue.stackSize < _requiredMaterials[i].stackSize){Debug.Log("not enough materials");return false;}else{materialsToRemove.Add(stashValue);}}else{Debug.Log("not enough materials");return false;}}for (int i = 0; i < materialsToRemove.Count; i++){RemoveItem(materialsToRemove[i].data);}AddItem(_itemToCraft);Debug.Log("Here is your item " + _itemToCraft.name);return true;}//检测材料足够制造对应装备的函数
}
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; }private bool isVulnerable;//脆弱效果[SerializeField] public int currentHealth;protected virtual void Start(){critPower.SetDefaultValue(150);//设置默认爆伤currentHealth = GetMaxHealthValue();fx = GetComponent<EntityFX>();}public void MakeVulnerableFor(float _duration) => StartCoroutine(VulnerableCorutine(_duration));//脆弱效果函数private IEnumerator VulnerableCorutine(float _duration){isVulnerable = true;yield return new WaitForSeconds(_duration);isVulnerable = false;}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)//此函数用来改变当前生命值,不调用特效{if (isVulnerable)_damage = Mathf.RoundToInt(_damage * 1.1f);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;}public virtual void OnEvasion(){}//可继承成功闪避触发的函数private bool TargetCanAvoidAttack(CharacterStats _targetStats)//闪避计算{int totleEvation = _targetStats.evasion.GetValue() + _targetStats.agility.GetValue();//我被麻痹后//敌人的闪避率提升if (isShocked)totleEvation += 20;if (Random.Range(0, 100) < totleEvation){_targetStats.OnEvasion();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
}

PlayerStat.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerStats : CharacterStats
{private Player player;protected override void Start(){player = GetComponent<Player>();base.Start();}public override void DoDamage(CharacterStats _targetStats){base.DoDamage(_targetStats);}public override void TakeDamage(int _damage){base.TakeDamage(_damage);}protected override void Die(){base.Die();player.Die();GetComponent<PlayerItemDrop>()?.GenerateDrop();}protected override void DecreaseHealthBy(int _damage){base.DecreaseHealthBy(_damage);ItemData_Equipment currentArmor = Inventory.instance.GetEquipment(EquipmentType.Armor);if(currentArmor != null){currentArmor.Effect(player.transform);}}public override void OnEvasion(){player.skill.dogge.CreateMirageOnDoDogge();}
}
Dogge_Skill.cs
using UnityEngine;
using UnityEngine.UI;public class Dogge_Skill : Skill
{[Header("Dodge")][SerializeField] private UI_SkillTreeSlot unlockDoggeButton;[SerializeField] private int evasionAmount;public bool doggeUnlocked;[Header("Mirage dodge")][SerializeField] private UI_SkillTreeSlot unlockMirageDoggeButton;public bool dodgemirageUnlocked;protected override void Start(){base.Start();unlockDoggeButton.GetComponent<Button>().onClick.AddListener(UnlockDodge);unlockMirageDoggeButton.GetComponent<Button>().onClick.AddListener(UnlockMirageDogge);}private void UnlockDodge(){if (unlockDoggeButton.unlocked){player.stats.evasion.AddModifier(evasionAmount);Inventory.instance.UpdateStatsUI();doggeUnlocked = true;}}private void UnlockMirageDogge(){if (unlockMirageDoggeButton.unlocked)dodgemirageUnlocked = true;}public void CreateMirageOnDoDogge(){if (dodgemirageUnlocked)SkillManager.instance.clone.CreateClone(player.transform, Vector3.zero);}
}
SkillManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkillManager : MonoBehaviour
{public static SkillManager instance;public Dash_Skill dash { get; private set; }public Clone_Skill clone { get; private set; }public Sword_Skill sword { get; private set; }public Blackhole_Skill blackhole { get; private set; }public Crystal_Skill crystal { get; private set; }public Parry_Skill parry { get; private set; }public Dogge_Skill dogge { get; private set; }private void Awake(){if (instance != null){// Destroy(instance.gameObject);}elseinstance = this;}private void Start(){dash = GetComponent<Dash_Skill>();clone = GetComponent<Clone_Skill>();sword = GetComponent<Sword_Skill>();blackhole = GetComponent<Blackhole_Skill>();crystal = GetComponent<Crystal_Skill>();parry = GetComponent<Parry_Skill>();dogge = GetComponent<Dogge_Skill>();}
}

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

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

相关文章

基于springboot实现房屋租赁管理系统设计项目【项目源码+论文说明】

基于springboot实现房屋租赁管理系统设计演示 摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对房屋租赁信息管理混乱&…

[尚硅谷flink] 检查点笔记

在Flink中&#xff0c;有一套完整的容错机制来保证故障后的恢复&#xff0c;其中最重要的就是检查点。 文章目录 11.1 检查点11.1.1 检查点的保存1&#xff09;周期性的触发保存2&#xff09;保存的时间点3&#xff09;保存的具体流程 11.1.2 从检查点恢复状态11.1.3 检查点算法…

解读宁波TISAX:保障企业安全的关键

&#x1f352;宁波TISAX&#xff0c;❣️作为信息安全领域的&#x1f92d;重要认证体系&#xff0c;为企业&#x1f41e;提供了强大的&#x1f349;安全保障。&#x1f40b;TISAX&#xff0c;&#x1f697;全称为Trusted Information Security Assessment Exchange&#xff0c;…

【树哈希】CF1182D Complete Mirror

CF1182D - Complete Mirror Description 给定一个 n n n 个点的无根树&#xff0c;求一个树根 r o o t root root,使得对于任意两个节点 v 1 , v 2 v_1,v_2 v1​,v2​&#xff0c;若满足 d i s t ( v 1 , r o o t ) d i s t ( v 2 , r o o t ) dist(v_1,root)dist(v_2,ro…

都2024年了,线上部署你不会只会log 调试吧,Arthas了解下!

文章目录 一、什么是Arthas&#xff1f;⛅背景⚡Arthas能为我们做什么 二、部署Arthas三、Arthas 基础命令四、Arthas 项目命令实战⌚thread 线程阻塞⏰watch命令演示⚡cpu飙升演示⛽方法演示 &#x1f6a8;小结 一、什么是Arthas&#xff1f; Arthas 是一款线上监控诊断产品&a…

[Linux][基础IO][一][系统文件IO][文件描述符fd]详细解读

目录 0.预备知识1.系统文件I/O1.open2.write/read/close/lseek 2.文件描述符fd1.[0 & 1 & 2]2.什么是文件描述符&#xff1f;3.文件描述符的分配规则4.重定向5.使用dup2系统调用 -- 完成重定向6.FILE 0.预备知识 什么叫做文件呢&#xff1f; 站在系统的角度&#xff0…

解放双手,批量绕过403

将dirsearch扫描出来的结果复制到url.txt&#xff0c;如下所示 url.txt [21:18:16] 502 - 0B - /var/log/exception.log [21:18:21] 502 - 0B - /WEB-INF/jetty-env.xml [21:18:22] 502 - 0B - /WEB-INF/weblogic.xml [21:18:27] 502 - 0B - /wp-json/wp/v2/u…

Android IPC机制

在Android系统中&#xff0c;IPC&#xff08;Inter-Process Communication&#xff0c;进程间通讯&#xff09;是指在不同进程之间传送数据和通讯的机制。Android中的应用通常运行在独立的沙箱环境中的进程里&#xff0c;由于安全限制&#xff0c;这些进程无法直接访问彼此的内…

Ubuntu 22.04 开机自动挂载webdav - 设置开机自启脚本 - 解决坚果云webdav无写入权限

效果图&#xff1a; 前言&#xff1a; 1&#xff09;亲测/etc/fstab的办法没有成功自动挂载&#xff0c;换成传统的rc.local可以解决&#xff1b; 2&#xff09;rc-local.service是系统自带的一个开机自启服务&#xff0c;但是在 ubuntu 20.04 上&#xff0c;该服务默认没有开…

基于JSP的教务管理

摘要 随着现代技术的不断发展&#xff0c;计算机已经深度的应用到了当下的各个行业之中&#xff0c;教育行业也不例外。计算机对教育行业中的教务管理等内容的帮助&#xff0c;使得教职工从传统的手工办公像计算机辅助阶段迈进&#xff0c;并且实现了非常好的发展。现在的学校…

SDK-0.8.8-Release-版本+ApiMeta - ApiHug-Release

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace ​ 更…

回溯算法中常见的使用方法逻辑整理

回溯算法 常见的使用方法逻辑整理 1. 回溯算法 特点 回溯算法实际上一个类似枚举的搜索尝试过程&#xff0c;主要是在搜索尝试过程中寻找问题的解&#xff0c;当发现已不满足求解条件时&#xff0c;就“回溯”返回&#xff0c;尝试别的路径。回溯法是一种选优搜索法&#xff0…

基于springboot实现师生共评作业管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现师生共评作业管理系统演示 摘要 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#xff0c;针对这个问题开发一个专门适应师生作业交流形式的网站。本文介绍了师生共评的作业管理系统的开发全过程。通过分析企业对于师生共评的作业管理…

数据库:SQL分类之DQL详解

1.DQL语法 select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数 基本查询 条件查询&#xff08;where&#xff09; 聚合函数&#xff08;count、max、min、avg、sum &#xff09; 分组查询&…

代码整洁?我后悔重构了代码

原文&#xff1a;Dan Abramov - 2020.01.11 那是一个深夜。 我的同事刚刚提交了他们一周编写的代码。我们正在开发一个图形编辑器的画布&#xff0c;他们实现了通过拖动边缘的小手柄&#xff0c;来调整形状&#xff08;如矩形和椭圆&#xff09;的大小的功能。 代码是有效的…

实习僧网站的实习岗位信息分析

目录 背景描述数据说明数据集来源问题描述分析目标以及导入模块1. 数据导入2. 数据基本信息和基本处理3. 数据处理3.1 新建data_clean数据框3.2 数值型数据处理3.2.1 “auth_capital”&#xff08;注册资本&#xff09;3.2.2 “day_per_week”&#xff08;每周工作天数&#xf…

TFT显示屏驱动

REVIEW 已经学习过VGA 时序与实现-CSDN博客 VGA 多分辨率-CSDN博客 今天就来让TFT屏显示一下 ACZ702开发板管脚信息表 - ACZ702开发板 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn) 小梅哥视频&#xff1a;24 RGB TFT显示屏原理与驱动实现_哔哩哔哩_bilibili …

活动图高阶讲解-16

77 00:05:39,520 --> 00:05:41,520 另外一个就是循环 78 00:05:41,520 --> 00:05:45,520 如果怎么样 79 00:05:45,520 --> 00:05:47,520 就再做一遍 80 00:05:47,520 --> 00:05:49,520 如果还满足条件就再做一遍 81 00:05:49,520 --> 00:05:51,520 那就是循…

TG-12F使用SDK对接阿里生活物联网平台

文章目录 前言一、注意二、准备1. 安装Ubuntu&#xff08;版本20.04 X64&#xff09;程序运行时库。按顺序逐条执行命令&#xff1a;2. 安装Ubuntu&#xff08;版本20.04 X64&#xff09;依赖软件包。按照顺序逐条执行命令&#xff1a;3. 安装Python依赖包。按照顺序逐条执行命…

[spring] Spring Boot REST API - CRUD 操作

Spring Boot REST API - CRUD 操作 这里主要提一下 spring boot 创建 rest api&#xff0c;并对其进行 CRUD 操作 jackson & gson 目前浏览器和服务端主流的交互方式是使用 JSON(JavaScript Object Notation)&#xff0c;但是 JSON 没有办法直接和 Java 的 POJO 创建对应…