Petition-to-the-Gods-V3/Assets/Scripts/Client/ClientGameSticksSceneController.cs
2025-11-19 08:05:11 +08:00

373 lines
9.5 KiB
C#

using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class ClientGameSticksSceneController : MonoBehaviour
{
public static ClientGameSticksSceneController Instance;
public GameObject introPanel;
public GameObject playPanel;
public GameObject stopPanel;
public GameObject finishPanel;
public TMP_Text playCountdownText;
public Transform incenseTransform;
public Transform incenseHolderTransform;
private Image sincerityMeterFill;
private float minAngle = 30f;
private float maxAngle = 150f;
private float dragSensitivity = 0.5f;
private bool isDragging = false;
private float currentAngle = 90f;
private Camera mainCamera;
private Coroutine windCoroutine;
private bool gameActive = true;
public Button finishGoToNextButton;
public Button finishBackToMenuButton;
private int playCountdownSecVal = 30;
private void Awake()
{
Instance = this;
}
public void init()
{
processStep(1);
gameActive = false;
}
IEnumerator StatusCountdown()
{
yield return new WaitForSeconds(1f);
playCountdownSecVal--;
playCountdownText.text = "時間倒數 " + playCountdownSecVal.ToString() + "秒";
if (playCountdownSecVal > 0)
{
StartCoroutine(StatusCountdown());
}
else
{
processStep(3);
}
}
IEnumerator NextStep(int step, int waitSec)
{
yield return new WaitForSeconds(waitSec);
processStep(step);
}
public void processStep(int step)
{
if (introPanel)
{
introPanel.SetActive(step == 1);
if (step == 1)
{
playCountdownSecVal = 10;
StartCoroutine(NextStep(2, 3));
}
}
if (playPanel)
{
playPanel.SetActive(step == 2);
if (step == 2)
{
StartCoroutine(StatusCountdown());
ResetIncense();
}
else
{
gameActive = false;
}
}
if (stopPanel)
{
stopPanel.SetActive(step == 3);
if (step == 3)
{
if (ClientMessageHandler.Instance)
{
ClientMessageHandler.Instance.SendMessageToServer("gameSticksFinish", "");
}
StartCoroutine(NextStep(4, 3));
}
}
if (finishPanel)
{
finishPanel.SetActive(step == 4);
}
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
if (finishGoToNextButton)
{
finishGoToNextButton.onClick.AddListener(finishGoToNextButton_onClicked);
}
if (finishBackToMenuButton)
{
finishBackToMenuButton.onClick.AddListener(finishBackToMenuButton_onClicked);
}
init();
}
private void finishGoToNextButton_onClicked()
{
if (ClientMessageHandler.Instance)
{
ClientMessageHandler.Instance.SendMessageToServer("getWords", "");
}
StartCoroutine(LoadNextScene("ClientGameBackToRealScene"));
}
private void finishBackToMenuButton_onClicked()
{
StartCoroutine(LoadNextScene("ClientGameScene"));
}
IEnumerator LoadNextScene(string sceneName)
{
yield return new WaitForSeconds(0f);
SceneManager.LoadScene(sceneName);
}
// Update is called once per frame
void Update()
{
if (gameActive)
{
HandleInput();
}
}
void HandleInput()
{
// 滑鼠/觸控輸入 (使用新輸入系統)
if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame)
{
Vector2 pointerPosition = Mouse.current.position.ReadValue();
if (IsPointerOverIncense(pointerPosition))
{
StopGame();
return;
}
}
if (Mouse.current != null && Mouse.current.leftButton.isPressed && isDragging)
{
Vector2 pointerPosition = Mouse.current.position.ReadValue();
UpdateAngleFromPointer(pointerPosition);
}
if (Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame)
{
isDragging = false;
}
// 觸控輸入支援
if (Touchscreen.current != null)
{
var touches = Touchscreen.current.touches;
for (int i = 0; i < touches.Count; i++)
{
var touch = touches[i];
if (!touch.isInProgress)
continue;
var phase = touch.phase.ReadValue();
var position = touch.position.ReadValue();
if (phase == UnityEngine.InputSystem.TouchPhase.Began)
{
if (IsPointerOverIncense(position))
{
StopGame();
return;
}
}
else if (phase == UnityEngine.InputSystem.TouchPhase.Moved && isDragging)
{
UpdateAngleFromPointer(position);
}
else if (phase == UnityEngine.InputSystem.TouchPhase.Ended ||
phase == UnityEngine.InputSystem.TouchPhase.Canceled)
{
isDragging = false;
}
}
}
}
bool IsPointerOverIncense(Vector2 screenPosition)
{
Ray ray = mainCamera.ScreenPointToRay(screenPosition);
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
if (hit.collider != null && hit.collider.transform == incenseTransform)
{
return true;
}
return false;
}
void UpdateAngleFromPointer(Vector2 screenPosition)
{
// 將螢幕座標轉換為世界座標
Vector3 worldPosition = mainCamera.ScreenToWorldPoint(screenPosition);
Vector3 holderPosition = incenseHolderTransform.position;
// 計算角度
Vector2 direction = new Vector2(worldPosition.x - holderPosition.x,
worldPosition.y - holderPosition.y);
float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
angle = 90f + angle;
// 限制角度範圍
angle = Mathf.Clamp(angle, minAngle, maxAngle);
UpdateDisplay(angle);
}
void UpdateDisplay(float angle)
{
currentAngle = angle;
// 更新香的旋轉 (從底部旋轉)
float rotationAngle = 90f - angle;
incenseTransform.localRotation = Quaternion.Euler(0, 0, rotationAngle);
// 更新角度顯示
//if (angleText != null)
//{
// angleText.text = $"{Mathf.Round(angle)}°";
//}
// 計算誠意指數
float sincerity = Mathf.Clamp01(angle / 90f) * 100f;
// 更新誠意條
if (sincerityMeterFill != null)
{
sincerityMeterFill.fillAmount = sincerity / 100f;
}
// 更新分數
//if (scoreText != null)
//{
// scoreText.text = $"{Mathf.Round(sincerity)}%";
//}
// 更新訊息
UpdateMessage(sincerity);
}
void UpdateMessage(float sincerity)
{
//if (messageText == null) return;
// 如果遊戲已停止,顯示特殊訊息
if (!gameActive)
{
//messageText.text = "🛑 遊戲已停止!點擊重置按鈕重新開始";
//messageText.color = new Color(1f, 0.5f, 0f);
return;
}
}
// 公開方法供按鈕調用
public void ResetIncense()
{
if (windCoroutine != null)
{
StopCoroutine(windCoroutine);
windCoroutine = null;
}
gameActive = true;
isDragging = false;
UpdateDisplay(90f);
}
public void StopGame()
{
gameActive = false;
isDragging = false;
if (windCoroutine != null)
{
StopCoroutine(windCoroutine);
windCoroutine = null;
}
// 更新訊息顯示
//if (messageText != null)
//{
// messageText.text = "🛑 遊戲已停止!點擊重置按鈕重新開始";
// messageText.color = new Color(1f, 0.5f, 0f);
//}
Debug.Log("遊戲已停止 - 香被觸碰");
}
public void RandomChallenge()
{
if (windCoroutine != null)
{
StopCoroutine(windCoroutine);
windCoroutine = null;
}
float randomAngle = Random.Range(minAngle, maxAngle);
UpdateDisplay(randomAngle);
}
public void ToggleWindMode()
{
if (windCoroutine != null)
{
StopCoroutine(windCoroutine);
windCoroutine = null;
}
else
{
windCoroutine = StartCoroutine(WindModeCoroutine());
}
}
IEnumerator WindModeCoroutine()
{
while (true)
{
float windForce = Random.Range(-5f, 5f);
float newAngle = Mathf.Clamp(currentAngle + windForce, minAngle, maxAngle);
UpdateDisplay(newAngle);
yield return new WaitForSeconds(0.2f);
}
}
}