using asap.core; using cfg; using Cinemachine; using GameCore; using System.Collections; using System.Collections.Generic; using UniRx; using UnityEngine; namespace game { public class WashingGameVacuumCleaner : WashingGameBase { [Tooltip("清洁区域")] [SerializeField] private List m_CleaningAreas = new List(); [Tooltip("垃圾")] [SerializeField] private List m_Trashes = new List(); [Tooltip("屏幕点坐标偏移")] [SerializeField] private Vector2 m_Offset = Vector2.zero; [Tooltip("垃圾消失时间")] [SerializeField] private float m_TrashDisappearTime = 0.1f; [Tooltip("垃圾消失距离")] [SerializeField] private float m_TrashDisappearDistance = 0.1f; #region 页面功能 private EventWashingPanel panel; private void InitPanel() { panel.SetDataManager(m_DataManager); if (m_DataManager.WashingData.IsAllGameOver == true) { panel.ShowForAllGameOver(); // 设置关闭按钮 panel.SetBtnCloseClickListener(OnBtnCloseClickListener); return; } panel.ShowForCleaning(); // 设置预览按钮 panel.SetBtnPreviewClickListener(null); // 设置关闭按钮 panel.SetBtnCloseClickListener(OnBtnCloseClickListener); m_IsGuiding = panel.InitGuidance(); } private void HideElectricityConsumption() { if (panel == null) return; panel.SetElectricityConsumptionVisible(false); } private void ShowElectricityConsumption() { panel.SetElectricityConsumptionVisible(true); } private void SetGestureFollowPosition(Vector2 position, float time = 0.1f) { if (panel == null) return; ShowElectricityConsumption(); //Vector3 worldPosition = Vector3.zero; RectTransformUtility.ScreenPointToWorldPointInRectangle( panel.gestureFollow.transform.GetComponent(), position, UIManager.Instance.UICanvas.worldCamera, out Vector3 worldPosition); panel.SetGestureFollowPosition(worldPosition); } private void OnBtnCloseClickListener() { // 关闭当前Act GContext.Publish(new UnloadActToNextAct()); } private bool m_HasPublishConclusion = false; private void UpdatePanelProgress() { if (panel != null) { float progress = CleaningProgress; panel.UpdateSingleProgress(progress); if (m_DataManager != null) m_DataManager.WashingData.Percent = progress; if (progress >= 0.999f) { if (m_HasPublishConclusion == false) { if (m_DataManager != null) { m_DataManager.WashingData.Percent = 1f; m_DataManager.WashingData.IsOver = true; m_DataManager.SyncData(); } FishingYachtAct.Publish(new EventWashingConclusionData()); m_HasPublishConclusion = true; } } else { m_HasPublishConclusion = false; } } } public float CleaningProgress { get { int count = m_Trashes.Count; int num = 0; EventWashingData washingData = null; if (m_DataManager != null) washingData = m_DataManager.WashingData; for (int i = 0; i < count; ++i) { if (m_Trashes[i].IsOver()) { num += 1; if (washingData != null) washingData.StepItems[i] = 1f; } else { if (washingData != null) washingData.StepItems[i] = 0f; } } return (float)num / count; } } #endregion #region 垃圾处理 private void StopAllTrashesAction() { int count = m_Trashes.Count; for (int i = 0; i < count; ++i) { m_Trashes[i].StopAction(); } } private void ResumeAllTrashesAction() { int count = m_Trashes.Count; for (int i = 0; i < count; ++i) { m_Trashes[i].StartAction(null); } } #endregion #region 数据&状态相关 public override void ResetAndInitData(CinemachineVirtualCamera virtualCamera, CameraFollowPathMoveController cameraFollowPathMoveController, OperatingToolsBase tool) { base.ResetAndInitData(virtualCamera, cameraFollowPathMoveController, tool); if (tool != null) { int count = m_Trashes.Count; for (int i = 0; i < count; i++) { var trash = m_Trashes[i]; trash.SetCleaner((ToolForFollowerAndNormalPosition)tool, ((ToolForFollowerAndNormalPosition)tool).RangeCoverage, m_TrashDisappearTime, OnTrashItemCompleteAction); } } } private void OnTrashItemCompleteAction(StuffTrash stuffTrash) { if (m_DataManager == null) return; EventWashingData washingData = m_DataManager.WashingData; int count = m_Trashes.Count; for (int i = 0; i < count; ++i) { if (m_Trashes[i] == stuffTrash) { washingData.StepItems[i] = 1f; break; } } m_DataManager.SyncData(); } public static float ScaleFactor { get { var dpi = Screen.dpi; if (dpi <= 0) { dpi = 200.0f; } return 200.0f / dpi; } } protected void CheckIsOver() { float progress = CleaningProgress; panel.UpdateSingleProgress(progress); if (m_DataManager != null) m_DataManager.WashingData.Percent = progress; if (progress >= 0.999f) { if (m_HasPublishConclusion == false) { if (m_DataManager != null) { m_DataManager.WashingData.Percent = 1f; m_DataManager.WashingData.IsOver = true; m_DataManager.SyncData(); } FishingYachtAct.Publish(new EventWashingConclusionData()); m_HasPublishConclusion = true; } } } #endregion #region 事件 private void InitEvent() { this.Subscribe(StartConclusion); this.Subscribe(StepOver); this.Subscribe(AllGameOver); this.Subscribe(UpdateBatteryInfo); GContext.OnEvent().Subscribe(GuideListener).AddTo(this.disposables); } private void GuideListener(AddIndexEvent addIndexEvent) { if (addIndexEvent.CompleteGuide == true && panel != null) { panel.CompleteGuidance(); m_IsGuiding = false; } } private bool m_IsUpdateBatteryInfo = true; private void UpdateBatteryInfo(EventWashingTokenUpdateData data) { if (panel != null && m_IsUpdateBatteryInfo == true) { panel.SetBatteryInfo(); } } protected virtual void StartConclusion(EventWashingConclusionData data) { panel.StartConclusion(); } private void StepOver(EventWashingStepOverData data) { m_IsUpdateBatteryInfo = false; GameOver(); FishingYachtAct.Publish(new EventWashingGameOverData()); } private void AllGameOver(EventWashingAllGameOverData data) { if (panel != null) { panel.ShowForAllGameOver(); } } #endregion #region 数据处理 private void SyncGameData() { if (m_DataManager == null) return; EventWashingData washingData = m_DataManager.WashingData; bool syncData = false; int count = m_Trashes.Count; if (washingData.StepItems.Count == 0 && washingData.Percent == 0f && washingData.IsOver == false) { for (int i = 0; i < count; i++) { washingData.StepItems.Add(0f); m_Trashes[i].gameObject.SetActive(true); } syncData = true; } else { for (int i = 0; i < count; i++) { if (washingData.StepItems.Count == i) { washingData.StepItems.Add(0f); m_Trashes[i].gameObject.SetActive(true); syncData = true; } else if (washingData.StepItems[i] >= 1f) { m_Trashes[i].SetStatus(EventWashingActionStatus.Ending); m_Trashes[i].gameObject.SetActive(false); } else { m_Trashes[i].SetStatus(EventWashingActionStatus.Invalid); m_Trashes[i].gameObject.SetActive(true); } } } if (syncData) m_DataManager.SyncData(); } protected override void SetEnergyEnough() { base.SetEnergyEnough(); if (panel != null) panel.SetEnergyEnough(); } protected override void SetEnergyShortage() { base.SetEnergyShortage(); if (panel != null) panel.SetEnergyShortage(); } #endregion #region 生命周期 public override void InitGame(string name) { base.InitGame(name); this.m_GameType = EventWashingOperation.Cleaning; m_IsGuiding = true; } public async override void EnterGame() { base.EnterGame(); m_IsUpdateBatteryInfo = true; // 打开页面(UI) GameObject pannelObj = await UIManager.Instance.ShowUI(UITypes.EventWashingPanel); panel = pannelObj.transform.GetComponent(); InitPanel(); InitEvent(); AfterEnterGame(); CheckIsOver(); } protected override void Update() { base.Update(); if (m_Tool == null) return; int count = m_CleaningAreas.Count; if (count < 1) return; UpdatePanelProgress(); if (m_IsGuiding == true) return; bool showPowerConsumption = false; Vector2 screenPosition = Vector2.zero; if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0)) { screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y) + m_Offset * ScaleFactor; Ray ray = Camera.main.ScreenPointToRay(screenPosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { for (int i = 0; i < count; i++) { if (hit.transform == m_CleaningAreas[i].transform) { if (!IsGameOver() && (HaveEnergy() || ConsumeTokens(1))) { var normal = hit.normal; var point = hit.point; ((ToolForFollowerAndNormalPosition)m_Tool).Follow(point, normal); showPowerConsumption = true; } } } } } if (showPowerConsumption) { SetGestureFollowPosition(screenPosition); m_Tool.StartExecuting(); } else { // 隐藏电量消耗 HideElectricityConsumption(); m_Tool.StopExecuting(); } } protected override void PauseGame() { base.PauseGame(); StopAllTrashesAction(); } protected override void ResumeGame() { base.ResumeGame(); ResumeAllTrashesAction(); } public override void Fresh(EventWashingDataManager dataManager) { base.Fresh(dataManager); int count = m_CleaningAreas.Count; for (int i = 0;i < count;i++) { m_CleaningAreas[i].gameObject.SetActive(true); } //count = m_Trashes.Count; //for (int i = 0; i < count; i++) //{ // m_Trashes[i].gameObject.SetActive(true); //} m_HasPublishConclusion = false; } public override void GameOver() { base.GameOver(); int count = m_CleaningAreas.Count; for (int i = 0; i < count; i++) { m_CleaningAreas[i].gameObject.SetActive(false); } count = m_Trashes.Count; for (int i = 0; i < count; i++) { m_Trashes[i].gameObject.SetActive(false); } } public override void SyncData() { SyncGameData(); base.SyncData(); } #endregion } }