add stricks game, but not compileted
This commit is contained in:
parent
d0878733de
commit
2133187e72
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
372
Assets/Scripts/Client/ClientGameSticksSceneController.cs
Normal file
372
Assets/Scripts/Client/ClientGameSticksSceneController.cs
Normal file
@ -0,0 +1,372 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21be14704ca7f844e89b436aa94450c8
|
||||
@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
using Mirror.BouncyCastle.Tls.Crypto.Impl.BC;
|
||||
|
||||
@ -192,6 +192,11 @@ public class NetworkMessageHandler : MonoBehaviour
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "gameSticksFinish":
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
125
Assets/Scripts/Server/ServerGameSticksPanel.cs
Normal file
125
Assets/Scripts/Server/ServerGameSticksPanel.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Video;
|
||||
|
||||
public class ServerGameSticksPanel : MonoBehaviour
|
||||
{
|
||||
public static ServerGameSticksPanel Instance;
|
||||
|
||||
public GameObject introPanel;
|
||||
public GameObject playPanel;
|
||||
public GameObject checkPanel;
|
||||
|
||||
public VideoPlayer introVideoPlayer;
|
||||
public RawImage introRawImage;
|
||||
|
||||
public TMP_Text playStatusText;
|
||||
|
||||
private int gameTimeCountdownSecVal = 60;
|
||||
|
||||
public void processStep(int step)
|
||||
{
|
||||
if (introPanel)
|
||||
{
|
||||
introPanel.SetActive(step == 1);
|
||||
if (step == 1)
|
||||
{
|
||||
gameTimeCountdownSecVal = 60;
|
||||
if (introVideoPlayer)
|
||||
{
|
||||
introVideoPlayer.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (playPanel)
|
||||
{
|
||||
playPanel.SetActive(step == 2);
|
||||
if (step == 2)
|
||||
{
|
||||
StartCoroutine(GameTimeCountdown());
|
||||
}
|
||||
}
|
||||
if (checkPanel)
|
||||
{
|
||||
checkPanel.SetActive(step == 3);
|
||||
if (step == 3)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator GameTimeCountdown()
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
|
||||
|
||||
|
||||
gameTimeCountdownSecVal--;
|
||||
playStatusText.text = "倒計時 : <color=\"red\">" + gameTimeCountdownSecVal.ToString() + "</color>s";
|
||||
if (gameTimeCountdownSecVal > 0)
|
||||
{
|
||||
StartCoroutine(GameTimeCountdown());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ServerWorkSceneController.Instance)
|
||||
{
|
||||
ServerWorkSceneController.Instance.processStep(17); // go to gameWaittingPanel
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetupIntroVideoPlayer()
|
||||
{
|
||||
if (introVideoPlayer != null)
|
||||
{
|
||||
// 設置影片結束事件
|
||||
introVideoPlayer.loopPointReached += OnIntroVideoFinished;
|
||||
|
||||
// 設置影片顯示
|
||||
if (introVideoPlayer != null)
|
||||
{
|
||||
introVideoPlayer.targetTexture = null;
|
||||
introVideoPlayer.renderMode = VideoRenderMode.RenderTexture;
|
||||
RenderTexture rt = new RenderTexture(1920, 1080, 24);
|
||||
introVideoPlayer.targetTexture = rt;
|
||||
introRawImage.texture = rt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnIntroVideoFinished(VideoPlayer vp)
|
||||
{
|
||||
Debug.Log("影片播放完成");
|
||||
//StartCoroutine(LoadNextScene());
|
||||
processStep(2);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
SetupIntroVideoPlayer();
|
||||
init();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
processStep(1);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Server/ServerGameSticksPanel.cs.meta
Normal file
2
Assets/Scripts/Server/ServerGameSticksPanel.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9055ae24ecf67a444bc0730eb9b690a1
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user