diff --git a/TowerForge/TowerForge.xcodeproj/project.pbxproj b/TowerForge/TowerForge.xcodeproj/project.pbxproj index 66ae1286..87ccf2ad 100644 --- a/TowerForge/TowerForge.xcodeproj/project.pbxproj +++ b/TowerForge/TowerForge.xcodeproj/project.pbxproj @@ -14,7 +14,7 @@ 3C9955A52BA47DC600D33FA5 /* BaseProjectile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955A42BA47DC600D33FA5 /* BaseProjectile.swift */; }; 3C9955AD2BA483B100D33FA5 /* TFSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955AC2BA483B100D33FA5 /* TFSystem.swift */; }; 3C9955AF2BA48FD200D33FA5 /* MeleeUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955AE2BA48FD200D33FA5 /* MeleeUnit.swift */; }; - 3C9955B12BA4ACA100D33FA5 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955B02BA4ACA100D33FA5 /* Arrow.swift */; }; + 3C9955B12BA4ACA100D33FA5 /* Bullet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955B02BA4ACA100D33FA5 /* Bullet.swift */; }; 3C9955B42BA4B12000D33FA5 /* ArrowTower.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955B32BA4B12000D33FA5 /* ArrowTower.swift */; }; 3C9955BA2BA5637200D33FA5 /* DamageEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955B92BA5637200D33FA5 /* DamageEvent.swift */; }; 3C9955BC2BA563A800D33FA5 /* TFEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9955BB2BA563A800D33FA5 /* TFEvent.swift */; }; @@ -36,6 +36,7 @@ 3CE951582BAD724D008B2785 /* TFContact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE951572BAD724D008B2785 /* TFContact.swift */; }; 3CE9515F2BADE2C5008B2785 /* ShootingSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE9515E2BADE2C5008B2785 /* ShootingSystem.swift */; }; 3CE951612BADE881008B2785 /* Spawnable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE951602BADE881008B2785 /* Spawnable.swift */; }; + 3CE951632BAE037C008B2785 /* AiSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE951622BAE037C008B2785 /* AiSystem.swift */; }; 5200624E2BA8D597000DBA30 /* AiComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5200624D2BA8D597000DBA30 /* AiComponent.swift */; }; 520062522BA8DA09000DBA30 /* UnitGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520062512BA8DA09000DBA30 /* UnitGenerator.swift */; }; 520062562BA8E026000DBA30 /* PlayerSpawnable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520062552BA8E026000DBA30 /* PlayerSpawnable.swift */; }; @@ -106,7 +107,7 @@ 3C9955A42BA47DC600D33FA5 /* BaseProjectile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseProjectile.swift; sourceTree = ""; }; 3C9955AC2BA483B100D33FA5 /* TFSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFSystem.swift; sourceTree = ""; }; 3C9955AE2BA48FD200D33FA5 /* MeleeUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeleeUnit.swift; sourceTree = ""; }; - 3C9955B02BA4ACA100D33FA5 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = ""; }; + 3C9955B02BA4ACA100D33FA5 /* Bullet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bullet.swift; sourceTree = ""; }; 3C9955B32BA4B12000D33FA5 /* ArrowTower.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowTower.swift; sourceTree = ""; }; 3C9955B92BA5637200D33FA5 /* DamageEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamageEvent.swift; sourceTree = ""; }; 3C9955BB2BA563A800D33FA5 /* TFEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFEvent.swift; sourceTree = ""; }; @@ -128,6 +129,7 @@ 3CE951572BAD724D008B2785 /* TFContact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFContact.swift; sourceTree = ""; }; 3CE9515E2BADE2C5008B2785 /* ShootingSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShootingSystem.swift; sourceTree = ""; }; 3CE951602BADE881008B2785 /* Spawnable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Spawnable.swift; sourceTree = ""; }; + 3CE951622BAE037C008B2785 /* AiSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AiSystem.swift; sourceTree = ""; }; 5200624D2BA8D597000DBA30 /* AiComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AiComponent.swift; sourceTree = ""; }; 520062512BA8DA09000DBA30 /* UnitGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitGenerator.swift; sourceTree = ""; }; 520062552BA8E026000DBA30 /* PlayerSpawnable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerSpawnable.swift; sourceTree = ""; }; @@ -207,7 +209,7 @@ children = ( 3CE9514C2BAC8668008B2785 /* Base Entities */, 3C9955AE2BA48FD200D33FA5 /* MeleeUnit.swift */, - 3C9955B02BA4ACA100D33FA5 /* Arrow.swift */, + 3C9955B02BA4ACA100D33FA5 /* Bullet.swift */, 3C9955B32BA4B12000D33FA5 /* ArrowTower.swift */, 52578B8B2BA627B200B4D76C /* Team.swift */, 529F91872BA6D7A7009551D9 /* SoldierUnit.swift */, @@ -237,6 +239,7 @@ 3C769A732BA591BD00F454F9 /* SpawnSystem.swift */, BA443D3C2BAD9557009F0FFB /* RemoveSystem.swift */, 3CE9515E2BADE2C5008B2785 /* ShootingSystem.swift */, + 3CE951622BAE037C008B2785 /* AiSystem.swift */, ); path = Systems; sourceTree = ""; @@ -648,6 +651,7 @@ 52578B822BA61AAF00B4D76C /* PositionComponent.swift in Sources */, 3C9955A32BA47DBB00D33FA5 /* BaseUnit.swift in Sources */, 3C9955BA2BA5637200D33FA5 /* DamageEvent.swift in Sources */, + 3CE951632BAE037C008B2785 /* AiSystem.swift in Sources */, 3CE9515F2BADE2C5008B2785 /* ShootingSystem.swift in Sources */, 3C9955CA2BA5888F00D33FA5 /* SpawnEvent.swift in Sources */, 3CE951582BAD724D008B2785 /* TFContact.swift in Sources */, @@ -679,7 +683,7 @@ 520062582BA8ED73000DBA30 /* HomeComponent.swift in Sources */, 52DF5FA82BA32B2300135367 /* AppDelegate.swift in Sources */, 3C769A742BA591BD00F454F9 /* SpawnSystem.swift in Sources */, - 3C9955B12BA4ACA100D33FA5 /* Arrow.swift in Sources */, + 3C9955B12BA4ACA100D33FA5 /* Bullet.swift in Sources */, 3CE9514F2BAC8936008B2785 /* Renderer.swift in Sources */, 3C769A722BA58DE700F454F9 /* MovementSystem.swift in Sources */, 52DF5FEB2BA3400C00135367 /* TFAnimatableNode.swift in Sources */, diff --git a/TowerForge/TowerForge/GameWorld.swift b/TowerForge/TowerForge/GameWorld.swift index 9c6357d6..23e99e74 100644 --- a/TowerForge/TowerForge/GameWorld.swift +++ b/TowerForge/TowerForge/GameWorld.swift @@ -97,6 +97,7 @@ class GameWorld { systemManager.add(system: RemoveSystem(entityManager: entityManager, eventManager: eventManager)) systemManager.add(system: SpawnSystem(entityManager: entityManager, eventManager: eventManager)) systemManager.add(system: ShootingSystem(entityManager: entityManager, eventManager: eventManager)) + systemManager.add(system: AiSystem(entityManager: entityManager, eventManager: eventManager)) } private func setUpSelectionNode() { diff --git a/TowerForge/TowerForge/LevelManager/Components/GameComponents/ShootingComponent.swift b/TowerForge/TowerForge/LevelManager/Components/GameComponents/ShootingComponent.swift index e707d098..ab6beb3f 100644 --- a/TowerForge/TowerForge/LevelManager/Components/GameComponents/ShootingComponent.swift +++ b/TowerForge/TowerForge/LevelManager/Components/GameComponents/ShootingComponent.swift @@ -38,11 +38,11 @@ class ShootingComponent: TFComponent { guard let positionA = entityA.component(ofType: PositionComponent.self)?.position, let positionB = entityB.component(ofType: PositionComponent.self)?.position, - abs(positionA.x - positionB.x) <= range else { + abs(positionA.x - positionB.x) <= range, abs(positionA.y - positionB.y) <= 50 else { return nil } lastShotTime = CACurrentMediaTime() - return SpawnEvent(ofType: Arrow.self, timestamp: lastShotTime, position: positionA, player: playerA) + return SpawnEvent(ofType: Bullet.self, timestamp: lastShotTime, position: positionA, player: playerA) } } diff --git a/TowerForge/TowerForge/LevelManager/Entities/Arrow.swift b/TowerForge/TowerForge/LevelManager/Entities/Bullet.swift similarity index 71% rename from TowerForge/TowerForge/LevelManager/Entities/Arrow.swift rename to TowerForge/TowerForge/LevelManager/Entities/Bullet.swift index 61ea2883..bf400ed7 100644 --- a/TowerForge/TowerForge/LevelManager/Entities/Arrow.swift +++ b/TowerForge/TowerForge/LevelManager/Entities/Bullet.swift @@ -1,5 +1,5 @@ // -// Arrow.swift +// Bullet.swift // TowerForge // // Created by Zheng Ze on 16/3/24. @@ -8,23 +8,23 @@ import Foundation import SpriteKit -class Arrow: BaseProjectile, Spawnable { - static let textureNames: [String] = [] +class Bullet: BaseProjectile, Spawnable { + static let textureNames: [String] = ["bullet"] static let size = CGSize(width: 10, height: 10) - static let key = "arrow" + static let key = "bullet" static let damage = 5.0 static let attackRate = 1.0 static let velocity = CGVector(dx: 100, dy: 0) required init(position: CGPoint, player: Player) { - super.init(textureNames: Arrow.textureNames, - size: Arrow.size, - key: Arrow.key, + super.init(textureNames: Bullet.textureNames, + size: Bullet.size, + key: Bullet.key, position: position, player: player, - velocity: Arrow.velocity) - self.addComponent(DamageComponent(attackRate: Arrow.attackRate, - attackPower: Arrow.damage, + velocity: Bullet.velocity) + self.addComponent(DamageComponent(attackRate: Bullet.attackRate, + attackPower: Bullet.damage, temporary: true)) } diff --git a/TowerForge/TowerForge/LevelManager/Systems/AiSystem.swift b/TowerForge/TowerForge/LevelManager/Systems/AiSystem.swift new file mode 100644 index 00000000..ef76f05b --- /dev/null +++ b/TowerForge/TowerForge/LevelManager/Systems/AiSystem.swift @@ -0,0 +1,35 @@ +// +// AiSystem.swift +// TowerForge +// +// Created by Zheng Ze on 23/3/24. +// + +import Foundation + +class AiSystem: TFSystem { + var isActive = true + weak var entityManager: EntityManager? + weak var eventManager: EventManager? + + init(entityManager: EntityManager, eventManager: EventManager) { + self.entityManager = entityManager + self.eventManager = eventManager + } + + func update(within time: CGFloat) { + guard let entityManager = entityManager, let eventManager = eventManager else { + return + } + + let homeComponents = entityManager.components(ofType: HomeComponent.self) + for homeComponent in homeComponents { + homeComponent.update(deltaTime: time) + } + + let aiComponents = entityManager.components(ofType: AiComponent.self) + for aiComponent in aiComponents { + aiComponent.update(deltaTime: time) + } + } +}