2D猎宝行动(类扫雷小游戏)DAY 9

xiaoxiao2025-04-24  7

1.制作道具栏的图标

2.完成UI的绘制并创建UI脚本

创建MainPanel类

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class MainPanel : MonoBehaviour { private static MainPanel _instance; public Image armorIcon; public Image keyIcon; public Image arrowIcon; public Image swordIcon; public Image hoeIcon; public Image hoeBag; public Image tntIcon; public Image tntBag; public Image mapIcon; public Image mapBag; public Image grassIcon; public Text levelText; public Text hpText; public Text armorText; public Text keyText; public Text weaponText; public Text hoeText; public Text tntText; public Text mapText; public Text goldText; private void Awake() { _instance = this; } }

3.完成道具记录变量和UI更新方法

完善UI代码

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class MainPanel : MonoBehaviour { private static MainPanel _instance; public Image armorIcon; public Image keyIcon; public Image arrowIcon; public Image arrowBg; public Image swordIcon; public Image hoeIcon; public Image hoeBag; public Image tntIcon; public Image tntBag; public Image mapIcon; public Image mapBag; public Image grassIcon; public Text levelText; public Text hpText; public Text armorText; public Text keyText; public Text weaponText; public Text hoeText; public Text tntText; public Text mapText; public Text goldText; public bool isHide = false; private void Awake() { _instance = this; } void Start() { UpdateUI(); } public void OnLevelButton() { if(isHide == false) { isHide = true; GetComponent<RectTransform>().DOAnchorPosY(-7, 0.5f); } else { isHide = false; GetComponent<RectTransform>().DOAnchorPosY(45, 0.5f); } } public void UpdateUI() { levelText.text = "Level" + GameManager._instance.lv; hpText.text = GameManager._instance.hp.ToString(); if(GameManager._instance.armor == 0) { armorIcon.gameObject.SetActive(false); armorText.gameObject.SetActive(false); } else { armorIcon.gameObject.SetActive(true); armorText.gameObject.SetActive(true); armorText.text = GameManager._instance.armor.ToString(); } if (GameManager._instance.key == 0) { keyIcon.gameObject.SetActive(false); keyText.gameObject.SetActive(false); } else { keyIcon.gameObject.SetActive(true); keyText.gameObject.SetActive(true); keyText.text = GameManager._instance.key.ToString(); } switch (GameManager._instance.weaponType) { case WeaponType.None: arrowBg.gameObject.SetActive(true); arrowIcon.gameObject.SetActive(false); swordIcon.gameObject.SetActive(false); weaponText.gameObject.SetActive(false); break; case WeaponType.Arrow: arrowBg.gameObject.SetActive(true); arrowIcon.gameObject.SetActive(true); swordIcon.gameObject.SetActive(false); weaponText.gameObject.SetActive(true); weaponText.text = GameManager._instance.arrow.ToString(); break; case WeaponType.Sword: arrowBg.gameObject.SetActive(false); arrowIcon.gameObject.SetActive(false); swordIcon.gameObject.SetActive(true); weaponText.gameObject.SetActive(false); break; } if (GameManager._instance.hoe == 0) { hoeIcon.gameObject.SetActive(false); hoeText.gameObject.SetActive(false); hoeBag.gameObject.SetActive(false); } else { hoeIcon.gameObject.SetActive(true); hoeText.gameObject.SetActive(true); hoeBag.gameObject.SetActive(true); hoeText.text = GameManager._instance.hoe.ToString(); } if (GameManager._instance.tnt == 0) { tntIcon.gameObject.SetActive(false); tntText.gameObject.SetActive(false); tntBag.gameObject.SetActive(false); } else { tntIcon.gameObject.SetActive(true); tntText.gameObject.SetActive(true); tntBag.gameObject.SetActive(true); tntText.text = GameManager._instance.tnt.ToString(); } if (GameManager._instance.map == 0) { mapIcon.gameObject.SetActive(false); mapText.gameObject.SetActive(false); mapBag.gameObject.SetActive(false); } else { mapIcon.gameObject.SetActive(true); mapText.gameObject.SetActive(true); mapBag.gameObject.SetActive(true); mapText.text = GameManager._instance.map.ToString(); } grassIcon.gameObject.SetActive(GameManager._instance.isGrass); goldText.text = GameManager._instance.gold.ToString(); } }

运行程序,如下图:

3.处理道具的拾取

分别在金钱和道具类里边添加获取方法

private void GetGold() { int x = 1; if (GameManager._instance.isGrass == true) x = 2; switch (goldType) { case GoldType.One: GameManager._instance.gold += 30 * x; break; case GoldType.Two: GameManager._instance.gold += 60 * x; break; case GoldType.Three: GameManager._instance.gold += 100 * x; break; case GoldType.Four: GameManager._instance.gold += 150 * x; break; case GoldType.Five: GameManager._instance.gold += 450 * x; break; case GoldType.Six: GameManager._instance.gold += 600 * x; break; case GoldType.Seven: GameManager._instance.gold += 1000 * x; break; } MainPanel._instance.UpdateUI(); } private void GetTool() { switch (toolType) { case ToolType.Hp: GameManager._instance.hp++; break; case ToolType.Armor: GameManager._instance.armor++; break; case ToolType.Sword: GameManager._instance.weaponType = WeaponType.Sword; GameManager._instance.armor = 0; break; case ToolType.Map: GameManager._instance.map++; break; case ToolType.Arrow: GameManager._instance.weaponType = WeaponType.Arrow; GameManager._instance.arrow++; break; case ToolType.Key: GameManager._instance.key++; break; case ToolType.Tnt: GameManager._instance.tnt++; break; case ToolType.Hoe: GameManager._instance.hoe++; break; case ToolType.Grass: GameManager._instance.isGrass = true; break; } MainPanel._instance.UpdateUI(); }

在GamaManager中添加受到伤害的方法

public void TakeDamage() { if(armor > 0) { armor--; } else { hp--; } if(hp == 0) { DisplayAllTraps(); ani.SetBool("Die", true); } else { ani.SetTrigger("TakeDamage"); } }

4.使用钥匙和武器道具

修改门中的方法和制作开门特效预制体

public override void OnLeftMouseButton() { if (Vector3.Distance(transform.position, GameManager._instance.player.transform.position) < 1.5f) { if (GameManager._instance.key > 0) { GameManager._instance.key--; MainPanel._instance.UpdateUI(); Instantiate(GameManager._instance.doorOpenEffect, transform); ToNumberElement(true); } else { base.OnLeftMouseButton(); } } else { base.OnLeftMouseButton(); } }

5.制作道具使用的范围提示效果

6.使用单选按钮组来选择道具的使用

7.使用锄头、炸药和地图道具

添加使用道具的方法SelectGizmos

using System.Collections; using System.Collections.Generic; using UnityEngine; public class SelectGizmos : MonoBehaviour { public ToolType toolType; private void OnMouseUp() { int x = (int)transform.position.x; int y = (int)transform.position.y; switch (toolType) { case ToolType.Map: MainPanel._instance.hoeToggle.isOn = false; GameManager._instance.map--; MainPanel._instance.UpdateUI(); for (int i = x - 3; i < x + 3; i++) { for (int j = y - 3; j < y + 3; j++) { if (i >= 0 && i < GameManager._instance.w && j >= 0 && j < GameManager._instance.h && GameManager._instance.mapArray[i, j].elementContent != ElementContent.Exit) { if(GameManager._instance.mapArray[i, j].elementContent ==ElementContent.Trap&& GameManager._instance.mapArray[i, j].elementState != ElementState.Marked) { GameManager._instance.mapArray[i, j].OnRightMouseButton(); } if (GameManager._instance.mapArray[i, j].elementContent != ElementContent.Trap && GameManager._instance.mapArray[i, j].elementState == ElementState.Marked) { GameManager._instance.mapArray[i, j].OnRightMouseButton(); } } } } break; case ToolType.Tnt: MainPanel._instance.tntToggle.isOn = false; GameManager._instance.tnt--; MainPanel._instance.UpdateUI(); for(int i = x - 1; i < x + 1; i++) { for(int j = y - 1; j < y + 1; j++) { if (i >= 0 && i < GameManager._instance.w && j >= 0 && j < GameManager._instance.h &&GameManager._instance.mapArray[i,j].elementContent!=ElementContent.Exit) { if(GameManager._instance.mapArray[i, j].elementType == ElementType.DoubleCovered) { ((DoubleCoveredElement)GameManager._instance.mapArray[i, j]).UncoverElementSingle(); } else { GameManager._instance.mapArray[i, j].ToNumberElement(true); } } } } break; case ToolType.Hoe: MainPanel._instance.hoeToggle.isOn = false; GameManager._instance.hoe--; MainPanel._instance.UpdateUI(); for (int i = x - 1; i < x + 1; i++) { for (int j = y - 1; j < y + 1; j++) { if (i >= 0 && i < GameManager._instance.w && j >= 0 && j < GameManager._instance.h && GameManager._instance.mapArray[i, j].elementContent != ElementContent.Exit) { if (GameManager._instance.mapArray[i, j].elementType != ElementType.CantCovered) { ((SingleCoveredElement)GameManager._instance.mapArray[i, j]).UncoverElementSingle(); } else { if (GameManager._instance.mapArray[i, j].elementContent == ElementContent.SmallWall) { GameManager._instance.mapArray[i, j].ToNumberElement(true); } } } } } break; default: break; } } }

运行程序,结果如下:

8.制作UI动效

修改更新UI的方法,并在其他地方进行参数修改

public void UpdateUI(params RectTransform[] rts) { foreach(RectTransform rt in rts) { rt.DOShakeScale(0.5f).onComplete += () => { rt.localScale = new Vector3(1, 1, 1); }; } }

9.资源池的简介与简单资源池的创建

什么是资源池

将一定数量的对象预先存储在资源池中,当需要的时候使用,而不是每次都实例化一个对象,不用的时候再放回。例如一款射击类游戏,需要不断的发射子弹,如果每发射一颗子弹,都要实例化一个对象,随后再销毁对象,再实例化对象,必然会消耗较大的内存。如果预先就将子弹实例化出一定的数量,并保存在弹夹中,发射的时候,取出来发射,不用的时候,再放回弹夹。如此反复利用,可以避免频繁实例化和销毁带来的性能消耗。这里的弹夹的概念就是资源池模式!  

于是首先先给特效创建一个枚举类型

public enum EffectType { SmokeEffect, UncoveredEffect, GoldEffect, DoorOpenEffect }

然后创建资源池管理类,并进行初始化

using System.Collections; using System.Collections.Generic; using UnityEngine; public class PoolManager : MonoBehaviour { public static PoolManager _instance; Dictionary<EffectType, List<GameObject>> poolListDic = new Dictionary<EffectType, List<GameObject>>(); List<GameObject> uncoveredEffectList = new List<GameObject>(); List<GameObject> smokeEffectList = new List<GameObject>(); List<GameObject> goldEffectList = new List<GameObject>(); List<GameObject> doorOpenEffectList = new List<GameObject>(); Dictionary<EffectType, int> poolListCapacityDic = new Dictionary<EffectType, int>(); int uncoveredEffectCapacity; int smokeEffectCapacity = 5; int goldEffectCapacity = 20; int doorOpenEffectCapacity = 5; Dictionary<EffectType, GameObject> effectGoDic = new Dictionary<EffectType, GameObject>(); private void Awake() { _instance = this; poolListDic.Add(EffectType.UncoveredEffect, uncoveredEffectList); poolListDic.Add(EffectType.SmokeEffect, uncoveredEffectList); poolListDic.Add(EffectType.GoldEffect, uncoveredEffectList); poolListDic.Add(EffectType.DoorOpenEffect, uncoveredEffectList); uncoveredEffectCapacity = (int)(GameManager._instance.w * GameManager._instance.h * 0.2f); poolListCapacityDic.Add(EffectType.UncoveredEffect, uncoveredEffectCapacity); poolListCapacityDic.Add(EffectType.SmokeEffect, smokeEffectCapacity); poolListCapacityDic.Add(EffectType.GoldEffect, goldEffectCapacity); poolListCapacityDic.Add(EffectType.DoorOpenEffect, doorOpenEffectCapacity); effectGoDic.Add(EffectType.UncoveredEffect, GameManager._instance.uncoveredEffect); effectGoDic.Add(EffectType.SmokeEffect, GameManager._instance.smokeEffect); effectGoDic.Add(EffectType.GoldEffect, GameManager._instance.goldEffect); effectGoDic.Add(EffectType.DoorOpenEffect, GameManager._instance.doorOpenEffect); } }

10.完成资源池的功能

完成资源池的添加,重置。

public GameObject GetInstance(EffectType type, Transform t = null,bool worldPosStays = false) { List<GameObject> list; poolListDic.TryGetValue(type, out list); if (list.Count > 0) { GameObject tempGo = list[list.Count - 1]; tempGo.SetActive(true); ResetInstance(tempGo); if(t!= null) { tempGo.transform.SetParent(t, worldPosStays); } list.RemoveAt(list.Count - 1); return tempGo; } else { GameObject go; effectGoDic.TryGetValue(type, out go); if (t != null) { return Instantiate(go, t, worldPosStays); } else { return Instantiate(go); } } } public void StoreInstance(EffectType type,GameObject go) { List<GameObject> list; poolListDic.TryGetValue(type, out list); int listCap; poolListCapacityDic.TryGetValue(type, out listCap); if (list.Count < listCap) { go.SetActive(false); list.Add(go); } else { Destroy(go); } } private void ResetInstance(GameObject go) { ParticleSystem ps = go.GetComponent<ParticleSystem>(); if(ps != null) { ps.Stop(); ps.Play(); } foreach(Transform t in go.transform) { ParticleSystem tps = go.GetComponent<ParticleSystem>(); if (tps != null) { tps.Stop(); tps.Play(); } } }

 

转载请注明原文地址: https://www.6miu.com/read-5029058.html

最新回复(0)