/
GameEngine.swift
130 lines (103 loc) · 3.71 KB
/
GameEngine.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// GameEngine.swift
// star-dash
//
// Created by Ho Jun Hao on 14/3/24.
//
import Foundation
class GameEngine {
private let systemManager: SystemManager
let entityManager: EntityManager // TODO: Set to private
private let eventManager: EventManager
init() {
self.systemManager = SystemManager()
self.entityManager = EntityManager()
self.eventManager = EventManager()
setUpSystems()
}
func gameInfo() -> GameInfo? {
guard let scoreSystem = systemManager.system(ofType: ScoreSystem.self),
let playerEntityId = entityManager.playerEntityId(),
let score = scoreSystem.score(of: playerEntityId) else {
return nil
}
return GameInfo(
playerScore: score
)
}
func update(by deltaTime: TimeInterval) {
systemManager.update(by: deltaTime)
eventManager.executeAll(on: self)
}
func handleCollision(_ entityOneId: EntityId, _ entityTwoId: EntityId, at contactPoint: CGPoint) {
guard let entityOne = entity(of: entityOneId) as? Collidable,
let entityTwo = entity(of: entityTwoId) as? Collidable,
let event = entityOne.collides(with: entityTwo, at: contactPoint) else {
return
}
eventManager.add(event: event)
}
func handlePlayerJump() {
guard let playerEntityId = entityManager.playerEntityId() else {
return
}
eventManager.add(event: JumpEvent(on: playerEntityId, by: PhysicsConstants.jumpImpulse))
}
func handlePlayerMove(toLeft: Bool) {
guard let playerEntityId = entityManager.playerEntityId(),
let playerComponent = entityManager.component(ofType: PlayerComponent.self, of: playerEntityId),
playerComponent.canMove else {
return
}
eventManager.add(event: MoveEvent(on: playerEntityId, toLeft: toLeft))
}
func handlePlayerStoppedMoving() {
guard let playerEntityId = entityManager.playerEntityId() else {
return
}
eventManager.add(event: StopMovingEvent(on: playerEntityId))
}
func playerPosition() -> CGPoint? {
guard let playerEntityId = entityManager.playerEntityId(),
let positionComponent = entityManager.component(ofType: PositionComponent.self, of: playerEntityId) else {
return nil
}
return positionComponent.position
}
private func setUpSystems() {
systemManager.add(PositionSystem(entityManager, dispatcher: self))
systemManager.add(PhysicsSystem(entityManager, dispatcher: self))
systemManager.add(ScoreSystem(entityManager, dispatcher: self))
}
}
extension GameEngine: EventModifiable {
func entity(with entityId: EntityId) -> Entity? {
entityManager.entity(with: entityId)
}
func system<T: System>(ofType type: T.Type) -> T? {
systemManager.system(ofType: type)
}
func component<T: Component>(ofType type: T.Type, ofEntity entityId: EntityId) -> T? {
entityManager.component(ofType: type, of: entityId)
}
func add(entity: Entity) {
entityManager.add(entity: entity)
}
func add(event: Event) {
eventManager.add(event: event)
}
func remove(entity: Entity) {
entityManager.remove(entity: entity)
}
}
extension GameEngine: EntitySyncInterface {
var entities: [Entity] {
Array(entityManager.entityMap.values)
}
func component<T: Component>(ofType type: T.Type, of entityId: EntityId) -> T? {
entityManager.component(ofType: type, of: entityId)
}
func entity(of entityId: EntityId) -> Entity? {
entityManager.entityMap[entityId]
}
}