//根据城市总数,随机城市 private void CreateCities() { GameObject cityNode = GameObject.FindGameObjectWithTag(EGameConstL.TAG_CITY_NODE); if (!cityNode || !m_cityModel) { EUtilityHelperL.LogError("None city node or model!"); return; } //生成预定数量的城市 for (int i = 0; i < m_citiesCount; ++i) { City clone = Instantiate <City>(m_cityModel); clone.name = string.Format("City_{0}", i); clone.UnitName = clone.name; clone.transform.SetParent(cityNode.transform); clone.transform.localPosition = GetCityPos(); clone.transform.localScale = Vector3.one; clone.transform.localRotation = Quaternion.identity; clone.transform.gameObject.SetActive(true); //初始化城市 clone.Init(); } }
//*********************************************** private GridUnit GetGridClicked(Vector3 clickedWorldPos) { //转换空间到格子组织节点(GridUnits)的空间 clickedWorldPos = gridUnitsRoot.transform.InverseTransformPoint(clickedWorldPos); //初步判定所在行列 int row = Mathf.FloorToInt((clickedWorldPos.y - EGameConstL.Map_GridOffsetY * 0.5f) / -EGameConstL.Map_GridOffsetY); int column = Mathf.FloorToInt((clickedWorldPos.x + EGameConstL.Map_GridWidth * 0.5f - ((row & 1) == (EGameConstL.Map_FirstRowOffset ? 1 : 0) ? 0f : (EGameConstL.Map_GridWidth * 0.5f))) / EGameConstL.Map_GridWidth); int testRow = 0; int testColumn = 0; //二次判定,判定周围格子 GridUnit clickedGrid = null; float minDis = Mathf.Infinity; for (int r = -1; r <= 1; ++r) { for (int c = -1; c <= 1; ++c) { testRow = row + r; testColumn = column + c; if (testRow < 0 || testRow >= currentData.mapData.mapHeight || testColumn < 0 || testColumn >= currentData.mapData.mapWidth) { continue; } float distance = EUtilityHelperL.CalcDistanceInXYAxis(clickedWorldPos, currentData.mapData.mapGrids[testColumn, testRow].localPosition); if (distance < minDis && distance < EGameConstL.Map_HexRadius) { minDis = distance; clickedGrid = gridUnits[testColumn, testRow]; } } } return(clickedGrid); }
private void CreateHero() { GameObject m_heroNode = GameObject.FindGameObjectWithTag(EGameConstL.TAG_HERO_NODE); if (!m_heroModel || !m_heroNode) { return; } if (m_allFields.Count == 0) { EUtilityHelperL.LogWarning("请先创建野外"); return; } Hero clone = Instantiate <Hero>(m_heroModel); if (clone) { clone.name = string.Format("Hero_{0}", m_allHeros.Count); clone.transform.SetParent(m_heroNode.transform); m_allHeros.Add(clone); //在城市位置出生 int randIdx = Random.Range(0, m_allCities.Count); Vector3 pos = m_allCities[randIdx].transform.position; pos.y = 1.51f; clone.transform.position = pos; clone.gameObject.SetActive(true); //初始化 clone.Init(); clone.AddExp(Random.Range(0, 50)); } }
//准备加载战场 private void PrepareBattleMap() { if (currentData == null) { EUtilityHelperL.LogError("Prepare battle map failed. No battle data."); return; } gridUnits = new GridUnit[currentData.mapData.mapWidth, currentData.mapData.mapHeight]; for (int r = 0; r < currentData.mapData.mapHeight; ++r) { for (int c = 0; c < currentData.mapData.mapWidth; ++c) { GridUnitData gud = currentData.mapData.mapGrids[c, r]; if (gud != null) { //创建一个用于显示的格子对象 GridUnit gridUnit = CreateGrid(); if (gridUnit != null) { gridUnits[c, r] = gridUnit; gridUnit.transform.localPosition = gud.localPosition; gridUnit.name = string.Format("Grid_{0}_{1}", r, c); gridUnit.gridData = gud; gridUnit.RefreshColor(); gridUnit.gameObject.SetActive(true); } } } } }
//准备加载战场 private void PrepareBattleMap() { if (currentData == null) { EUtilityHelperL.LogError("Prepare battle map failed. No battle data."); return; } gridUnits = new GridUnit[currentData.mapWidth, currentData.mapHeight]; for (int row = 0; row < currentData.mapHeight; ++row) { for (int column = 0; column < currentData.mapWidth; ++column) { GridUnitData gud = currentData.mapGrids[column, row]; if (gud != null) { //创建一个用于显示的格子对象 GridUnit gu = CreateGrid(); if (gu != null) { gridUnits[column, row] = gu; gu.transform.localPosition = gud.localPosition; gu.name = string.Format("Grid_{0}_{1}", row, column); gu.gridData = gud; gu.Refresh(); gu.gameObject.SetActive(true); } } } } }
private void Init() { if (inited) { return; } inited = true; EUtilityHelperL.Log("Battle creator inited."); }
//拷贝文件夹 public static void CopyFolder(string _from, string _to) { // EUtilityHelperL.Log(string.Format("拷贝文件:从{0}到{1}", _from, _to)); if (Directory.Exists(_from) == false) { EUtilityHelperL.LogError("拷贝文件失败:文件不存在(" + _from + ")"); return; } if (Directory.Exists(_to) == false) { // EUtilityHelperL.Log(_to + "文件不存在,新建"); Directory.CreateDirectory(_to); } //TODO:先这么写吧,能用就行,有机会再完善 //拷贝.txt, .lua, .json string[] paths = Directory.GetFiles(_from, "*.*", SearchOption.TopDirectoryOnly); for (int i = 0; i < paths.Length; ++i) { paths[i] = paths[i].Replace('\\', '/'); string fileName = paths[i].Remove(0, paths[i].LastIndexOf("/") + 1); File.Copy(paths[i], _to + "/" + fileName, true); } // paths = Directory.GetFiles(_from, "*.json", SearchOption.TopDirectoryOnly); // for(int i = 0; i < paths.Length; ++i) // { // paths[i] = paths[i].Replace('\\','/'); // string fileName = paths[i].Remove(0, paths[i].LastIndexOf("/") + 1); // File.Copy(paths[i], _to + "/" + fileName, true); // } // paths = Directory.GetFiles(_from, "*.txt", SearchOption.TopDirectoryOnly); // for(int i = 0; i < paths.Length; ++i) // { // paths[i] = paths[i].Replace('\\','/'); // string fileName = paths[i].Remove(0, paths[i].LastIndexOf("/") + 1); // File.Copy(paths[i], _to + "/" + fileName, true); // } //拷贝文件夹 string[] folderPaths = Directory.GetDirectories(_from, "*", SearchOption.TopDirectoryOnly); for (int i = 0; i < folderPaths.Length; ++i) { folderPaths[i] = folderPaths[i].Replace('\\', '/'); string folderName = folderPaths[i].Remove(0, folderPaths[i].LastIndexOf("/") + 1); //递归拷贝 CopyFolder(folderPaths[i], _to + "/" + folderName); } }
/// <summary> /// //计算英雄探索某一野外的收益 /// </summary> /// <param name="heroData">英雄数据</param> /// <param name="heroPos">英雄位置</param> /// <param name="fieldData">野外数据</param> /// <param name="fieldPos">野外位置</param> /// <returns></returns> public float Calculate(HeroData heroData, Vector3 heroPos, FieldData fieldData, Vector3 fieldPos) { //收益 //经验 + 金钱 + 声望 float exp = CalculateExp(heroData, fieldData, fieldData.resRemain); float gold = CalculateGold(heroData, fieldData, fieldData.resRemain); float fame = CalculateFame(heroData, fieldData, fieldData.resRemain); //时间 float time = CalculateExploreTime(heroData, fieldData, fieldData.resRemain); //路途时间 float travelTime = EUtilityHelperL.CalcDistanceIn2D(heroPos, fieldPos) / heroData.moveSpeed; return((exp + gold + fame) / (time + travelTime + Mathf.Epsilon)); }
//获取文件名字 public static string GetFileName(string _path, bool hideBack = true) { int start = _path.LastIndexOf('/'); if (start >= 0) { string _temp = _path.Remove(0, start + 1); int end = _temp.IndexOf('.'); if (end >= 0 && hideBack) { return(_temp.Remove(end)); } } EUtilityHelperL.LogError("获取文件名称失败"); return(""); }
public override void Init(params object[] args) { if (m_inited) { return; } if (!m_fieldModel) { EUtilityHelperL.LogError("City unit error: none file model"); return; } //向世界管理器注册 WorldManager.Instance.OperateCity(this, true); m_inited = true; }
public BattleMapData CreateMap(int width, int height, int obstacleCount, int obstacleGap) { BattleMapData battleMapData = null; int mapID = 0; base.Create(out battleMapData, out mapID); if (battleMapData != null) { battleMapData.mapID = mapID; battleMapData.Generate(width, height, obstacleCount, obstacleGap); } else { EUtilityHelperL.LogError(string.Format("Create map failed->width:{0},height:{1}", width, height)); } return(battleMapData); }
//获取一个随机的野外位置 private Vector3 GetFieldPos(Transform city) { Vector3 randPos = Vector3.zero; //每次随机查找位置可以随机的机会,越大则越可能让世界摆放的相对分散,计算时间也越长 int chance = randomChance; //是否找到了合适的位置 bool findOut = false; List <Transform> temp = null; m_fieldClonesAroundCity.TryGetValue(city, out temp); while (chance > 0 && !findOut) { findOut = true; --chance; //在m_cityRadiusRange.x ~ m_cityRadiusRange.y半径范围内随机一个位置 //注意这里随机的位置是相对于当前city空间的 var randV2 = Random.insideUnitCircle.normalized * Random.Range(m_cityRadiusRange.x, m_cityRadiusRange.y); randPos.x = randV2.x; randPos.z = randV2.y; if (temp != null) { //计算与其他野外的位置关系 foreach (var item in temp) { //距离有点近呢 //需要将空间位置进行一次转换 if (EUtilityHelperL.CalcDistanceIn2D(city.InverseTransformPoint(item.transform.position), randPos) < m_fieldDensity) { findOut = false; break; } } } } //提醒一下 if (!findOut) { Debug.LogWarning("没有找到合适的野外位置,凑合一下吧~"); } return(randPos); }
/// <summary> /// 获得随机的野外位置 /// </summary> /// <param name="density">密度系数</param> /// <param name="minRadius">最小半径</param> /// <param name="maxRadius">最大半径</param> /// <returns></returns> private Vector3 GetFieldPos(float density, float minRadius, float maxRadius) { Vector3 randPos = Vector3.zero; //每次随机查找位置可以随机的机会,越大则越可能让世界摆放的相对分散,计算时间也越长 int chance = EGameConstL.FIELD_RAND_CHANCE; //是否找到了合适的位置 bool findOut = false; while (chance > 0 && !findOut) { findOut = true; --chance; //在m_cityRadiusRange.x ~ m_cityRadiusRange.y半径范围内随机一个位置 //注意这里随机的位置是相对于当前city空间的 var randV2 = Random.insideUnitCircle.normalized * Random.Range(minRadius, maxRadius); randPos.x = randV2.x; randPos.z = randV2.y; //计算与其他野外的位置关系 foreach (var item in m_roundFields) { //距离有点近呢 //需要将空间位置进行一次转换 if (EUtilityHelperL.CalcDistanceIn2D(transform.InverseTransformPoint(item.transform.position), randPos) < density) { findOut = false; break; } } } //提醒一下 if (!findOut) { Debug.LogWarning("Can not find out optimum random position for field..."); } return(randPos); }
//战场中铺设格子 public void Generate(int width, int height, int obstacleCount, int gap) { EUtilityHelperL.TimerStart(); if (width <= 0 || height <= 0) { return; } //记录地图宽高 mapWidth = width; mapHeight = height; //生成格子数组 mapGrids = new GridUnitData[mapWidth, mapHeight]; //全部生成为普通格子 for (int r = 0; r < mapHeight; ++r) { for (int c = 0; c < mapWidth; ++c) { GridUnitData gridUnitData = new GridUnitData(mapID, r, c); gridUnitData.localPosition = new Vector3( c * EGameConstL.Map_GridWidth + ((r & 1) == (EGameConstL.Map_FirstRowOffset ? 0 : 1) ? (EGameConstL.Map_GridWidth * 0.5f) : 0f), -r * EGameConstL.Map_GridOffsetY, 0 ); //初始设置为普通格子 gridUnitData.GridType = GridType.Normal; //保存 mapGrids[c, r] = gridUnitData; } } //随机一些障碍格子 GenerateObstacle(obstacleCount, gap); //整理格子列表 TidyGridList(); EUtilityHelperL.Log(string.Format("Generate map {0}, time cost:{1}", mapID, EUtilityHelperL.TimerEnd())); }
//选择城市 void SearchCity() { float dis = Mathf.Infinity; float tempDis = 0f; City target = null; var citys = WorldManager.Instance.AllCities; while (citys.MoveNext()) { tempDis = EUtilityHelperL.CalcDistanceIn2D_SQR(citys.Current.transform.position, transform.position); if (tempDis < dis) { target = citys.Current; dis = tempDis; } } if (target) { m_cityTarget = target; State = HeroState.Move; } }
/// <summary> /// 创建野外 /// </summary> /// <param name="count">创建数量</param> /// <param name="density">密度系数</param> /// <param name="minRadius">最小半径</param> /// <param name="maxRadius">最大半径</param> public void CreateFields(int count, float density, float minRadius, float maxRadius) { GameObject fieldNode = GameObject.FindGameObjectWithTag(EGameConstL.TAG_FIELD_NODE); if (!fieldNode || !m_fieldModel) { EUtilityHelperL.LogError("None filed node or model!"); return; } int created = 0; //生成预定数量的野外 for (int i = 0; i < count; ++i) { Field clone = Instantiate <Field>(m_fieldModel); clone.transform.SetParent(fieldNode.transform); //设置名字 clone.name = string.Format("Field_{0}_{1}", m_roundFields.Count, UnitName); clone.UnitName = clone.name; //设置所属城市 clone.CityUnit = this; //必须要做的转换 clone.transform.position = transform.TransformPoint(GetFieldPos(density, minRadius, maxRadius)); clone.transform.localScale = Vector3.one; clone.transform.localRotation = Quaternion.identity; clone.gameObject.SetActive(true); m_roundFields.Add(clone); clone.Init(); ++created; } }
//计算声望获取倍数 public float CalculateFameMultiple(HeroData heroData, FieldData fieldData) { int needLevel = 1; if (!fieldDiff.ContainsKey(fieldData.difficulty)) { EUtilityHelperL.LogWarning("错误的野外难度!"); } else { needLevel = Mathf.FloorToInt(fieldDiff[fieldData.difficulty].key); } //等级差距 float lvGap = heroData.level - needLevel; for (int i = 0; i < ladderFame.Length; ++i) { if (lvGap <= ladderFame[i].key) { return(ladderFame[i].value); } } return(ladderFame[ladderFame.Length - 1].value); }
//计算探索速度 public float CalculateExploreTimeMultiple(HeroData heroData, FieldData fieldData) { float strNeed = Mathf.Infinity; if (fieldDiff.ContainsKey(fieldData.difficulty)) { strNeed = fieldDiff[fieldData.difficulty].value; } else { EUtilityHelperL.LogError("错误的野外难度等级"); } //计算力量差距 int gap = Mathf.FloorToInt((heroData.strength - strNeed) / strNeed * 100f); for (int i = 0; i < ladderTime.Length; ++i) { if (gap <= ladderTime[i].key) { return(ladderTime[i].value); } } return(ladderTime[ladderTime.Length - 1].value); }
//获取一个随机的城市位置 private Vector3 GetCityPos() { Vector3 randPos = new Vector3(0f, 1.01f, 0f); //每次随机查找位置可以随机的机会,越大则越可能让世界摆放的相对分散,计算时间也越长 int chance = EGameConstL.CITY_RAND_CHANCE; //是否找到了合适的位置 bool findOut = false; while (chance > 0 && !findOut) { findOut = true; --chance; //随机一个位置 randPos.x = Random.Range(-m_mapSize.x * 0.5f, m_mapSize.x * 0.5f); randPos.z = Random.Range(-m_mapSize.y * 0.5f, m_mapSize.y * 0.5f); //计算与其他城市间的位置关系 foreach (var item in m_allCities) { //距离有点近呢 if (EUtilityHelperL.CalcDistanceIn2D(item.transform.localPosition, randPos) < m_cityDensity) { findOut = false; break; } } } //提醒一下 if (!findOut) { Debug.LogWarning("Can not find out optimum random position for city..."); } return(randPos); }
//放置一些障碍格子 private void DisposeGridUnits(int obstacle, int gap) { obstacle = Mathf.Min(mapWidth * mapHeight, obstacle); for (int i = 0; i < obstacle; ++i) { int randomIdx = -1; GridUnitData target = null; int tryTimes = 999; while (tryTimes > 0 && target == null) { randomIdx = Random.Range(0, normalGrids.Count); target = normalGrids[randomIdx]; //判断距离 for (int j = 0; j < obstacleGrids.Count; ++j) { var distance = obstacleGrids[j].Distance(target); if (obstacleGrids[j].Distance(target) < gap) { target = null; break; } } --tryTimes; } if (target != null) { SetGridType(target, GridType.Obstacle); normalGrids.RemoveAt(randomIdx); } else { EUtilityHelperL.LogWarning("Dispose grid unit data warning."); } } }
public void Init(params object[] args) { EUtilityHelperL.Log("Battle map manager inited."); }
private void TestNavigation() { //如果点击了鼠标左键 if (Input.GetMouseButtonDown(0)) { //计算点击位置 Vector3 clickedWorldPos = BattleCamera.ScreenToWorldPoint(Input.mousePosition); clickedWorldPos.z = 0; //判断是否有格子被点中? GridUnit clicked = GetGridClicked(clickedWorldPos); //点中了格子 if (clicked != null) { if (clicked.gridData.GridType == GridType.Obstacle) { //点中了障碍物! Debug.Log("Clicked obstacle."); return; } if (from == null) { //当前还没有选择起始地点 from = clicked; from.GridRenderType = GridRenderType.Start; } else if (to == null) { //两次点中了起点 if (from.Equals(clicked)) { return; } //当前没有选择终点 to = clicked; to.GridRenderType = GridRenderType.End; EUtilityHelperL.TimerStart(); int navTimes = 999; int count = navTimes; while (count > 0) { //有起点有终点,开始导航 if (MapNavigator.Instance.Navigate(currentData.mapData, from.gridData, to.gridData, path, searched)) { } else { //没有找到路径 Debug.LogError("Navitation failed. No path."); return; } --count; } TestGridRender(); EUtilityHelperL.Log(string.Format("Nav times:{0}, timeCost{1:00}", navTimes, EUtilityHelperL.TimerEnd())); } else { from.GridRenderType = GridRenderType.Normal; from = null; to.GridRenderType = GridRenderType.Normal; to = null; foreach (var item in searched) { gridUnits[item.column, item.row].GridRenderType = GridRenderType.Normal; } foreach (var item in path) { gridUnits[item.column, item.row].GridRenderType = GridRenderType.Normal; } } } //没有点中格子 else { if (from != null) { from.GridRenderType = GridRenderType.Normal; from = null; } if (to != null) { to.GridRenderType = GridRenderType.Normal; to = null; } foreach (var item in searched) { gridUnits[item.column, item.row].GridRenderType = GridRenderType.Normal; } foreach (var item in path) { gridUnits[item.column, item.row].GridRenderType = GridRenderType.Normal; } } } }