Initial Commit
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlappyBird.Core;
|
||||
using UnityEngine;
|
||||
using Zenject;
|
||||
|
||||
namespace FlappyBird.Pipes
|
||||
{
|
||||
public class PipeSpawner : IInitializable, ITickable, IDisposable
|
||||
{
|
||||
private readonly IObjectPoolManager _objectPoolManager;
|
||||
private readonly IGameManager _gameManager;
|
||||
private readonly PipeSettings _settings;
|
||||
private readonly GameObject _pipePrefab;
|
||||
|
||||
private readonly List<PipeView> _activePipes = new List<PipeView>();
|
||||
|
||||
private bool _isRunning;
|
||||
private float _spawnTimer;
|
||||
|
||||
[Inject]
|
||||
public PipeSpawner(
|
||||
IObjectPoolManager objectPoolManager,
|
||||
IGameManager gameManager,
|
||||
PipeSettings settings,
|
||||
[Inject(Id = "PipePrefab")] GameObject pipePrefab)
|
||||
{
|
||||
_objectPoolManager = objectPoolManager;
|
||||
_gameManager = gameManager;
|
||||
_settings = settings;
|
||||
_pipePrefab = pipePrefab;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the spawner by registering the Pipe pool, subscribing to game state changes,
|
||||
/// and setting the initial spawn timer based on settings.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
// Register the pool with the new generic ObjectPoolManager
|
||||
_objectPoolManager.RegisterPool<PipeView>(_pipePrefab, _settings.initialPoolSize);
|
||||
|
||||
_gameManager.OnGameStateChanged += HandleGameStateChanged;
|
||||
ApplyState(_gameManager.CurrentState);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_gameManager.OnGameStateChanged -= HandleGameStateChanged;
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
if (!_isRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MoveActivePipes();
|
||||
UpdateSpawnTimer();
|
||||
}
|
||||
|
||||
private void HandleGameStateChanged(GameState state)
|
||||
{
|
||||
ApplyState(state);
|
||||
}
|
||||
|
||||
private void ApplyState(GameState state)
|
||||
{
|
||||
if (state == GameState.Playing)
|
||||
{
|
||||
_isRunning = true;
|
||||
_spawnTimer = _settings.spawnImmediately ? 0f : _settings.spawnInterval;
|
||||
return;
|
||||
}
|
||||
|
||||
_isRunning = false;
|
||||
|
||||
if (state == GameState.Menu)
|
||||
{
|
||||
DespawnAllActivePipes();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSpawnTimer()
|
||||
{
|
||||
_spawnTimer -= Time.deltaTime;
|
||||
if (_spawnTimer > 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnPipe();
|
||||
_spawnTimer += Mathf.Max(0.01f, _settings.spawnInterval);
|
||||
}
|
||||
|
||||
private void SpawnPipe()
|
||||
{
|
||||
PipeView pipeView = _objectPoolManager.Get<PipeView>();
|
||||
|
||||
// Randomize the vertical position of the gap
|
||||
float gapCenterY = UnityEngine.Random.Range(_settings.minGapCenterY, _settings.maxGapCenterY);
|
||||
|
||||
pipeView.ConfigureGap(gapCenterY, _settings.gapSize, _settings.scoreTriggerWidth);
|
||||
pipeView.SetWorldPosition(new Vector3(_settings.spawnX, 0f, 0f));
|
||||
|
||||
_activePipes.Add(pipeView);
|
||||
}
|
||||
|
||||
private void MoveActivePipes()
|
||||
{
|
||||
float step = _settings.moveSpeed * Time.deltaTime;
|
||||
|
||||
for (int i = _activePipes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
PipeView pipeView = _activePipes[i];
|
||||
pipeView.MoveLeft(step);
|
||||
|
||||
// Despawn if the pipe has moved past the despawn threshold
|
||||
if (pipeView.XPosition > _settings.despawnX)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_activePipes.RemoveAt(i);
|
||||
_objectPoolManager.Return(pipeView);
|
||||
}
|
||||
}
|
||||
|
||||
private void DespawnAllActivePipes()
|
||||
{
|
||||
for (int i = _activePipes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
_objectPoolManager.Return(_activePipes[i]);
|
||||
}
|
||||
|
||||
_activePipes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user