diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift index 77903c85..68a4ebcc 100644 --- a/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift @@ -38,6 +38,11 @@ extension GameScene: SDScene { objectMap[object.node] = object addChild(object.node) } + + public func removeObject(_ object: SDObject) { + objectMap[object.node] = nil + object.removeFromParent() + } } extension GameScene: SKPhysicsContactDelegate { diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDObject.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDObject.swift index 3549ee9a..f66db885 100644 --- a/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDObject.swift +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDObject.swift @@ -39,4 +39,8 @@ public class SDObject { public var physicsBody: SDPhysicsBody? { willSet { node.physicsBody = newValue?.body } } + + func removeFromParent() { + node.removeFromParent() + } } diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift index 79f0fe83..c35a3142 100644 --- a/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift @@ -5,4 +5,5 @@ public protocol SDScene { var size: CGSize { get } func addObject(_ object: SDObject) + func removeObject(_ object: SDObject) } diff --git a/star-dash/star-dash.xcodeproj/project.pbxproj b/star-dash/star-dash.xcodeproj/project.pbxproj index 6090ff75..d4e1f390 100644 --- a/star-dash/star-dash.xcodeproj/project.pbxproj +++ b/star-dash/star-dash.xcodeproj/project.pbxproj @@ -83,6 +83,10 @@ E64361132BA4C2CD003850FD /* PhysicsModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E643610D2BA4C2CC003850FD /* PhysicsModule.swift */; }; E64361142BA4C2CD003850FD /* CreationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E643610E2BA4C2CC003850FD /* CreationModule.swift */; }; E64361152BA4C2CD003850FD /* GameBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = E643610F2BA4C2CC003850FD /* GameBridge.swift */; }; + E69EE9322BAC6CBB00033AB5 /* GameInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69EE9312BAC6CBB00033AB5 /* GameInfo.swift */; }; + E69EE9342BAC6CC300033AB5 /* OverlayInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69EE9332BAC6CC300033AB5 /* OverlayInfo.swift */; }; + E69FDDE02BAD3DAD0089D5F3 /* PointsComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69FDDDF2BAD3DAD0089D5F3 /* PointsComponent.swift */; }; + E69FDDE22BAD3DC40089D5F3 /* EntityConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69FDDE12BAD3DC40089D5F3 /* EntityConstants.swift */; }; E6A011172BA5F4AD006904D9 /* EntitySyncInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6A011162BA5F4AD006904D9 /* EntitySyncInterface.swift */; }; E6A745162BA057040080C1BE /* MTKRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6A745112BA057040080C1BE /* MTKRenderer.swift */; }; E6A745172BA057040080C1BE /* ControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6A745122BA057040080C1BE /* ControlView.swift */; }; @@ -208,6 +212,10 @@ E643610D2BA4C2CC003850FD /* PhysicsModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhysicsModule.swift; sourceTree = ""; }; E643610E2BA4C2CC003850FD /* CreationModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreationModule.swift; sourceTree = ""; }; E643610F2BA4C2CC003850FD /* GameBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameBridge.swift; sourceTree = ""; }; + E69EE9312BAC6CBB00033AB5 /* GameInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameInfo.swift; sourceTree = ""; }; + E69EE9332BAC6CC300033AB5 /* OverlayInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverlayInfo.swift; sourceTree = ""; }; + E69FDDDF2BAD3DAD0089D5F3 /* PointsComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PointsComponent.swift; sourceTree = ""; }; + E69FDDE12BAD3DC40089D5F3 /* EntityConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntityConstants.swift; sourceTree = ""; }; E6A011162BA5F4AD006904D9 /* EntitySyncInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntitySyncInterface.swift; sourceTree = ""; }; E6A745112BA057040080C1BE /* MTKRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTKRenderer.swift; sourceTree = ""; }; E6A745122BA057040080C1BE /* ControlView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlView.swift; sourceTree = ""; }; @@ -342,6 +350,7 @@ 4E630F282B9F7EC20008F887 /* Components */, 4E630F252B9F7E500008F887 /* Entities */, 46B8C0992BA328D900498705 /* GameEngine.swift */, + E69EE9312BAC6CBB00033AB5 /* GameInfo.swift */, ); path = GameEngine; sourceTree = ""; @@ -459,6 +468,7 @@ 4E630F282B9F7EC20008F887 /* Components */ = { isa = PBXGroup; children = ( + E69FDDDF2BAD3DAD0089D5F3 /* PointsComponent.swift */, E6B34A462BAA03AF0009A60B /* PlayerComponent.swift */, 4E630F292B9F7EF60008F887 /* PositionComponent.swift */, 14970F4F2BA814D500CC1E8A /* ScoreComponent.swift */, @@ -482,6 +492,7 @@ 4E86605D2BA095CC0035530D /* Constants */ = { isa = PBXGroup; children = ( + E69FDDE12BAD3DC40089D5F3 /* EntityConstants.swift */, 4E8660652BA097D40035530D /* PhysicsConstants.swift */, 14970F552BA8177B00CC1E8A /* GameConstants.swift */, ); @@ -527,6 +538,7 @@ E6A745102BA057040080C1BE /* Rendering */ = { isa = PBXGroup; children = ( + E69EE9332BAC6CC300033AB5 /* OverlayInfo.swift */, E6B5509F2BA15D2000DC7396 /* MTKRenderer */, E6A745132BA057040080C1BE /* Renderer.swift */, E6B0AAD02BAAE3DC009CB939 /* ViewDelegate.swift */, @@ -719,6 +731,7 @@ files = ( 46D418182BA5CD840091A38B /* Player+Collidable.swift in Sources */, 46D4181E2BA5D2620091A38B /* Monster+Collidable.swift in Sources */, + E69EE9342BAC6CC300033AB5 /* OverlayInfo.swift in Sources */, E6B1DC902BA34A4800473563 /* SDPhysicsEngine in Sources */, 4E630F272B9F7E770008F887 /* Entity.swift in Sources */, 4E630F2C2B9F7F460008F887 /* Component.swift in Sources */, @@ -758,10 +771,12 @@ 4604BBD92BA81C940078B84C /* InventorySystem.swift in Sources */, 14E247952BA2CB480071FFC0 /* EventManager.swift in Sources */, 4E630EF82B9F7E070008F887 /* SceneDelegate.swift in Sources */, + E69FDDE02BAD3DAD0089D5F3 /* PointsComponent.swift in Sources */, 14970F542BA8163300CC1E8A /* ScoreSystem.swift in Sources */, E64361112BA4C2CD003850FD /* SyncModule.swift in Sources */, E6A7451B2BA0C1890080C1BE /* PlayerView.swift in Sources */, 46D418282BA5D6800091A38B /* Floor+Collidable.swift in Sources */, + E69EE9322BAC6CBB00033AB5 /* GameInfo.swift in Sources */, 46D418222BA5D4E60091A38B /* Obstacle+Collidable.swift in Sources */, E638B9CF2BAB3C5D00931CC2 /* TeleportEvent.swift in Sources */, E6A745162BA057040080C1BE /* MTKRenderer.swift in Sources */, @@ -778,6 +793,7 @@ E6A7451D2BA0CAD90080C1BE /* JoystickView.swift in Sources */, E6B550A12BA15E9C00DC7396 /* OverlayView.swift in Sources */, 46D418262BA5D6500091A38B /* Wall+Collidable.swift in Sources */, + E69FDDE22BAD3DC40089D5F3 /* EntityConstants.swift in Sources */, 4E630F342B9F8FC00008F887 /* Player.swift in Sources */, 4E630F372B9F91DE0008F887 /* PlayerSprite.swift in Sources */, 14970F502BA814D500CC1E8A /* ScoreComponent.swift in Sources */, diff --git a/star-dash/star-dash/Constants/EntityConstants.swift b/star-dash/star-dash/Constants/EntityConstants.swift new file mode 100644 index 00000000..46f593fd --- /dev/null +++ b/star-dash/star-dash/Constants/EntityConstants.swift @@ -0,0 +1,9 @@ +import CoreGraphics + +struct EntityConstants { + struct CoinCollectible { + static let points = 10 + static let sprite = "Coin" + static let size = CGSize(width: 50, height: 50) + } +} diff --git a/star-dash/star-dash/Constants/PhysicsConstants.swift b/star-dash/star-dash/Constants/PhysicsConstants.swift index 7a7e0dc4..c8e40f38 100644 --- a/star-dash/star-dash/Constants/PhysicsConstants.swift +++ b/star-dash/star-dash/Constants/PhysicsConstants.swift @@ -21,15 +21,25 @@ struct PhysicsConstants { } struct CollisionMask { - static let player = CollisionCategory.max ^ CollisionCategory.player + static let player = CollisionCategory.max ^ CollisionCategory.player ^ CollisionCategory.collectible static let monster = CollisionCategory.player | CollisionCategory.tool - static let collectible = CollisionCategory.player + static let collectible = CollisionCategory.none static let obstacle = CollisionCategory.player | CollisionCategory.monster | CollisionMask.tool static let tool = CollisionCategory.max ^ CollisionCategory.collectible ^ CollisionCategory.tool static let wall = CollisionCategory.player | CollisionCategory.monster | CollisionCategory.tool static let floor = CollisionCategory.player | CollisionCategory.monster | CollisionCategory.tool } + struct ContactMask { + static let player = CollisionCategory.floor | CollisionCategory.collectible + static let monster = CollisionCategory.player + static let collectible = CollisionCategory.player + static let obstacle = CollisionCategory.none + static let tool = CollisionCategory.obstacle + static let wall = CollisionCategory.tool | CollisionCategory.player + static let floor = CollisionCategory.player + } + struct Dimensions { // TODO: determine appropriate size for each static let player = CGSize(width: 60, height: 60) diff --git a/star-dash/star-dash/Events/PlayerEvents/PickupCollectibleEvent.swift b/star-dash/star-dash/Events/PlayerEvents/PickupCollectibleEvent.swift index a0ab9821..b4a94aad 100644 --- a/star-dash/star-dash/Events/PlayerEvents/PickupCollectibleEvent.swift +++ b/star-dash/star-dash/Events/PlayerEvents/PickupCollectibleEvent.swift @@ -20,10 +20,11 @@ class PickupCollectibleEvent: Event { } func execute(on target: EventModifiable) { - guard let scoreSystem = target.system(ofType: ScoreSystem.self) else { + guard let scoreSystem = target.system(ofType: ScoreSystem.self), + let pointsComponent = target.component(ofType: PointsComponent.self, ofEntity: collectibleEntityId) else { return } - scoreSystem.applyScoreChange(to: entityId, scoreChange: GameConstants.ScoreChange.pickupCollectible) + scoreSystem.applyScoreChange(to: entityId, scoreChange: pointsComponent.points) target.add(event: RemoveEvent(on: collectibleEntityId)) } } diff --git a/star-dash/star-dash/GameBridge/GameBridge.swift b/star-dash/star-dash/GameBridge/GameBridge.swift index a71662ba..9a66db72 100644 --- a/star-dash/star-dash/GameBridge/GameBridge.swift +++ b/star-dash/star-dash/GameBridge/GameBridge.swift @@ -88,5 +88,13 @@ class GameBridge { } private func removeObject(from entityId: EntityId) { + guard let object = entitiesMap[entityId] else { + return + } + + entitiesMap[entityId] = nil + objectsMap[object.id] = nil + + self.scene.removeObject(object) } } diff --git a/star-dash/star-dash/GameBridge/SyncModule/PhysicsModule.swift b/star-dash/star-dash/GameBridge/SyncModule/PhysicsModule.swift index e9e4e622..b20a5a82 100644 --- a/star-dash/star-dash/GameBridge/SyncModule/PhysicsModule.swift +++ b/star-dash/star-dash/GameBridge/SyncModule/PhysicsModule.swift @@ -38,6 +38,7 @@ class PhysicsModule: SyncModule { object.physicsBody = createRectanglePhysicsBody(physicsComponent: physicsComponent) object.physicsBody?.restitution = physicsComponent.restitution object.physicsBody?.isDynamic = physicsComponent.isDynamic + object.physicsBody?.affectedByGravity = physicsComponent.affectedByGravity object.physicsBody?.categoryBitMask = physicsComponent.categoryBitMask object.physicsBody?.contactTestMask = physicsComponent.contactTestMask object.physicsBody?.collisionBitMask = physicsComponent.collisionBitMask diff --git a/star-dash/star-dash/GameBridge/SyncModule/SpriteModule.swift b/star-dash/star-dash/GameBridge/SyncModule/SpriteModule.swift index a08c9705..aa15e7c9 100644 --- a/star-dash/star-dash/GameBridge/SyncModule/SpriteModule.swift +++ b/star-dash/star-dash/GameBridge/SyncModule/SpriteModule.swift @@ -31,7 +31,11 @@ extension SpriteModule: CreationModule { var newObject = SDObject() if let spriteComponent = entityManager.component(ofType: SpriteComponent.self, of: entity.id) { let spriteObject = SDSpriteObject(imageNamed: "PlayerRedNose") - spriteObject.size = CGSize(width: 100, height: 140) + + if let size = spriteComponent.size { + spriteObject.size = size + } + newObject = spriteObject } diff --git a/star-dash/star-dash/GameEngine/Components/PointsComponent.swift b/star-dash/star-dash/GameEngine/Components/PointsComponent.swift new file mode 100644 index 00000000..752e9ebf --- /dev/null +++ b/star-dash/star-dash/GameEngine/Components/PointsComponent.swift @@ -0,0 +1,14 @@ +import Foundation + +class PointsComponent: Component { + let points: Int + + init(id: UUID, entityId: UUID, points: Int) { + self.points = points + super.init(id: id, entityId: entityId) + } + + convenience init(entityId: UUID, points: Int) { + self.init(id: UUID(), entityId: entityId, points: points) + } +} diff --git a/star-dash/star-dash/GameEngine/Components/SpriteComponent.swift b/star-dash/star-dash/GameEngine/Components/SpriteComponent.swift index 585fac6d..6059e767 100644 --- a/star-dash/star-dash/GameEngine/Components/SpriteComponent.swift +++ b/star-dash/star-dash/GameEngine/Components/SpriteComponent.swift @@ -12,16 +12,16 @@ class SpriteComponent: Component { // for sprite set will need to discuss how to rep animation var image: String var textureAtlas: String? - var size: CGSize + var size: CGSize? - init(id: ComponentId, entityId: EntityId, image: String, textureAtlas: String?, size: CGSize) { + init(id: ComponentId, entityId: EntityId, image: String, textureAtlas: String?, size: CGSize?) { self.image = image self.size = size self.textureAtlas = textureAtlas super.init(id: id, entityId: entityId) } - convenience init(entityId: EntityId, image: String, textureAtlas: String?, size: CGSize) { + convenience init(entityId: EntityId, image: String, textureAtlas: String?, size: CGSize?) { self.init(id: UUID(), entityId: entityId, image: image, textureAtlas: textureAtlas, size: size) } } diff --git a/star-dash/star-dash/GameEngine/Entities/GameEntities/Collectible.swift b/star-dash/star-dash/GameEngine/Entities/GameEntities/Collectible.swift index bb0d7c39..f7d5d59c 100644 --- a/star-dash/star-dash/GameEngine/Entities/GameEntities/Collectible.swift +++ b/star-dash/star-dash/GameEngine/Entities/GameEntities/Collectible.swift @@ -10,23 +10,46 @@ import Foundation class Collectible: Entity { let id: EntityId private let position: CGPoint + private let sprite: String + private let points: Int + private let size: CGSize - init(id: EntityId, position: CGPoint) { + init(id: EntityId, position: CGPoint, sprite: String, points: Int, size: CGSize) { self.id = id self.position = position + self.sprite = sprite + self.points = points + self.size = size } - convenience init(position: CGPoint) { - self.init(id: UUID(), position: position) + convenience init(position: CGPoint, sprite: String, points: Int, size: CGSize) { + self.init(id: UUID(), position: position, sprite: sprite, points: points, size: size) } func setUpAndAdd(to: EntityManager) { let positionComponent = PositionComponent(entityId: self.id, position: self.position, rotation: .zero) - let physicsComponent = PhysicsComponent(entityId: self.id, size: PhysicsConstants.Dimensions.collectible) + let physicsComponent = PhysicsComponent(entityId: self.id, size: self.size) + physicsComponent.affectedByGravity = false + physicsComponent.isDynamic = false + physicsComponent.categoryBitMask = PhysicsConstants.CollisionCategory.collectible + physicsComponent.contactTestMask = PhysicsConstants.ContactMask.collectible physicsComponent.collisionBitMask = PhysicsConstants.CollisionMask.collectible + let spriteComponent = SpriteComponent(entityId: self.id, image: sprite, textureAtlas: nil, size: size) + let pointsComponent = PointsComponent(entityId: self.id, points: points) to.add(entity: self) to.add(component: positionComponent) to.add(component: physicsComponent) + to.add(component: spriteComponent) + to.add(component: pointsComponent) + } + + static func createCoinCollectible(position: CGPoint) -> Collectible { + Collectible( + position: position, + sprite: EntityConstants.CoinCollectible.sprite, + points: EntityConstants.CoinCollectible.points, + size: EntityConstants.CoinCollectible.size + ) } } diff --git a/star-dash/star-dash/GameEngine/Entities/GameEntities/Floor.swift b/star-dash/star-dash/GameEngine/Entities/GameEntities/Floor.swift index 51b3f76f..72627b0c 100644 --- a/star-dash/star-dash/GameEngine/Entities/GameEntities/Floor.swift +++ b/star-dash/star-dash/GameEngine/Entities/GameEntities/Floor.swift @@ -27,7 +27,7 @@ class Floor: Entity { physicsComponent.restitution = 0.0 physicsComponent.isDynamic = false physicsComponent.categoryBitMask = PhysicsConstants.CollisionCategory.floor - physicsComponent.contactTestMask = PhysicsConstants.CollisionCategory.player + physicsComponent.contactTestMask = PhysicsConstants.ContactMask.floor physicsComponent.collisionBitMask = PhysicsConstants.CollisionMask.floor to.add(entity: self) diff --git a/star-dash/star-dash/GameEngine/Entities/GameEntities/Player.swift b/star-dash/star-dash/GameEngine/Entities/GameEntities/Player.swift index 0c0d1b90..de6c668c 100644 --- a/star-dash/star-dash/GameEngine/Entities/GameEntities/Player.swift +++ b/star-dash/star-dash/GameEngine/Entities/GameEntities/Player.swift @@ -30,11 +30,16 @@ class Player: Entity { let healthComponent = HealthComponent(entityId: self.id, health: GameConstants.InitialHealth.player) let physicsComponent = PhysicsComponent(entityId: self.id, size: PhysicsConstants.Dimensions.player) physicsComponent.categoryBitMask = PhysicsConstants.CollisionCategory.player - physicsComponent.contactTestMask = PhysicsConstants.CollisionCategory.floor + physicsComponent.contactTestMask = PhysicsConstants.ContactMask.player physicsComponent.collisionBitMask = PhysicsConstants.CollisionMask.player physicsComponent.affectedByGravity = true physicsComponent.restitution = 0.0 - let spriteComponent = SpriteComponent(entityId: self.id, image: "", textureAtlas: "", size: .zero) + let spriteComponent = SpriteComponent( + entityId: self.id, + image: "PlayerRedNose", + textureAtlas: "", + size: CGSize(width: 100, height: 140) + ) let scoreComponent = ScoreComponent(entityId: self.id, score: 0) to.add(entity: self) diff --git a/star-dash/star-dash/GameEngine/GameEngine.swift b/star-dash/star-dash/GameEngine/GameEngine.swift index 207872fc..54ae9b84 100644 --- a/star-dash/star-dash/GameEngine/GameEngine.swift +++ b/star-dash/star-dash/GameEngine/GameEngine.swift @@ -20,6 +20,18 @@ class GameEngine { 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) @@ -57,6 +69,7 @@ class GameEngine { private func setUpSystems() { systemManager.add(PositionSystem(entityManager, dispatcher: self)) systemManager.add(PhysicsSystem(entityManager, dispatcher: self)) + systemManager.add(ScoreSystem(entityManager, dispatcher: self)) } } diff --git a/star-dash/star-dash/GameEngine/GameInfo.swift b/star-dash/star-dash/GameEngine/GameInfo.swift new file mode 100644 index 00000000..3ca81506 --- /dev/null +++ b/star-dash/star-dash/GameEngine/GameInfo.swift @@ -0,0 +1,3 @@ +struct GameInfo { + let playerScore: Int +} diff --git a/star-dash/star-dash/GameEngine/Systems/ScoreSystem.swift b/star-dash/star-dash/GameEngine/Systems/ScoreSystem.swift index cc058f12..14ed8fc4 100644 --- a/star-dash/star-dash/GameEngine/Systems/ScoreSystem.swift +++ b/star-dash/star-dash/GameEngine/Systems/ScoreSystem.swift @@ -18,6 +18,14 @@ class ScoreSystem: System { self.dispatcher = dispatcher } + func score(of entityId: EntityId) -> Int? { + guard let scoreComponent = getScoreComponent(of: entityId) else { + return nil + } + + return scoreComponent.score + } + func applyScoreChange(to entityId: EntityId, scoreChange: Int) { guard let scoreComponent = getScoreComponent(of: entityId) else { return diff --git a/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift b/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift index dbd7042b..7289eafc 100644 --- a/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift +++ b/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift @@ -35,6 +35,10 @@ class MTKRenderer: NSObject, Renderer { super.init() } + func updateOverlay(overlayInfo: OverlayInfo) { + playerView?.updateOverlay(score: overlayInfo.score) + } + /// Set ups the views for a single player game. func createSinglePlayerView(at superview: UIView) { let playerView = PlayerView(superview: superview, device: self.device, drawDelegate: self) diff --git a/star-dash/star-dash/Rendering/MTKRenderer/OverlayView.swift b/star-dash/star-dash/Rendering/MTKRenderer/OverlayView.swift index 10334cad..dd49363e 100644 --- a/star-dash/star-dash/Rendering/MTKRenderer/OverlayView.swift +++ b/star-dash/star-dash/Rendering/MTKRenderer/OverlayView.swift @@ -11,10 +11,9 @@ class OverlayView: UIView { let scoreLabel = UILabel() func setupSubviews() { - scoreLabel.text = "Score: 0" scoreLabel.numberOfLines = 1 scoreLabel.translatesAutoresizingMaskIntoConstraints = false - scoreLabel.textColor = .white + scoreLabel.textColor = .black addSubview(scoreLabel) NSLayoutConstraint.activate([ @@ -22,5 +21,11 @@ class OverlayView: UIView { scoreLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -1 * margin), scoreLabel.leadingAnchor.constraint(greaterThanOrEqualTo: self.leadingAnchor, constant: margin) ]) + + update(score: 0) + } + + func update(score: Int) { + scoreLabel.text = "Score: \(score)" } } diff --git a/star-dash/star-dash/Rendering/MTKRenderer/PlayerView.swift b/star-dash/star-dash/Rendering/MTKRenderer/PlayerView.swift index aa65fff2..85cbc703 100644 --- a/star-dash/star-dash/Rendering/MTKRenderer/PlayerView.swift +++ b/star-dash/star-dash/Rendering/MTKRenderer/PlayerView.swift @@ -35,4 +35,8 @@ class PlayerView { func setControlViewDelegate(_ delegate: ControlViewDelegate) { controlView.controlViewDelegate = delegate } + + func updateOverlay(score: Int) { + overlayView.update(score: score) + } } diff --git a/star-dash/star-dash/Rendering/OverlayInfo.swift b/star-dash/star-dash/Rendering/OverlayInfo.swift new file mode 100644 index 00000000..39078791 --- /dev/null +++ b/star-dash/star-dash/Rendering/OverlayInfo.swift @@ -0,0 +1,3 @@ +struct OverlayInfo { + let score: Int +} diff --git a/star-dash/star-dash/Rendering/Renderer.swift b/star-dash/star-dash/Rendering/Renderer.swift index 89278d8b..1cd7c11c 100644 --- a/star-dash/star-dash/Rendering/Renderer.swift +++ b/star-dash/star-dash/Rendering/Renderer.swift @@ -4,5 +4,6 @@ import UIKit The `Renderer` protocol defines the requirements for an object responsible for rendering game objects onto a view. */ protocol Renderer { + func updateOverlay(overlayInfo: OverlayInfo) func createSinglePlayerView(at rootView: UIView) } diff --git a/star-dash/star-dash/ViewController.swift b/star-dash/star-dash/ViewController.swift index cb24472b..e7bc563c 100644 --- a/star-dash/star-dash/ViewController.swift +++ b/star-dash/star-dash/ViewController.swift @@ -57,6 +57,11 @@ class ViewController: UIViewController { let floor = Floor(position: CGPoint(x: scene.size.width / 2, y: scene.size.height / 2 - 400)) floor.setUpAndAdd(to: entityManager) + + let collectible = Collectible.createCoinCollectible( + position: CGPoint(x: scene.size.width / 2 + 30, y: scene.size.height / 2 - 100) + ) + collectible.setUpAndAdd(to: entityManager) } } @@ -66,6 +71,14 @@ extension ViewController: SDSceneDelegate { gameBridge?.syncToEntities() gameEngine?.update(by: deltaTime) gameBridge?.syncFromEntities() + + guard let gameInfo = gameEngine?.gameInfo() else { + return + } + + renderer?.updateOverlay(overlayInfo: OverlayInfo( + score: gameInfo.playerScore + )) } func contactOccured(objectA: SDObject, objectB: SDObject, contactPoint: CGPoint) {