272 lines
9.7 KiB
C#
272 lines
9.7 KiB
C#
using asap.core;
|
||
using cfg;
|
||
using DG.Tweening;
|
||
using GameCore;
|
||
using System.Collections.Generic;
|
||
using System.Threading.Tasks;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class AquariumRandomMapPanel : MonoBehaviour
|
||
{
|
||
AquariumManager AM;
|
||
RectTransform Content;
|
||
GameObject img_map;
|
||
int allCount = 5;
|
||
float height;
|
||
public float StartDuration = 0.35f;
|
||
public float AccNum = 3;
|
||
public float[] SelectedMapNumRandUp = new[] { 2f, 5f };
|
||
public float[] SelectedMapNumRandDown = new[] { 4f, 7f };
|
||
int MapNum = 2;
|
||
float BackRatio = 2f;
|
||
IUIService uIService;
|
||
float LoopDuration = 0.125f;
|
||
|
||
GameObject result;
|
||
TMP_Text text_map;
|
||
TMP_Text text_level;
|
||
AquariumDetectEgg[] aquariumDetectEggs;
|
||
Transform eggRoot;
|
||
Tables _tables;
|
||
Transform door;
|
||
private void Awake()
|
||
{
|
||
_tables = GContext.container.Resolve<Tables>();
|
||
uIService = GContext.container.Resolve<IUIService>();
|
||
AM = GContext.container.Resolve<AquariumManager>();
|
||
Content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
|
||
img_map = transform.Find("Viewport/Content/Item").gameObject;
|
||
height = img_map.GetComponent<RectTransform>().rect.height;
|
||
img_map.SetActive(false);
|
||
result = transform.Find("result").gameObject;
|
||
text_map = transform.Find("result/text_map").GetComponent<TMP_Text>();
|
||
text_level = transform.Find("result/fishcard/text_level").GetComponent<TMP_Text>();
|
||
eggRoot = transform.Find("eggRoot");
|
||
aquariumDetectEggs = eggRoot.GetComponentsInChildren<AquariumDetectEgg>();
|
||
//eggRoot.gameObject.SetActive(false);
|
||
door = transform.Find("door");
|
||
}
|
||
//private void Start()
|
||
//{
|
||
// result.SetActive(false);
|
||
//}
|
||
bool isUP;
|
||
public void SetMap()
|
||
{
|
||
isUP = Random.value < 0.5f;
|
||
float t = Random.Range(0f, 1f);
|
||
if (isUP)
|
||
{
|
||
BackRatio = SelectedMapNumRandUp[0] + (SelectedMapNumRandUp[1] - SelectedMapNumRandUp[0]) * t;
|
||
}
|
||
else
|
||
{
|
||
BackRatio = SelectedMapNumRandDown[0] + (SelectedMapNumRandDown[1] - SelectedMapNumRandDown[0]) * t;
|
||
}
|
||
MapNum = Mathf.CeilToInt(BackRatio);
|
||
PlayerData playerData = GContext.container.Resolve<PlayerData>();
|
||
AM.GetRandmMap();
|
||
var lastMapID = playerData.lastMapId;
|
||
List<MapData> mapDatas = _tables.TbMapData.DataList;
|
||
List<int> indexs = new List<int>
|
||
{
|
||
0,1
|
||
};
|
||
for (int i = 2; i < mapDatas.Count; i++)
|
||
{
|
||
if (mapDatas[i].ID <= lastMapID)
|
||
{
|
||
indexs.Insert(Random.Range(0, indexs.Count), i);
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
while (indexs.Count < allCount + MapNum)
|
||
{
|
||
indexs.AddRange(indexs);
|
||
}
|
||
|
||
List<int> newIDs = indexs;
|
||
for (int i = 0; i < allCount + MapNum; i++)
|
||
{
|
||
SetMapBg(mapDatas[newIDs[i]].Bg);
|
||
}
|
||
var mapData = _tables.TbMapData.DataMap[AM.MapId];
|
||
SetMapBg(mapData.Bg);
|
||
SetMapBg(mapDatas[newIDs[0]].Bg);
|
||
text_map.text = LocalizationMgr.GetText(mapData.Name_l10n_key);
|
||
string levelLV = LocalizationMgr.GetText("UI_FishingMapPanel_101006");
|
||
int fishCardLevel = GContext.container.Resolve<PlayerFishData>().GetFishLevelByMap(AM.MapId);
|
||
text_level.text = levelLV + fishCardLevel.ToString();
|
||
}
|
||
public async Task PlayMap()
|
||
{
|
||
var sequence = DOTween.Sequence();
|
||
//sequence.Append(door.DOLocalMoveX(900, 0.5f).SetEase(Ease.Linear));
|
||
float subHeight = height * AccNum;
|
||
float time = 2 * AccNum / (1 / StartDuration + 1 / LoopDuration);
|
||
sequence.Append(Content.DOAnchorPosY(subHeight, time).SetEase(Ease.InQuad));
|
||
float timer1 = LoopDuration * (allCount - AccNum);
|
||
sequence.Append(Content.DOAnchorPosY(allCount * height, timer1).SetLoops(2, LoopType.Restart).SetEase(Ease.Linear));
|
||
//跑马灯动画
|
||
float timer2 = 0;
|
||
float ratio = MapNum - BackRatio;
|
||
if (ratio > 0.01)
|
||
{
|
||
timer2 = LoopDuration * ratio;
|
||
sequence.Append(Content.DOAnchorPosY((allCount + ratio) * height, timer2).SetEase(Ease.Linear));
|
||
}
|
||
sequence.Play();
|
||
await Awaiters.Seconds(time + timer1 * 2 + timer2);
|
||
await SharkAni();
|
||
}
|
||
void SetMapBg(string bg)
|
||
{
|
||
GameObject go = Instantiate(img_map, Content);
|
||
Image image = go.transform.GetChild(0).GetComponent<Image>();
|
||
go.SetActive(true);
|
||
uIService.SetImageSprite(image, bg);
|
||
}
|
||
|
||
public void InitEgg()
|
||
{
|
||
//开始随机蛋蛋
|
||
for (int i = 0; i < aquariumDetectEggs.Length; i++)
|
||
{
|
||
if (i < AM.Slot)
|
||
{
|
||
AquariumEgg aquariumEgg = _tables.TbAquariumEgg.GetOrDefault(AM.data.slotDatas[i].eggId);
|
||
aquariumDetectEggs[i].SetIcon(AM.eggNames, aquariumEgg.Icon, i);
|
||
}
|
||
else
|
||
{
|
||
aquariumDetectEggs[i].gameObject.SetActive(false);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void PlayEgg()
|
||
{
|
||
//开始随机蛋蛋
|
||
for (int i = 0; i < aquariumDetectEggs.Length; i++)
|
||
{
|
||
if (i < AM.Slot)
|
||
{
|
||
//AquariumEgg aquariumEgg = _tables.TbAquariumEgg.GetOrDefault(AM.data.slotDatas[i].eggId);
|
||
aquariumDetectEggs[i].Play();
|
||
}
|
||
}
|
||
}
|
||
public void HideMap()
|
||
{
|
||
Content.gameObject.SetActive(false);
|
||
}
|
||
|
||
[Header("物理参数")]
|
||
[SerializeField, Min(1), Tooltip("弹簧刚度 k (N·m/rad)")]
|
||
private float springStiffness = 100f;
|
||
[SerializeField, Min(1), Tooltip("阻尼系数 (N·m·s/rad)")]
|
||
private float dampingRatio = 15f;
|
||
[SerializeField, Min(0.1f), Tooltip("动摩擦 (N·m) T_k")]
|
||
private float dynamicFriction = 3f;
|
||
[SerializeField, Min(0.1f), Tooltip("转动惯量 (kg·m²)")]
|
||
private float momentOfInertia = 1.0f;
|
||
|
||
//匀速进入减速的角度,是相对于第一次减速阶段稳定角的角度,正数(减)在奖励顺时针方向,负数(加)在目标点逆时针方向
|
||
private float valueOffset2 = 200f;
|
||
[Header("减速阶段")]
|
||
[SerializeField, Tooltip("停留左侧时,匀速进入减速的角度,是相对于第一次减速阶段稳定角的角度")]
|
||
private float[] valueOffsetToTmpStableUp = new float[2] { 0.2f, 0.4f };
|
||
[SerializeField, Tooltip("停留右侧时,匀速进入减速的角度")]
|
||
private float[] valueOffsetToTmpStableDown = new float[2] { -0.2f, -0.4f };
|
||
|
||
[Header("停止条件")]
|
||
[SerializeField, Min(10f), Tooltip("第一阶段减速的速度停止条件")]
|
||
private float velocityStop = 30f;
|
||
[SerializeField, Min(10f), Tooltip("第二阶段减速的速度停止条件,!!!必须小于 velocityStop !!! ")]
|
||
private float velocityStopFinal = 10f;
|
||
[SerializeField, Tooltip("第一阶段减速的角度停止条件")]
|
||
private float valueStopRatio = 5f;
|
||
[SerializeField, Tooltip("第二阶段减速的角度停止条件")]
|
||
private float valueStopFinalRatio = 0.1f;
|
||
|
||
private float currentValue = 0f;
|
||
private float currentVelocity = 0f;
|
||
private float targetValue = 0f;
|
||
bool revertTargetValue = false;
|
||
bool effectTask;
|
||
|
||
private void DecelerationgAni(float deltaTime)
|
||
{
|
||
float valueError = currentValue - targetValue;
|
||
int direction = valueError > 0 ? 1 : -1;
|
||
float springTorque = springStiffness * Mathf.Abs(valueError) * direction;
|
||
float dampingTorque = -dampingRatio * currentVelocity;
|
||
float frictionTorque = CalculateFrictionTorque();
|
||
float totalTorque = springTorque + dampingTorque + frictionTorque;
|
||
float angularAcceleration = totalTorque / momentOfInertia;
|
||
currentVelocity += angularAcceleration * deltaTime;
|
||
|
||
CheckStopCondition();
|
||
}
|
||
private float CalculateFrictionTorque()
|
||
{
|
||
return -dynamicFriction * Mathf.Sign(currentVelocity);
|
||
}
|
||
private void CheckStopCondition()
|
||
{
|
||
float valueError = Mathf.Abs(currentValue - targetValue);
|
||
|
||
bool inPosition = valueError < Mathf.Abs(valueStopRatio);
|
||
bool slowEnough = Mathf.Abs(currentVelocity) < velocityStop;
|
||
|
||
bool inPositionFinal = valueError < Mathf.Abs(valueStopFinalRatio);
|
||
bool slowEnoughFinal = Mathf.Abs(currentVelocity) < velocityStopFinal;
|
||
|
||
if (inPosition && slowEnough && !revertTargetValue)
|
||
{
|
||
targetValue -= valueOffset2;
|
||
revertTargetValue = true;
|
||
}
|
||
else if (inPositionFinal && slowEnoughFinal)
|
||
{
|
||
currentVelocity = 0f;
|
||
currentValue = targetValue;
|
||
revertTargetValue = false;
|
||
effectTask = false;
|
||
}
|
||
}
|
||
public async Task SharkAni()
|
||
{
|
||
float tmpValue2;
|
||
if (isUP)
|
||
{
|
||
tmpValue2 = UnityEngine.Random.Range(valueOffsetToTmpStableUp[0], valueOffsetToTmpStableUp[1]);
|
||
}
|
||
else
|
||
{
|
||
tmpValue2 = UnityEngine.Random.Range(valueOffsetToTmpStableDown[0], valueOffsetToTmpStableDown[1]);
|
||
}
|
||
valueOffset2 = tmpValue2 * height;
|
||
|
||
revertTargetValue = false;
|
||
targetValue = (allCount + MapNum) * height;
|
||
targetValue += valueOffset2;
|
||
currentValue = allCount * height;
|
||
currentVelocity = -height / LoopDuration;
|
||
effectTask = true;
|
||
while (effectTask)
|
||
{
|
||
DecelerationgAni(Time.deltaTime);
|
||
currentValue -= currentVelocity * Time.deltaTime;
|
||
Content.anchoredPosition = new Vector2(0, currentValue);
|
||
await Awaiters.NextFrame;
|
||
}
|
||
}
|
||
}
|