124 lines
3.5 KiB
C#
124 lines
3.5 KiB
C#
using System;
|
|
using ModestTree;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace Zenject.SpaceFighter
|
|
{
|
|
public class EnemySpawner : ITickable, IInitializable
|
|
{
|
|
readonly EnemyFacade.Factory _enemyFactory;
|
|
readonly SignalBus _signalBus;
|
|
readonly LevelBoundary _levelBoundary;
|
|
readonly Settings _settings;
|
|
|
|
float _desiredNumEnemies;
|
|
int _enemyCount;
|
|
float _lastSpawnTime;
|
|
|
|
public EnemySpawner(
|
|
Settings settings,
|
|
LevelBoundary levelBoundary,
|
|
SignalBus signalBus,
|
|
EnemyFacade.Factory enemyFactory)
|
|
{
|
|
_enemyFactory = enemyFactory;
|
|
_signalBus = signalBus;
|
|
_levelBoundary = levelBoundary;
|
|
_settings = settings;
|
|
|
|
_desiredNumEnemies = settings.NumEnemiesStartAmount;
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
_signalBus.Subscribe<EnemyKilledSignal>(OnEnemyKilled);
|
|
}
|
|
|
|
void OnEnemyKilled()
|
|
{
|
|
_enemyCount--;
|
|
}
|
|
|
|
public void Tick()
|
|
{
|
|
_desiredNumEnemies += _settings.NumEnemiesIncreaseRate * Time.deltaTime;
|
|
|
|
if (_enemyCount < (int)_desiredNumEnemies
|
|
&& Time.realtimeSinceStartup - _lastSpawnTime > _settings.MinDelayBetweenSpawns)
|
|
{
|
|
SpawnEnemy();
|
|
_enemyCount++;
|
|
}
|
|
}
|
|
|
|
void SpawnEnemy()
|
|
{
|
|
float speed = Random.Range(_settings.SpeedMin, _settings.SpeedMax);
|
|
float accuracy = Random.Range(_settings.AccuracyMin, _settings.AccuracyMax);
|
|
|
|
var enemyFacade = _enemyFactory.Create(accuracy, speed);
|
|
enemyFacade.Position = ChooseRandomStartPosition();
|
|
|
|
_lastSpawnTime = Time.realtimeSinceStartup;
|
|
}
|
|
|
|
Vector3 ChooseRandomStartPosition()
|
|
{
|
|
var side = Random.Range(0, 3);
|
|
var posOnSide = Random.Range(0, 1.0f);
|
|
|
|
float buffer = 2.0f;
|
|
|
|
switch (side)
|
|
{
|
|
case 0:
|
|
// top
|
|
{
|
|
return new Vector3(
|
|
_levelBoundary.Left + posOnSide * _levelBoundary.Width,
|
|
_levelBoundary.Top + buffer, 0);
|
|
}
|
|
case 1:
|
|
// right
|
|
{
|
|
return new Vector3(
|
|
_levelBoundary.Right + buffer,
|
|
_levelBoundary.Top - posOnSide * _levelBoundary.Height, 0);
|
|
}
|
|
case 2:
|
|
// bottom
|
|
{
|
|
return new Vector3(
|
|
_levelBoundary.Left + posOnSide * _levelBoundary.Width,
|
|
_levelBoundary.Bottom - buffer, 0);
|
|
}
|
|
case 3:
|
|
// left
|
|
{
|
|
return new Vector3(
|
|
_levelBoundary.Left - buffer,
|
|
_levelBoundary.Top - posOnSide * _levelBoundary.Height, 0);
|
|
}
|
|
}
|
|
|
|
throw Assert.CreateException();
|
|
}
|
|
|
|
[Serializable]
|
|
public class Settings
|
|
{
|
|
public float SpeedMin;
|
|
public float SpeedMax;
|
|
|
|
public float AccuracyMin;
|
|
public float AccuracyMax;
|
|
|
|
public float NumEnemiesIncreaseRate;
|
|
public float NumEnemiesStartAmount;
|
|
|
|
public float MinDelayBetweenSpawns = 0.5f;
|
|
}
|
|
}
|
|
}
|