using Core.Utilities; using System; using System.Collections.Generic; using TowerDefense.Level; using TowerDefense.Towers; using TowerDefense.UI.HUD; using UnityEngine; using UnityEngine.UI; using TMPro; using KTGMGemClient; public class EndlessRandomTower : Singleton { // 当前类所在的Btn. public Button randomBtn; /// /// 倒计时对应的背景图片. /// public Image cdTimeBg; /// /// 倒计划对应的文字. /// public TextMeshProUGUI cdTimeText; /// /// 购买二级宝石的按钮贴图. /// public Sprite buyBtnLevelUp; protected bool bSetBuyLvlUp; protected bool bCdTimeStart; protected float btnLvlUpCdTime; public static bool MAX_INTERNAL = false; // 玩家初始阵容 protected List towerArray = new List(); protected int maxTower = 0; private bool firstDeploy = false; public static readonly int MAX_TOWERDIS = 5; // 开始出现技能塔的时间: public static float SKILL_TOWER_TIME = 30.0f; // 购买之后直接出现2级宝石的时间. public static float LEVELUP_TOWER_TIME = 10.0f; protected System.Random mRandom; protected int rTowerIdx = 2; // 所有宝石随机总权重 private int randomTotalWeight; // 所有宝石位置权重列表 private List weightList; // 是否初始化过出战数据 private bool isInitFightData = false; // Start is called before the first frame update void Start() { if (!EndlessLevelManager.instanceExists) Debug.LogError("[UI] No level manager for tower list"); foreach (Tower tower in EndlessLevelManager.instance.TowerLibrary) { towerArray.Add(tower); } maxTower = towerArray.Count; while (maxTower > MAX_TOWERDIS) { maxTower--; towerArray.RemoveAt(towerArray.Count - 1); } mRandom = new System.Random(); bSetBuyLvlUp = false; bCdTimeStart = false; cdTimeBg.gameObject.SetActive(false); cdTimeText.text = ""; } /// /// 获取TowerList. /// public List towerList { get { return this.towerArray; } } /// /// 处理按钮升级相关. /// private void Update() { float gstime = EndlessUIStart.instance.GameStartTime; if (gstime <= 0) return; if ((!bCdTimeStart) && (LEVELUP_TOWER_TIME - gstime) <= JsonDataCenter.TOWERLVLUP_CDTIME) { bCdTimeStart = true; btnLvlUpCdTime = LEVELUP_TOWER_TIME - gstime; cdTimeBg.gameObject.SetActive(true); } if ((!bSetBuyLvlUp) && (gstime > LEVELUP_TOWER_TIME)) { bSetBuyLvlUp = true; this.randomBtn.GetComponent().sprite = buyBtnLevelUp; cdTimeBg.gameObject.SetActive(false); cdTimeText.text = ""; } // 更新倒计时: if ((!bSetBuyLvlUp) && bCdTimeStart) { btnLvlUpCdTime -= Time.deltaTime; string distr = ((int)Math.Ceiling(btnLvlUpCdTime)).ToString() + "s"; cdTimeText.text = distr; } } public void actionTest() { multipara((str, strnew) => { Debug.Log(str + strnew); }, "Ying"); } protected void actadd(string str, string strnew) { Debug.Log("这是新增的Action String:" + str); } /// /// 用于测试Action参数的测试函数,Action多参数的用法. /// /// /// protected void multipara(Action act, string p1) { string finalstr = "Welcome to " + p1; act += this.actadd; act(finalstr, "YingYing"); } /// /// 获取序列化的Tower /// /// public Tower getRTower() { Tower t = this.towerArray[this.rTowerIdx]; rTowerIdx++; if (rTowerIdx >= this.maxTower) rTowerIdx = 2; return t; } /// /// 根据Tower名字获取当前的Tower指针。 /// /// /// public Tower getTowerByName(string name) { for (int ti = 0; ti < this.maxTower; ti++) if (name == this.towerArray[ti].towerName) return towerArray[ti]; return GetRandomTower(false); } /// /// 获取随机命中位置索引 /// private int GetRandomIndex(List list, int totalWeight) { int random = mRandom.Next(0, totalWeight); int index = -1; int total = 0; for (int i = 0; i < list.Count; ++i) { total += list[i]; if (total >= random) { index = i; break; } } return index; } /// /// 根据规则生成一个随机的塔 /// /// 是否仅产生精灵宝石,而不产生技能宝石 /// public Tower GetRandomTower(bool onlySpawnElf = true) { if (!isInitFightData) { isInitFightData = true; weightList = new List(); List posWeight = JsonDataCenter.GetList(); randomTotalWeight = 0; for (int i = 0; i < posWeight.Count; ++i) { weightList.Add(posWeight[i].weight); randomTotalWeight += posWeight[i].weight; } // 游戏开始之前先把出站组乱序 GameUtils.Shuffle(towerArray); } Tower ret = null; // 还没到技能时间,忽略掉技能宝石 if (onlySpawnElf) { // 精灵宝石位置索引列表 List elfIndexList = new List(); for (int i = 0; i < towerArray.Count; ++i) { if (towerArray[i].towerFeature == EFeatureTower.NULL) elfIndexList.Add(i); } // 没有上阵精灵宝石 if (elfIndexList.Count == 0) { Debug.LogError("--------------------- 没有上阵精灵宝石 ---------------------"); return null; } // 计算所有精灵宝石位置的总权重 int elfTotalWeight = 0; // 精灵宝石位置权重列表 List elfWeightList = new List(); for (int i = 0; i < elfIndexList.Count; ++i) { elfTotalWeight += weightList[elfIndexList[i]]; elfWeightList.Add(weightList[elfIndexList[i]]); } // 所有精灵宝石位置的权重都为0,直接等概率出一个精灵宝石 int index = elfTotalWeight == 0 ? mRandom.Next(0, elfIndexList.Count) : GetRandomIndex(elfWeightList, elfTotalWeight); ret = towerArray[elfIndexList[index]]; } // 可以自由产生 else { int index = randomTotalWeight == 0 ? mRandom.Next(0, towerArray.Count) : GetRandomIndex(weightList, randomTotalWeight); ret = towerArray[index]; } // 生成宝石成功,需要调整宝石位置,把宝石放到队尾 towerArray.Remove(ret); towerArray.Add(ret); return ret; } /// /// 随机购买Tower的入口,如果购买成功,则需要实时更新价格 /// public void onClick() { if (GameConfig.IsNewbie && !GameConfig.CanBuyNewTower) return; // 还没到技能时间,忽略掉技能宝石 Tower newTower = GetRandomTower(EndlessUIStart.instance.GameStartTime <= SKILL_TOWER_TIME); if (!newTower) throw new Exception("未能成功产生Tower"); RandomPlaceTower(newTower); } /// /// 随机找一个空白位置放置塔防 /// /// public bool RandomPlaceTower(Tower tower, int level = -1, int cost = -1, int posx = - 1, int posy = -1) { EndlessGameUI gameUI = EndlessGameUI.instance; if (gameUI.isBuilding) gameUI.CancelGhostPlacement(); if (EndlessUIStart.instance.GameStartTime >= LEVELUP_TOWER_TIME) return gameUI.RandomPlaceTower(tower, posx, posy, level == -1 ? 1 : level, cost); else return gameUI.RandomPlaceTower(tower, posx, posy, level == -1 ? 0 : level, cost); } /// /// 在固定的位置,放置一个随机的塔防类型. /// /// /// public void randomTower(int x, int y, int lvl, string tname = "") { int tidx = 0; Tower targetTower = null; if (tname == "") { tidx = mRandom.Next(0, this.maxTower); // 随机升级的Tower,不能升级成为成长骰子. int maxLoop = 20; while (this.towerArray[tidx].towerFeature != EFeatureTower.NULL) { tidx = mRandom.Next(0, this.maxTower); maxLoop--; if (maxLoop <= 0) { tidx = this.rTowerIdx; rTowerIdx++; if (rTowerIdx >= maxTower) rTowerIdx = 2; Debug.LogError("超级循环发生了."); break; } } targetTower = this.towerArray[tidx]; } else targetTower = getTowerByName(tname); // River: 随机找一个空白位置放置塔防。 EndlessGameUI.instance.RandomPlaceTower(targetTower, x, y, lvl); } }