Add initial game systems and input handling for player interactions
This commit is contained in:
36
Assets/Scripts/Core/GameEvents.cs
Normal file
36
Assets/Scripts/Core/GameEvents.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
public static class GameEvents
|
||||
{
|
||||
// Gameplay Events (Inputs to the systems)
|
||||
public static event Action<int> PresentCaught;
|
||||
public static event Action PresentDropped;
|
||||
|
||||
// State Changes (Outputs from the systems)
|
||||
public static event Action<int> ScoreUpdated;
|
||||
public static event Action<int> LivesUpdated;
|
||||
public static event Action<float> TimeUpdated;
|
||||
public static event Action GameOver;
|
||||
|
||||
// Invokers
|
||||
public static void ReportPresentCaught(int value) => PresentCaught?.Invoke(value);
|
||||
public static void ReportPresentDropped() => PresentDropped?.Invoke();
|
||||
public static void ReportScoreUpdated(int score) => ScoreUpdated?.Invoke(score);
|
||||
public static void ReportLivesUpdated(int lives) => LivesUpdated?.Invoke(lives);
|
||||
public static void ReportTimeUpdated(float time) => TimeUpdated?.Invoke(time);
|
||||
public static void ReportGameOver() => GameOver?.Invoke();
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
// Reset events when scene reloads to prevent memory leaks
|
||||
PresentCaught = null;
|
||||
PresentDropped = null;
|
||||
ScoreUpdated = null;
|
||||
LivesUpdated = null;
|
||||
TimeUpdated = null;
|
||||
GameOver = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/GameEvents.cs.meta
Normal file
3
Assets/Scripts/Core/GameEvents.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26df539822f340e29cceac4ec34dd771
|
||||
timeCreated: 1765312863
|
||||
8
Assets/Scripts/Core/GameMode.cs
Normal file
8
Assets/Scripts/Core/GameMode.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Core
|
||||
{
|
||||
public enum GameMode
|
||||
{
|
||||
Arcade,
|
||||
TimeAttack,
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/GameMode.cs.meta
Normal file
3
Assets/Scripts/Core/GameMode.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53351add092b4030b6c58e9f72380f6d
|
||||
timeCreated: 1765311817
|
||||
97
Assets/Scripts/Core/GameSession.cs
Normal file
97
Assets/Scripts/Core/GameSession.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
public class GameSession
|
||||
{
|
||||
public GameMode GameMode { get; private set; }
|
||||
public int Score { get; private set; }
|
||||
public int Lives { get; private set; }
|
||||
public float TimeRemaining { get; private set; }
|
||||
public bool IsGameOver { get; private set; }
|
||||
public int HighScore { get; private set; }
|
||||
|
||||
public event Action<int> OnScoreChanged;
|
||||
public event Action<int> OnLivesChanged;
|
||||
public event Action<float> OnTimeChanged;
|
||||
public event Action OnGameOver;
|
||||
|
||||
private readonly int _initialTimeOrLives;
|
||||
|
||||
public GameSession(GameMode gameMode, int initialValue, int currentHighScore)
|
||||
{
|
||||
GameMode = gameMode;
|
||||
Score = 0;
|
||||
IsGameOver = false;
|
||||
HighScore = currentHighScore;
|
||||
|
||||
switch (gameMode)
|
||||
{
|
||||
case GameMode.TimeAttack:
|
||||
TimeRemaining = initialValue;
|
||||
Lives = 1;
|
||||
break;
|
||||
case GameMode.Arcade:
|
||||
Lives = initialValue;
|
||||
TimeRemaining = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
{
|
||||
if (IsGameOver || GameMode != GameMode.TimeAttack) return;
|
||||
|
||||
TimeRemaining -= deltaTime;
|
||||
OnTimeChanged?.Invoke(TimeRemaining);
|
||||
|
||||
if (TimeRemaining <= 0)
|
||||
{
|
||||
TimeRemaining = 0;
|
||||
EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddScore(int points)
|
||||
{
|
||||
if (IsGameOver) return;
|
||||
|
||||
Score += points;
|
||||
OnScoreChanged?.Invoke(Score);
|
||||
}
|
||||
|
||||
public void LoseLife()
|
||||
{
|
||||
if (IsGameOver) return;
|
||||
|
||||
if (GameMode == GameMode.Arcade)
|
||||
{
|
||||
Lives--;
|
||||
OnLivesChanged?.Invoke(Lives);
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeRemaining -= _initialTimeOrLives;
|
||||
OnTimeChanged?.Invoke(TimeRemaining);
|
||||
}
|
||||
|
||||
if (Lives <= 0)
|
||||
{
|
||||
Lives = 0;
|
||||
EndGame();
|
||||
}
|
||||
}
|
||||
|
||||
private void EndGame()
|
||||
{
|
||||
IsGameOver = true;
|
||||
|
||||
if (Score > HighScore)
|
||||
{
|
||||
HighScore = Score;
|
||||
}
|
||||
|
||||
OnGameOver?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/GameSession.cs.meta
Normal file
3
Assets/Scripts/Core/GameSession.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e5b97c41204455ca44be18f18ddd3b3
|
||||
timeCreated: 1765307365
|
||||
3
Assets/Scripts/Core/Systems.meta
Normal file
3
Assets/Scripts/Core/Systems.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a13e7537abf404e9a3932ec3f9b4e58
|
||||
timeCreated: 1765312897
|
||||
35
Assets/Scripts/Core/Systems/LivesSystem.cs
Normal file
35
Assets/Scripts/Core/Systems/LivesSystem.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace Core.Systems
|
||||
{
|
||||
public class LivesSystem : IDisposable
|
||||
{
|
||||
private int _currentLives;
|
||||
|
||||
public LivesSystem(int initialLives)
|
||||
{
|
||||
_currentLives = initialLives;
|
||||
GameEvents.PresentDropped += OnPresentDropped;
|
||||
|
||||
GameEvents.ReportLivesUpdated(_currentLives);
|
||||
}
|
||||
|
||||
private void OnPresentDropped()
|
||||
{
|
||||
if (_currentLives <= 0) return;
|
||||
|
||||
_currentLives--;
|
||||
GameEvents.ReportLivesUpdated(_currentLives);
|
||||
|
||||
if (_currentLives <= 0)
|
||||
{
|
||||
GameEvents.ReportGameOver();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GameEvents.PresentDropped -= OnPresentDropped;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/Systems/LivesSystem.cs.meta
Normal file
3
Assets/Scripts/Core/Systems/LivesSystem.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 694c3777489643ee843bf35f734ac060
|
||||
timeCreated: 1765312961
|
||||
46
Assets/Scripts/Core/Systems/PersistenceSystem.cs
Normal file
46
Assets/Scripts/Core/Systems/PersistenceSystem.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Infrastructure;
|
||||
|
||||
namespace Core.Systems
|
||||
{
|
||||
public class PersistenceSystem : IDisposable
|
||||
{
|
||||
private readonly IPersistenceService _service;
|
||||
private readonly string _saveKey;
|
||||
private int _currentRunScore;
|
||||
|
||||
public PersistenceSystem(IPersistenceService service, string saveKey)
|
||||
{
|
||||
_service = service;
|
||||
_saveKey = saveKey;
|
||||
|
||||
GameEvents.ScoreUpdated += OnScoreUpdated;
|
||||
GameEvents.GameOver += OnGameOver;
|
||||
}
|
||||
|
||||
public int GetHighScore()
|
||||
{
|
||||
return _service.LoadHighScore(_saveKey);
|
||||
}
|
||||
|
||||
private void OnGameOver()
|
||||
{
|
||||
var existingHighScore = _service.LoadHighScore(_saveKey);
|
||||
if (_currentRunScore > existingHighScore)
|
||||
{
|
||||
_service.SaveHighScore(_saveKey, _currentRunScore);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScoreUpdated(int newScore)
|
||||
{
|
||||
_currentRunScore = newScore;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GameEvents.ScoreUpdated -= OnScoreUpdated;
|
||||
GameEvents.GameOver -= OnGameOver;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/Systems/PersistenceSystem.cs.meta
Normal file
3
Assets/Scripts/Core/Systems/PersistenceSystem.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99a4c19937ce4a97881d2796dead20d4
|
||||
timeCreated: 1765313464
|
||||
26
Assets/Scripts/Core/Systems/ScoreSystem.cs
Normal file
26
Assets/Scripts/Core/Systems/ScoreSystem.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
|
||||
namespace Core.Systems
|
||||
{
|
||||
public class ScoreSystem : IDisposable
|
||||
{
|
||||
private int _currentScore;
|
||||
|
||||
public ScoreSystem()
|
||||
{
|
||||
_currentScore = 0;
|
||||
GameEvents.PresentCaught += OnPresentCaught;
|
||||
}
|
||||
|
||||
private void OnPresentCaught(int value)
|
||||
{
|
||||
_currentScore += value;
|
||||
GameEvents.ReportScoreUpdated(_currentScore);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GameEvents.PresentCaught -= OnPresentCaught;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/Systems/ScoreSystem.cs.meta
Normal file
3
Assets/Scripts/Core/Systems/ScoreSystem.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9724125bb1674f2e9f8150c290b71d1a
|
||||
timeCreated: 1765312906
|
||||
51
Assets/Scripts/Core/Systems/TimeAttackSystem.cs
Normal file
51
Assets/Scripts/Core/Systems/TimeAttackSystem.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Core.Systems
|
||||
{
|
||||
public class TimeAttackSystem : IDisposable
|
||||
{
|
||||
private float _timeRemaining;
|
||||
private readonly float _penaltyPerDrop;
|
||||
|
||||
public TimeAttackSystem(float initialTime, float penaltyPerDrop = 5f)
|
||||
{
|
||||
_timeRemaining = initialTime;
|
||||
_penaltyPerDrop = penaltyPerDrop;
|
||||
|
||||
GameEvents.ReportTimeUpdated(_timeRemaining);
|
||||
|
||||
GameEvents.PresentDropped += OnPresentDropped;
|
||||
}
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
{
|
||||
if (_timeRemaining <= 0) return;
|
||||
|
||||
_timeRemaining -= deltaTime;
|
||||
|
||||
if (_timeRemaining <= 0)
|
||||
{
|
||||
_timeRemaining = 0;
|
||||
GameEvents.ReportTimeUpdated(0f);
|
||||
GameEvents.ReportGameOver();
|
||||
}
|
||||
else
|
||||
{
|
||||
GameEvents.ReportTimeUpdated(_timeRemaining);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPresentDropped()
|
||||
{
|
||||
if (_timeRemaining > 0)
|
||||
{
|
||||
_timeRemaining -= _penaltyPerDrop;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GameEvents.PresentDropped -= OnPresentDropped;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Core/Systems/TimeAttackSystem.cs.meta
Normal file
3
Assets/Scripts/Core/Systems/TimeAttackSystem.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81bda016e43341779a714e971304d37d
|
||||
timeCreated: 1765313331
|
||||
Reference in New Issue
Block a user