319 lines
10 KiB
C#
319 lines
10 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using sc.modeling.splines.runtime;
|
|
using UnityEngine;
|
|
using UnityEngine.Splines;
|
|
|
|
namespace Gameplay.LegionBattle.View
|
|
{
|
|
|
|
public class FightLineControl : MonoBehaviour
|
|
{
|
|
|
|
public GameObject m_groundView;
|
|
public GameObject m_unitView;
|
|
public GameObject m_areaParent;
|
|
public GameObject m_unitsParent;
|
|
public GameObject m_linesParentt;
|
|
|
|
public GameObject m_boardQuadLeft;
|
|
public GameObject m_boardQuadRight;
|
|
|
|
public Camera m_mainCamera;
|
|
|
|
public SplineContainer m_splineContainerLeft;
|
|
public SplineContainer m_splineContainerRight;
|
|
|
|
private FightLineMap _baseMap;
|
|
|
|
private List<FightLineStandUnit> _team1StandUnits;
|
|
private List<FightLineStandUnit> _team2StandUnits;
|
|
|
|
public const int MAP_X_COUNT = 40;
|
|
public const int MAP_Y_COUNT = 40;
|
|
|
|
private void Awake()
|
|
{
|
|
_baseMap = new FightLineMap(MAP_X_COUNT, MAP_Y_COUNT);
|
|
_baseMap.FillStartWeights();
|
|
_baseMap.CreateViewMap(m_groundView, m_areaParent.transform);
|
|
_baseMap.UpdateColors();
|
|
|
|
_team1StandUnits = new List<FightLineStandUnit>();
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
var unit = new FightLineStandUnit();
|
|
unit.side = -1;
|
|
unit.standPos = new Vector2Int(0, 10 + i);
|
|
unit.CreateView(m_unitView, m_unitsParent.transform);
|
|
_team1StandUnits.Add(unit);
|
|
}
|
|
_team1StandUnits[0].isMainUnit = true;
|
|
|
|
_team2StandUnits = new List<FightLineStandUnit>();
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
var unit = new FightLineStandUnit();
|
|
unit.side = 1;
|
|
unit.standPos = new Vector2Int(39, 10 + i);
|
|
unit.CreateView(m_unitView, m_unitsParent.transform);
|
|
_team2StandUnits.Add(unit);
|
|
}
|
|
_team2StandUnits[0].isMainUnit = true;
|
|
}
|
|
|
|
private Vector3 _GetClickWorldPoint(Vector2 mousePos)
|
|
{
|
|
var ray = m_mainCamera.ScreenPointToRay(mousePos);
|
|
Physics.Raycast(ray, out RaycastHit hit);
|
|
var worldPos = hit.point;
|
|
return worldPos;
|
|
}
|
|
|
|
public static Vector2Int GetGridPosFromWorld(Vector3 worldPos)
|
|
{
|
|
worldPos.x += 0.5f;
|
|
worldPos.y += 0.5f;
|
|
// 获取点击的格子
|
|
var x = Mathf.FloorToInt(worldPos.x);
|
|
var y = Mathf.FloorToInt(worldPos.y);
|
|
return new Vector2Int(x, y);
|
|
}
|
|
|
|
public static Vector3 GetWorldPosFromGrid(Vector2Int gridPos)
|
|
{
|
|
var worldPos = new Vector3(gridPos.x, gridPos.y, 0);
|
|
return worldPos;
|
|
}
|
|
|
|
private FightLineStandUnit _selectUnit;
|
|
|
|
private void _HandleInput()
|
|
{
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
var hitWorldPos = _GetClickWorldPoint(Input.mousePosition);
|
|
var hitGridPos = GetGridPosFromWorld(hitWorldPos);
|
|
|
|
if (_selectUnit == null)
|
|
{
|
|
_selectUnit = _SelectUnit(hitGridPos);
|
|
if (_selectUnit != null)
|
|
{
|
|
Debug.Log("选中单位");
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("未选中单位 at " + hitGridPos);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (_selectUnit != null)
|
|
{
|
|
// 移动
|
|
var newWorldPos = GetWorldPosFromGrid(hitGridPos);
|
|
_selectUnit.MoveTo(newWorldPos);
|
|
_selectUnit = null;
|
|
Debug.Log("移动单位");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_baseMap.UpdateLineBoard();
|
|
_UpdateLines();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
_HandleInput();
|
|
|
|
var isStandChanged = false;
|
|
for (int i = 0; i < _team1StandUnits.Count; i++)
|
|
{
|
|
var unit = _team1StandUnits[i];
|
|
unit.LogicUpdate(Time.deltaTime);
|
|
isStandChanged = isStandChanged || unit.isStandChanged;
|
|
unit.isStandChanged = false;
|
|
}
|
|
|
|
for (int i = 0; i < _team2StandUnits.Count; i++)
|
|
{
|
|
var unit = _team2StandUnits[i];
|
|
unit.LogicUpdate(Time.deltaTime);
|
|
isStandChanged = isStandChanged || unit.isStandChanged;
|
|
unit.isStandChanged = false;
|
|
}
|
|
|
|
if (isStandChanged)
|
|
{
|
|
_UpdateStandMap();
|
|
// _baseMap.ReverseTuDian();
|
|
_baseMap.UpdateAreas();
|
|
_baseMap.ReverseAloneArea();
|
|
_baseMap.UpdateColors();
|
|
|
|
_baseMap.leftArea.CalcBoarder();
|
|
_baseMap.leftArea.CreateBoardView(m_boardQuadLeft, m_linesParentt.transform);
|
|
|
|
_baseMap.rightArea.CalcBoarder();
|
|
_baseMap.rightArea.CreateBoardView(m_boardQuadRight, m_linesParentt.transform);
|
|
|
|
_UpdateLines();
|
|
}
|
|
}
|
|
|
|
|
|
private void _UpdateLines()
|
|
{
|
|
_UpdateSpline(m_splineContainerLeft, _baseMap.leftArea);
|
|
|
|
_UpdateSpline(m_splineContainerRight, _baseMap.rightArea);
|
|
}
|
|
|
|
private void _UpdateSpline(SplineContainer splineContainer,
|
|
FightLineArea area)
|
|
{
|
|
if (!splineContainer.gameObject.activeSelf) return;
|
|
area.ReSortBoardCells();
|
|
var spLine = splineContainer.Splines[0];
|
|
area.finalLine.UpdateSpline(spLine);
|
|
// splineContainer.transform.GetComponent<SplineMesher>().Rebuild();
|
|
}
|
|
|
|
private List<FightLineCell> _leftCellList = new List<FightLineCell>();
|
|
private List<FightLineCell> _leftCellList2 = new List<FightLineCell>();
|
|
|
|
private List<FightLineCell> _rightCellList = new List<FightLineCell>();
|
|
private List<FightLineCell> _rightCellList2 = new List<FightLineCell>();
|
|
|
|
|
|
private void _UpdateStandMap()
|
|
{
|
|
_baseMap.ForEachCell(cell =>
|
|
{
|
|
cell.iteration = 0;
|
|
cell.isVisited = false;
|
|
});
|
|
|
|
_leftCellList.Clear();
|
|
_leftCellList2.Clear();
|
|
_rightCellList.Clear();
|
|
_rightCellList2.Clear();
|
|
|
|
for (int i = 0; i < _team1StandUnits.Count; i++)
|
|
{
|
|
var unit = _team1StandUnits[i];
|
|
var cell = _baseMap.GetCellByGridPos(unit.standPos);
|
|
if (cell == null) continue;
|
|
if (cell.standValue != unit.side)
|
|
{
|
|
continue;
|
|
}
|
|
cell.iteration = unit.maxDistance;
|
|
_leftCellList.Add(cell);
|
|
cell.isVisited = true;
|
|
if (unit.isMainUnit)
|
|
{
|
|
cell.isMainCell = true;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < _team2StandUnits.Count; i++)
|
|
{
|
|
var unit = _team2StandUnits[i];
|
|
var cell = _baseMap.GetCellByGridPos(unit.standPos);
|
|
if (cell == null) continue;
|
|
if (cell.standValue != unit.side)
|
|
{
|
|
continue;
|
|
}
|
|
cell.iteration = unit.maxDistance;
|
|
_rightCellList.Add(cell);
|
|
cell.isVisited = true;
|
|
if (unit.isMainUnit)
|
|
{
|
|
cell.isMainCell = true;
|
|
}
|
|
}
|
|
|
|
// 向外扩张
|
|
while (_leftCellList.Count > 0 || _rightCellList.Count > 0)
|
|
{
|
|
for (int i = 0; i < _leftCellList.Count; i++)
|
|
{
|
|
var cell = _leftCellList[i];
|
|
cell.standValue = -1;
|
|
if (cell.iteration > 0)
|
|
{
|
|
var aroundCellList = cell.neighbors;
|
|
for (int j = 0; j < aroundCellList.Count; j++)
|
|
{
|
|
var aroundCell = aroundCellList[j];
|
|
if (aroundCell.isVisited) continue;
|
|
aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration);
|
|
aroundCell.isVisited = true;
|
|
_leftCellList2.Add(aroundCell);
|
|
}
|
|
}
|
|
|
|
}
|
|
_leftCellList.Clear();
|
|
_leftCellList.AddRange(_leftCellList2);
|
|
_leftCellList2.Clear();
|
|
|
|
for (int i = 0; i < _rightCellList.Count; i++)
|
|
{
|
|
var cell = _rightCellList[i];
|
|
cell.standValue = 1;
|
|
if (cell.iteration > 0)
|
|
{
|
|
var aroundCellList = cell.neighbors;
|
|
for (int j = 0; j < aroundCellList.Count; j++)
|
|
{
|
|
var aroundCell = aroundCellList[j];
|
|
if (aroundCell.isVisited) continue;
|
|
aroundCell.isVisited = true;
|
|
aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration);
|
|
_rightCellList2.Add(aroundCell);
|
|
}
|
|
}
|
|
}
|
|
_rightCellList.Clear();
|
|
_rightCellList.AddRange(_rightCellList2);
|
|
_rightCellList2.Clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private FightLineStandUnit _SelectUnit(Vector2Int gridPos)
|
|
{
|
|
for (int i = 0; i < _team1StandUnits.Count; i++)
|
|
{
|
|
var unit = _team1StandUnits[i];
|
|
if (unit.standPos == gridPos)
|
|
{
|
|
return unit;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < _team2StandUnits.Count; i++)
|
|
{
|
|
var unit = _team2StandUnits[i];
|
|
if (unit.standPos == gridPos)
|
|
{
|
|
return unit;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
}
|