141 lines
4.0 KiB
C#
141 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Core.Ports;
|
|
|
|
namespace Core.Domain
|
|
{
|
|
public class GameSession
|
|
{
|
|
private const string HighScoreKey = "HighScore";
|
|
private const float NpcSpawnTime = 4f;
|
|
private const float PowerUpSpawnInterval = 25f;
|
|
|
|
public int Score { get; private set; }
|
|
public int HighScore { get; private set; }
|
|
public bool IsGameOver { get; private set; }
|
|
|
|
public event Action<int> OnScoreChanged;
|
|
public event Action<string> OnOrbSpawned;
|
|
public event Action OnOrbReset;
|
|
public event Action OnGameOver;
|
|
public event Action OnSpawnNpc;
|
|
public event Action<PowerUpType, string> OnSpawnPowerUp;
|
|
|
|
private readonly List<Tile> _tiles;
|
|
private readonly IPersistenceService _persistenceService;
|
|
private readonly Random _rng = new();
|
|
private int _playerFloorIndex = 0;
|
|
private float _timeSinceStart;
|
|
private bool _npcSpawned;
|
|
private float _powerUpTimer;
|
|
|
|
public GameSession(List<Tile> tiles, IPersistenceService persistenceService)
|
|
{
|
|
_tiles = tiles;
|
|
_persistenceService = persistenceService;
|
|
|
|
Score = 0;
|
|
IsGameOver = false;
|
|
|
|
HighScore = _persistenceService.Load(HighScoreKey, 0);
|
|
}
|
|
|
|
public void StartGame()
|
|
{
|
|
_timeSinceStart = 0f;
|
|
_powerUpTimer = 0f;
|
|
_npcSpawned = false;
|
|
|
|
SpawnNextOrb();
|
|
}
|
|
|
|
public void Tick(float deltaTime)
|
|
{
|
|
if (IsGameOver) return;
|
|
|
|
_timeSinceStart += deltaTime;
|
|
if (!_npcSpawned && _timeSinceStart >= NpcSpawnTime)
|
|
{
|
|
_npcSpawned = true;
|
|
OnSpawnNpc?.Invoke();
|
|
}
|
|
|
|
_powerUpTimer += deltaTime;
|
|
if (_powerUpTimer >= PowerUpSpawnInterval)
|
|
{
|
|
_powerUpTimer = 0f;
|
|
SpawnRandomPowerUp();
|
|
}
|
|
}
|
|
|
|
public void OrbCollected()
|
|
{
|
|
if (IsGameOver) return;
|
|
|
|
Score += 10;
|
|
OnScoreChanged?.Invoke(Score);
|
|
SpawnNextOrb();
|
|
}
|
|
|
|
private void SpawnNextOrb()
|
|
{
|
|
var validTiles = _tiles.FindAll(t =>
|
|
t.CurrentState == TileState.Stable &&
|
|
t.Floor == _playerFloorIndex
|
|
);
|
|
|
|
if (validTiles.Count == 0)
|
|
{
|
|
validTiles = _tiles.FindAll(t => t.CurrentState == TileState.Stable);
|
|
}
|
|
|
|
if (validTiles.Count == 0)
|
|
{
|
|
EndGame();
|
|
return;
|
|
}
|
|
|
|
var pick = validTiles[_rng.Next(validTiles.Count)];
|
|
OnOrbSpawned?.Invoke(pick.Id);
|
|
}
|
|
|
|
public void EndGame()
|
|
{
|
|
if (IsGameOver) return;
|
|
|
|
IsGameOver = true;
|
|
|
|
if (Score > HighScore)
|
|
{
|
|
HighScore = Score;
|
|
_persistenceService.Save(HighScoreKey, HighScore);
|
|
}
|
|
|
|
OnGameOver?.Invoke();
|
|
}
|
|
|
|
public void SetPlayerFloor(int floorIndex)
|
|
{
|
|
if (_playerFloorIndex == floorIndex) return;
|
|
|
|
_playerFloorIndex = floorIndex;
|
|
|
|
if (IsGameOver) return;
|
|
|
|
OnOrbReset?.Invoke();
|
|
SpawnNextOrb();
|
|
}
|
|
|
|
private void SpawnRandomPowerUp()
|
|
{
|
|
var validTiles = _tiles.FindAll(t => t.CurrentState == TileState.Stable);
|
|
if (validTiles.Count == 0) return;
|
|
|
|
var tile = validTiles[_rng.Next(validTiles.Count)];
|
|
|
|
var type = _rng.Next(0, 2) == 0 ? PowerUpType.LightFooted : PowerUpType.SpeedBoost;
|
|
|
|
OnSpawnPowerUp?.Invoke(type, tile.Id);
|
|
}
|
|
}
|
|
} |