flakni krtka
This commit is contained in:
8
Assets/Scripts/flakni_krtka.meta
Normal file
8
Assets/Scripts/flakni_krtka.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53dcb38d358ca1348978dd32c4091cc3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
175
Assets/Scripts/flakni_krtka/Flakni_krtka.cs
Normal file
175
Assets/Scripts/flakni_krtka/Flakni_krtka.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
public class WhackTheMoleTask : MonoBehaviour, ITask
|
||||
{
|
||||
[Header("Game Settings")]
|
||||
public float moleAppearTime = 1.5f;
|
||||
public float spawnInterval = 0.8f;
|
||||
public int gameDuration = 30;
|
||||
public int scoreThreshold = 5;
|
||||
|
||||
[Header("UI References")]
|
||||
public List<Button> holes;
|
||||
public TMP_Text scoreText;
|
||||
public TMP_Text timerText;
|
||||
|
||||
public string TaskID { get; set; }
|
||||
public TaskType TaskType { get; set; }
|
||||
public string TaskName { get; set; }
|
||||
public (double, double) TaskLocation { get; set; }
|
||||
public bool IsCompleted { get; private set; }
|
||||
|
||||
private Action<ITask> _onCompleted;
|
||||
private Action<ITask> _onExit;
|
||||
|
||||
private int _score;
|
||||
private float _timer;
|
||||
private bool _gameRunning;
|
||||
private Button _activeMole;
|
||||
private int _lastHoleIndex = -1;
|
||||
private Coroutine _hideMoleCoroutine;
|
||||
private Coroutine _gameLoopCoroutine;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Initialize(null);
|
||||
_gameLoopCoroutine = StartCoroutine(GameLoop());
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
ExitTask(_onExit);
|
||||
}
|
||||
|
||||
public void Initialize(Action<ITask> onCompleted)
|
||||
{
|
||||
_onCompleted = onCompleted;
|
||||
IsCompleted = false;
|
||||
_score = 0;
|
||||
_gameRunning = false;
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
{
|
||||
if (IsCompleted) return;
|
||||
IsCompleted = true;
|
||||
_onCompleted?.Invoke(this);
|
||||
Debug.Log("[WhackTheMole] Task completed!");
|
||||
}
|
||||
|
||||
public void ExitTask(Action<ITask> onExit)
|
||||
{
|
||||
_onExit = onExit;
|
||||
_gameRunning = false;
|
||||
StopGameCoroutines();
|
||||
SetAllHolesInactive();
|
||||
_onExit?.Invoke(this);
|
||||
}
|
||||
|
||||
private IEnumerator GameLoop()
|
||||
{
|
||||
_timer = gameDuration;
|
||||
_score = 0;
|
||||
_gameRunning = true;
|
||||
RefreshScore();
|
||||
RefreshTimer();
|
||||
|
||||
float nextSpawn = 0f;
|
||||
|
||||
while (_timer > 0f && _gameRunning)
|
||||
{
|
||||
_timer -= Time.deltaTime;
|
||||
nextSpawn -= Time.deltaTime;
|
||||
RefreshTimer();
|
||||
|
||||
if (nextSpawn <= 0f)
|
||||
{
|
||||
SpawnMole();
|
||||
nextSpawn = spawnInterval;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
_gameRunning = false;
|
||||
EndGame();
|
||||
}
|
||||
|
||||
private void SpawnMole()
|
||||
{
|
||||
if (_hideMoleCoroutine != null) StopCoroutine(_hideMoleCoroutine);
|
||||
if (_activeMole != null) _activeMole.gameObject.SetActive(false);
|
||||
|
||||
int index = PickHoleIndex();
|
||||
_lastHoleIndex = index;
|
||||
_activeMole = holes[index];
|
||||
|
||||
_activeMole.gameObject.SetActive(true);
|
||||
Button thisHole = _activeMole;
|
||||
_activeMole.onClick.RemoveAllListeners();
|
||||
_activeMole.onClick.AddListener(() => OnMoleHit(thisHole));
|
||||
|
||||
_hideMoleCoroutine = StartCoroutine(AutoHideMole(thisHole, moleAppearTime));
|
||||
}
|
||||
|
||||
private int PickHoleIndex()
|
||||
{
|
||||
if (holes.Count == 1) return 0;
|
||||
int index;
|
||||
int attempts = 0;
|
||||
const int maxAttempts = 10;
|
||||
do
|
||||
{
|
||||
index = UnityEngine.Random.Range(0, holes.Count);
|
||||
attempts++;
|
||||
} while (index == _lastHoleIndex && attempts < maxAttempts);
|
||||
return index;
|
||||
}
|
||||
|
||||
private IEnumerator AutoHideMole(Button mole, float delay)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
if (mole == _activeMole) mole.gameObject.SetActive(false);
|
||||
_activeMole = null;
|
||||
_hideMoleCoroutine = null;
|
||||
}
|
||||
|
||||
private void OnMoleHit(Button mole)
|
||||
{
|
||||
if (!_gameRunning) return;
|
||||
if (_hideMoleCoroutine != null) StopCoroutine(_hideMoleCoroutine);
|
||||
mole.gameObject.SetActive(false);
|
||||
if (mole == _activeMole) _activeMole = null;
|
||||
_score++;
|
||||
RefreshScore();
|
||||
}
|
||||
|
||||
private void EndGame()
|
||||
{
|
||||
SetAllHolesInactive();
|
||||
Debug.Log($"[WhackTheMole] Game ended. Score: {_score} / Threshold: {scoreThreshold}");
|
||||
if (_score >= scoreThreshold) Complete();
|
||||
}
|
||||
|
||||
private void StopGameCoroutines()
|
||||
{
|
||||
if (_hideMoleCoroutine != null) { StopCoroutine(_hideMoleCoroutine); _hideMoleCoroutine = null; }
|
||||
if (_gameLoopCoroutine != null) { StopCoroutine(_gameLoopCoroutine); _gameLoopCoroutine = null; }
|
||||
}
|
||||
|
||||
private void SetAllHolesInactive()
|
||||
{
|
||||
if (holes == null) return;
|
||||
foreach (var hole in holes)
|
||||
if (hole != null) hole.gameObject.SetActive(false);
|
||||
_activeMole = null;
|
||||
}
|
||||
|
||||
private void RefreshScore() { if (scoreText != null) scoreText.text = $"Score: {_score}"; }
|
||||
private void RefreshTimer() { if (timerText != null) timerText.text = $"Time: {Mathf.CeilToInt(_timer)}"; }
|
||||
}
|
||||
2
Assets/Scripts/flakni_krtka/Flakni_krtka.cs.meta
Normal file
2
Assets/Scripts/flakni_krtka/Flakni_krtka.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47db745d0b3a1d94b8b60c34e8860151
|
||||
Reference in New Issue
Block a user