Update Osztály diagram authored by Horváth István's avatar Horváth István
Az alábbi diagrammok értelmezéséhez az [Architecture](Architecture) dokumentum ismerete szükséges. A fizika (Physics) komponensek nem kerültek felhasználásra: nincsen rájuk szükség.
# `Logic.Data` komponens (modell)
```plantuml
package Logic.Data{
package Logic.Data.World{
interface ITowerTypeData{
+ Name(): String{get}
+ Damage(): float{get}
+ Range(): float{get}
+ CooldownTime(): float{get}
+ BuildingCost(): int{get}
+ UpgradeCost(): int{get}
}
class TilePosition{
+ X(): int{get}
+ Y(): int{get}
}
class GameWorld{
- _grid: TileObject[,]
+ TileObjects(): IReadOnlyCollection<TileObject>{get}
+ Units(): IReadOnlyCollection<Unit>{get}
+ Width(): int{get}
+ Height(): int{get}
+ Grid(int, int): TileObject{get}
+ BuildTower(GameTeam, ITowerTypeData, TilePosition): void
+ DestroyTower(Tower): void
}
class WorldNavigation{
+ IsPositionReachable(from: Vector2, to: Vector2): bool
+ TryGetPathDeltas(Vector2, Vector2, collider: float): IEnumerable<Vector2>
}
GameWorld o-- WorldNavigation
Unit --> WorldNavigation
abstract TileObject{
+ World(): GameWorld{get}
}
abstract Building extends TileObject{
+ Owner(): GameTeam{get}
}
class Obstacle extends TileObject{
}
class Tower extends Building{
+ Upgrade(): void
+ Target(): Unit{get}
+ Level(): int{get}
+ RemainingCooldownTime(): float{get}
+ UpdateTarget(): void
+ UpdateCooldown(float): void
+ Shoot(): void
}
class Barrack extends Building{
- _checkPoints: IList<TilePosition>
+ QueuedUnits(): IReadOnlyCollection<IUnitTypeData>{get}
+ CheckPoints(): IReadOnlyCollection<TilePosition>{get}
+ QueueUnit(IUnitTypeData): void
+ PushCheckpoint(TilePosition): void
+ DeleteCheckpoint(TilePosition): void
+ SpawnCooldownTime(): float{get}
+ RemainingCooldownTime(): float{get}
+ Spawn(): void
}
class Castle extends Building{
+ Health(): float{get}
}
Class Unit{
- _checkpoints: IList<TilePosition>
+ Owner(): GameTeam{get}
+ NextCheckpoint(): TilePosition{get}
+ Move(float): void
+ SkipUnreachableCheckpoints() : void
+ Position(): Vector2{get}
}
Class Vector2{
+ X(): float{get}
+ Y(): float{get}
}
Unit o-- TilePosition
Unit o-- Vector2
interface IUnitTypeData{
+ Name(): String{get}
+ Health(): float{get}
+ Damage(): float{get}
+ Speed(): float{get}
+ Cost(): int{get}
}
Unit "1" o-- IUnitTypeData
GameWorld o-- TileObject
TileObject "1" o-- TilePosition
Tower "1" o-- ITowerTypeData
}
class GameTeam{
+ TeamColor(): Color{get}
+ Barracks(): IReadOnlyCollection<Barrack>
+ Castle(): Castle{get}
+ Money(): int{get}
+ AliveUnitCount(): int{get}
+ PresentTowerCount(): int{get}
+ MoneySpent(): int{get}
+ PurchasedUnitCount(): int{get}
+ BuiltTowerCount(): int{get}
}
class GameOverview{
+ World(): GameWorld{get}
+ GetTeam(Color): GameTeam
+ CurrentPhase(): GamePhase{get}
+ AdvancePhase(): void
+ TimeLeftFromPhase(): float
}
GameOverview o-- GameTeam
GameOverview o-- GameWorld
enum GamePhase{
PREPARE
FIGHT
}
enum Color{
RED
BLUE
}
Color <-- GameTeam
GamePhase <-- GameOverview
Color <-- GameOverview
}
```
# `Presentation.World` komponens (játéktér megjelenés)
Minden osztály, ami `...Data` elnevezéssel rendelkezik, az a `ScriptableObject`-ből, minden más osztály pedig a `MonoBehaviour`-ből származik le.
```plantuml
package Presentation.World {
class GameManager {
+ MainMenuScene: string { constant }
+ SimulationScene: string { constant }
+ ExitGame(): void
+ LoadMenu(): void
+ LoadNewGame(): void
}
class World {
+ Units: IList<Unit>
+ Tile: GameObject
+ Barrack: GameObject
+ Obstacle: GameObject
+ Tower: GameObject
+ Castle: GameObject
+ TilePadding: float
- _map: GameObject[,]
- Start(): void
- Update(float): void
- InstantiateTile(int, int, GameWorld): GameObject
- InstantiateTile(GameObject, Vector3, TileObject): GameObject
}
class Tile {
- TileData: TileData
- _spriteRenderer: SpriteRenderer
+ Position:TilePosition
- Start(): void
}
class UnitData {
+ color: Color
+ aliveSprite: Sprite
+ destroyedSprite: Sprite
+ attackEffect: GameObject
+ destroyedEffect: GameObject
}
class Unit {
- redUnitData: UnitData
- blueUnitData: UnitData
- _data: Logic.Data.World.Unit
- _spriteRenderer: SpriteRenderer
- Start(): void
+ SetData(Logic.Data.World.Unit): void
}
abstract class Structure {
}
class CastleData {
+ Color: Color
+ AmbientEffect: GameObject
+ ExplosionEffect: GameObject
+ IntactSprite: Sprite
+ DestroyedSprite: Sprite
}
class Castle extends Structure {
- blueCastleData: CastleData
- redCastleData: CastleData
- _data: Logic.Data.World.Castle
- _spriteRenderer: SpriteRenderer
- Start(): void
+ SetData(Logic.Data.World.Castle): void
}
class ProjectileData {
+ Color: Color
+ Sprite: Sprite
+ FlyingEffect: GameObject
+ ImpactEffect: GameObject
}
class Projectile {
- blueProjectileData: ProjectileData
- redProjectileData: ProjectileData
- _spriteRenderer: SpriteRenderer
- _teamColor: Logic.Data.Color
- Start(): void
+ SetTeamColor(Logic.Data.Color): void
}
class Tower extends Structure {
- blueTowerData: TowerData
- redTowerData: TowerData
- _data: Logic.Data.World.Tower
- _spriteRenderer: SpriteRenderer
- Start(): void
+ SetData(Logic.Data.World.Tower): void
}
class TowerData {
+ Color: Color
+ TowerSprite: Sprite
+ ShootingEffect: GameObject
+ AmbientEffect: GameObject
}
class Obstacle extends Structure {
- obstacleData: ObstacleData
- _spriteRenderer: SpriteRenderer
- Start(): void
}
class Barrack extends Structure {
- blueBarrackData: BarrackData
- redBarrackData: BarrackData
- _data: Logic.Data.World.Barrack
- _spriteRenderer: SpriteRenderer
- Start(): void
+ SetData(Logic.Data.World.Barrack): void
}
class TileData {
+ Color: Color
+ Sprite: Sprite
+ AmbientEffect: GameObject
}
class BarrackData {
+ Color: Color
+ Sprite: Sprite
+ AmbientEffect: GameObject
}
class ObstacleData {
+ Color: Color
+ Sprite: Sprite
+ AmbientEffect: GameObject
}
class SimulationCamera {
- minZoomLevel: float
- maxZoomLevel: float
- zoomSensitivity: float
- zoomSpeed: float
- panSensitivity: Vector2
- panSpeed: float
- _cam: camera
- _isRightButtondown: bool
- _panTarget: Vector3
- _zoomTarget: float
- Start(): void
- Update(): void
- SetupCallbacks(): void
}
class SimulationManager {
+ WorldWidth: int
+ WorldHeight: int
+ Seed: int
- mainCamera: Camera
+ IsPaused: bool
+ GameOverview: GameOverview
- Awake(): void
- Update(): void
- FixedUpdate(): void
+ SpawnProjectile(Tower): Projectile
+ ResumeGame(): void
+ PauseGame(): void
+ event OnTileSelected: Action<TilePosition>
}
Obstacle o-- ObstacleData
Barrack o-- BarrackData
Unit o-- UnitData
World o-- Tile
Tile o-- TileData
Tile o-- Structure
World o-- Unit
Castle o-- CastleData
Tower o-- TowerData
Tower o-- ProjectileData
Projectile o-- ProjectileData
}
```
# `Presentation.UI` komponens (felhasználói felület)
```plantuml
package Presentation.UI {
class MainMenu {
Start(): void
OnNewGameClicked(): void
OnExitClicked(): void
}
class SimulationUI {
- _gameState: GameState
- _activePlayer: ActivePlayer
Start(): void
OnStateUpdated(): void
OnDestroy(): void
}
class TowerPlacingUI {
- _activePlayer: ActivePlayer
Start(): void
Show(): void
Hide(): void
SetActivePlayer(ActivePlayer): void
OnUpdate(): void
OnTowerButtonClicked(Tower): void
ShowTowerStats(Tower): void
ShowTowerManagement(Tower): void
OnDestroy(): void
event OnTowerUpgraded(Tower)
event OnTowerSelected(Tower)
event OnNextClicked()
}
class UnitPurchasingUI {
- _activePlayer: ActivePlayer
Start(): void
Show(): void
Hide(): void
SetActivePlayer(ActivePlayer): void
OnUpdate(): void
OnUnitButtonClicked(Unit): void
OnDestroy(): void
event OnUnitPurchased(Unit)
event OnNextClicked()
}
class BattleUI {
Start(): void
Show(): void
Hide(): void
OnUpdate(): void
OnDestroy(): void
event OnExitClicked()
event OnPauseClicked()
}
class GameOverOverlay {
Start(): void
Show(): void
Hide(): void
OnDestroy(): void
event OnOkClicked()
}
class PauseOverlay {
Start(): void
Show(): void
Hide(): void
OnDestroy(): void
event OnExitClicked()
event OnNewGameClicked()
event OnResumeClicked()
}
SimulationUI *-- UnitPurchasingUI
SimulationUI *-- TowerPlacingUI
SimulationUI *-- BattleUI
SimulationUI *-- GameOverOverlay
SimulationUI *-- PauseOverlay
}
```
# `Logic.Handlers` komponens (parancskezelés)
Mindegyik `...Handler` a `BaseHandler` alosztálya és implementálja a `RegisterConsumers(CommandDispatcher)` metódust. Az `Handle(...)` metódusok visszatérési értéke a paramétertől függ. Ezek nincsenek jelölve a diagrammon a jobb átláthatóság érdekében.
```plantuml
package Logic.Data.* {
class Unit
class Tower
class Barrack
class GameWorld
class GameOverview
}
abstract BaseHandler {
+ {abstract} RegisterConsumers(CommandDispatcher) : void
}
class AdvanceTimeHandler {
- Handle(AdvanceTimeCommand)
}
AdvanceTimeHandler ---> GameOverview
AdvanceTimeHandler ---> Tower
AdvanceTimeHandler ---> Unit
AdvanceTimeHandler ---> Barrack
class AdvancePhaseHandler {
- Handle(AdvancePhaseCommand)
}
AdvancePhaseHandler ---> GameOverview
class ManageTowerHandler {
- Handle(BuildTowerCommand)
- Handle(UpgradeTowerCommand)
- Handle(DestroyTowerCommand)
}
ManageTowerHandler ---> Tower
ManageTowerHandler ---> GameWorld
class ManageUnitHandler {
- Handle(PurchaseUnitCommand)
}
ManageUnitHandler ---> Unit
ManageUnitHandler ---> Barrack
class ManageBarrackHandler {
- Handle(AddBarrackCheckpointCommand)
- Handle(RemoveBarrackCheckpointCommand)
}
ManageBarrackHandler ---> Barrack
```
# `Logic.Systems` komponens (modellekhez extra logika)
Mindegyik `...System` a `BaseSystem` alosztálya és implementálja a `RegisterListeners(EventDispatcher)` metódust. Az `On(...)` metódusok visszatérési értéke `void`. Ezek nincsenek jelölve a diagrammon a jobb átláthatóság érdekében.
```plantuml
package Logic.Data.* {
class Unit
class Tower
class Castle
class GameWorld
}
abstract BaseSystem {
+ {abstract} RegisterListeners(EventDispatcher) : void
}
class UnitDamagesCastleSystem {
- On(UnitMovedTileEvent)
}
UnitDamagesCastleSystem ---> Unit
UnitDamagesCastleSystem ---> Castle
class TowerDamagesUnitSystem {
- On(TowerShootEvent)
}
TowerDamagesUnitSystem ---> Tower
TowerDamagesUnitSystem ---> Unit
class DestroyUnitSystem {
- On(UnitDamagedEvent)
}
DestroyUnitSystem ---> Unit
DestroyUnitSystem ---> GameWorld
class UpdateUnitPathSystem {
- On(PhaseAdvancedEvent)
}
UpdateUnitPathSystem ---> Unit
```
# Diszpécser rendszerek (`CommandDispatcher`, `EventDispatcher`)
```plantuml
package Logic.Event {
class EventDispatcher {
{field} + <<delegate>> Listener<T : BaseEvent>(T) : void
- _listeners : IDictionary<Type, IList<Delegate>>
+ AddListener<T : BaseEvent>(Listener<T>) : void
+ RemoveListener<T : BaseEvent>(Listener<T>) : void
+ Raise(BaseEvent) : void
}
abstract BaseEvent
EventDispatcher --> BaseEvent
}
package Logic.Command {
class CommandDispatcher {
{field} + <<delegate>> Consumer<TC : BaseCommand<TR>, TR : ICommandResult>(T) : TR
- _consumers : IDictionary<Type, Delegate>
+ RegisterConsumer<TC, TR>(BaseCommand<TC, TR>) : void
+ RemoveConsumer<TC, TR>(BaseCommand<TC, TR>) : void
+ Issue<T : ICommandResult>(BaseCommand<T>) : T
}
abstract BaseCommand<T : ICommandResult>
abstract "BaseCommand<BiCommandResult>"
interface ICommandResult {
+ IsSuccess() : bool
}
class BiCommandResult <<sealed>> implements ICommandResult{
+ Success : BiCommandResult
+ Failure : BiCommandResult
}
CommandDispatcher -d-> BaseCommand
CommandDispatcher -d-> ICommandResult
BaseCommand --> ICommandResult
abstract "BaseCommand<BiCommandResult>" extends BaseCommand{
}
"BaseCommand<BiCommandResult>" --> BiCommandResult
}
```
# `Event`-ek (események)
Mindegyik `...Event`, ami nem interfész, az a `BaseEvent` alosztálya. Ez nincs jelölve a diagrammon a jobb átláthatóság érdekében.
```plantuml
package Logic.Event {
class PhaseAdvancedEvent {
+ Game : GameOverview {get}
+ OldPhase : GamePhase {get}
}
}
```
```plantuml
package Logic.Event.World.Tower {
interface ITowerEvent {
Tower() : Tower {get}
}
class TowerBuiltEvent implements ITowerEvent
class TowerUpgradedEvent implements ITowerEvent {
+ BeforeUpgradeType : ITowerTypeData {get}
}
class TowerDestroyedEvent implements ITowerEvent
class TowerShotEvent implements ITowerEvent {
+ Target : Unit {get}
}
class TowerTargetChangedEvent implements ITowerEvent {
+ OldTarget : Unit {get}
}
class TowerCooledDownEvent implements ITowerEvent
}
```
```plantuml
package Logic.Event.World.Unit {
interface IUnitTypeEvent {
+ Type() : UnitTypeData {get}
}
interface IUnitEvent extends IUnitTypeEvent {
+ Unit() : Unit {get}
}
class UnitQueuedEvent implements IUnitTypeEvent {
+ Barrack() : Barrack {get}
}
class UnitDeployedEvent implements IUnitEvent {
+ Barrack() : Barrack {get}
}
class UnitMovedTileEvent implements IUnitEvent {
+ OldPosition() : TilePosition {get}
}
class UnitDamagedEvent implements IUnitEvent {
+ Damage() : float {get}
+ Attacker() : Tower {get}
}
class UnitDestroyedEvent implements IUnitEvent
}
```
```plantuml
package Logic.Event.World.Castle {
interface ICastleEvent {
+ Castle(): Castle {get}
}
class CastleDamagedEvent implements ICastleEvent {
+ Damage() : float {get}
+ Attacker() : Unit {get}
}
class CastleDestroyedEvent implements ICastleEvent
}
```
# `Command`-ok (parancsok)
Mindegyik `...Command` a `BaseCommand` alosztálya. Ez nincs jelölve a diagrammon a jobb átláthatóság érdekében.
```plantuml
package Logic.Command {
class AdvanceTimeCommand {
+ Game : GameOverview {get}
+ DeltaTime() : float {get}
}
class AdvancePhaseCommand {
+ Game : GameOverview {get}
}
}
```
```plantuml
package Logic.Command.World.Tower {
class BuildTowerCommand {
+ Team() : GameTeam {get}
+ Type() : ITowerTypeData {get}
+ Position() : TilePosition {get}
}
class UpgradeTowerCommand {
+ Tower() : Tower {get}
}
class DestroyTowerCommand {
+ Tower() : Tower {get}
}
}
```
```plantuml
package Logic.Command.World.Unit {
class PurchaseUnitCommand {
+ Team() : GameTeam {get}
+ Type() : IUnitTypeData {get}
}
}
```
```plantuml
package Logic.Command.World.Barrack {
class AddBarrackCheckpointCommand {
+ Barrack() : Barrack {get}
+ Position() : TilePosition {get}
}
class RemoveBarrackCheckpointCommand {
+ Barrack() : Barrack {get}
+ Position() : TilePosition {get}
}
}
```