diff --git a/TowerForge/TowerForge.xcodeproj/project.pbxproj b/TowerForge/TowerForge.xcodeproj/project.pbxproj index f55f27f2..fd04f4bb 100644 --- a/TowerForge/TowerForge.xcodeproj/project.pbxproj +++ b/TowerForge/TowerForge.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 52DF5FF92BA35D2B00135367 /* MovableComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DF5FF82BA35D2B00135367 /* MovableComponent.swift */; }; 52DF5FFB2BA3601400135367 /* HealthComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DF5FFA2BA3601400135367 /* HealthComponent.swift */; }; 52DF5FFF2BA3656500135367 /* ShootingComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DF5FFE2BA3656500135367 /* ShootingComponent.swift */; }; + 9B8696552BAD759F0002377C /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B8696542BAD759F0002377C /* Grid.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -158,6 +159,7 @@ 52DF5FF82BA35D2B00135367 /* MovableComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovableComponent.swift; sourceTree = ""; }; 52DF5FFA2BA3601400135367 /* HealthComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthComponent.swift; sourceTree = ""; }; 52DF5FFE2BA3656500135367 /* ShootingComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShootingComponent.swift; sourceTree = ""; }; + 9B8696542BAD759F0002377C /* Grid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Grid.swift; sourceTree = ""; }; BABB7C052BA9A41000D54DAE /* TowerForceTestPlan.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = TowerForceTestPlan.xctestplan; sourceTree = ""; }; /* End PBXFileReference section */ @@ -356,6 +358,7 @@ 52DF5FB12BA32B2300135367 /* Main.storyboard */, 52DF5FB42BA32B2600135367 /* Assets.xcassets */, 52DF5FB62BA32B2600135367 /* LaunchScreen.storyboard */, + 9B8696542BAD759F0002377C /* Grid.swift */, ); path = TowerForge; sourceTree = ""; @@ -610,6 +613,7 @@ 5295A2132BAAEA16005018A8 /* UnitNode.swift in Sources */, 52DF5FF32BA351E100135367 /* SpriteComponent.swift in Sources */, 3CE9514B2BAC83FA008B2785 /* SpawnableEntities.swift in Sources */, + 9B8696552BAD759F0002377C /* Grid.swift in Sources */, 52578B872BA6209700B4D76C /* DamageComponent.swift in Sources */, 52DF5FB02BA32B2300135367 /* GameViewController.swift in Sources */, 3CE951512BAC8955008B2785 /* Renderable.swift in Sources */, diff --git a/TowerForge/TowerForge/GameWorld.swift b/TowerForge/TowerForge/GameWorld.swift index aa054cfc..cc13c9d1 100644 --- a/TowerForge/TowerForge/GameWorld.swift +++ b/TowerForge/TowerForge/GameWorld.swift @@ -13,6 +13,7 @@ class GameWorld { private var systemManager: SystemManager private var eventManager: EventManager private var selectionNode: UnitSelectionNode + private var grid: Grid private var renderer: Renderer? init(scene: GameScene?) { @@ -21,6 +22,7 @@ class GameWorld { systemManager = SystemManager() eventManager = EventManager() selectionNode = UnitSelectionNode() + grid = Grid(entityManager: entityManager) renderer = Renderer(target: self, scene: scene) self.setUpSelectionNode() @@ -54,7 +56,7 @@ class GameWorld { } private func setUpSelectionNode() { - selectionNode.delegate = self + selectionNode.delegate = grid scene?.addChild(selectionNode) // Position unit selection node on the left side of the screen selectionNode.position = CGPoint(x: selectionNode.frame.width / 2, y: scene?.frame.midY ?? 300) @@ -77,14 +79,6 @@ extension GameWorld: EventTarget { } } -extension GameWorld: UnitSelectionNodeDelegate { - func unitSelectionNodeDidSpawn(ofType type: T.Type, position: CGPoint) { - let unit = UnitGenerator.spawn(ofType: type, at: position, player: Player.ownPlayer, - entityManager: entityManager) - entityManager.add(unit) - } -} - extension GameWorld: Renderable { func entitiesToRender() -> [TFEntity] { entityManager.entities diff --git a/TowerForge/TowerForge/Grid.swift b/TowerForge/TowerForge/Grid.swift new file mode 100644 index 00000000..8a41d484 --- /dev/null +++ b/TowerForge/TowerForge/Grid.swift @@ -0,0 +1,43 @@ +// +// Grid.swift +// TowerForge +// +// Created by Keith Gan on 22/3/24. +// + +import SpriteKit + +class Grid: UnitSelectionNodeDelegate { + let DEFAULT_NO_OF_ROWS = 8 + + private var entityManager: EntityManager + private var noOfRows: Int + + init(entityManager: EntityManager) { + self.entityManager = entityManager + self.noOfRows = DEFAULT_NO_OF_ROWS + } + + func unitSelectionNodeDidSpawn(ofType type: T.Type, position: CGPoint) { + let snapPosition = CGPoint(x: position.x, y: snapYPosition(yPosition: position.y)) + let unit = UnitGenerator.spawn(ofType: type, at: snapPosition, player: Player.ownPlayer, entityManager: entityManager) + entityManager.add(unit) + } + + private func snapYPosition(yPosition: Double) -> Double { + let normalizedYPosition = normalizeYPosition(yPosition: yPosition) + let screenHeight = Double(UIScreen.main.bounds.height) + let rowHeight = screenHeight / Double(noOfRows) + let rowIndex = Int(normalizedYPosition / rowHeight) + let centerY = Double(rowIndex) * rowHeight + rowHeight / 2 + return denormalizeYPosition(yPosition: centerY) + } + + private func normalizeYPosition(yPosition: Double) -> Double { + yPosition + UIScreen.main.bounds.height / 2 + } + + private func denormalizeYPosition(yPosition: Double) -> Double { + yPosition - UIScreen.main.bounds.height / 2 + } +}