diff --git a/.swiftlint.yml b/.swiftlint.yml index 5310eee9..3d4ab71e 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -2,7 +2,6 @@ excluded: - Pods opt_in_rules: - - anyobject_protocol - array_init - attributes - closure_body_length @@ -20,7 +19,6 @@ opt_in_rules: - empty_xctest_method - expiring_todo - explicit_init - - explicit_self - fallthrough - fatal_error_message - file_name @@ -65,8 +63,6 @@ opt_in_rules: - unneeded_parentheses_in_closure_argument - unowned_variable_capture - untyped_error_in_catch - - unused_declaration - - unused_import - vertical_parameter_alignment_on_call - xct_specific_matcher - yoda_condition @@ -81,3 +77,8 @@ disabled_rules: line_length: warning: 120 error: 150 + +analyzer_rules: + - explicit_self + - unused_declaration + - unused_import diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift index 68a4ebcc..c002f9e7 100644 --- a/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/GameScene.swift @@ -43,6 +43,15 @@ extension GameScene: SDScene { objectMap[object.node] = nil object.removeFromParent() } + + public func addCameraObject(_ cameraObject: SDCameraObject) { + addObject(cameraObject) + camera = cameraObject.cameraNode + } + + public func setCameraObjectXPosition(to x: CGFloat) { + camera?.position.x = x + } } extension GameScene: SKPhysicsContactDelegate { @@ -57,7 +66,7 @@ extension GameScene: SKPhysicsContactDelegate { fatalError("Unknown node in game scene") } - sceneDelegate?.contactOccured( + sceneDelegate?.contactOccurred( objectA: objectA, objectB: objectB, contactPoint: contact.contactPoint diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDCameraObject.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDCameraObject.swift new file mode 100644 index 00000000..320069ef --- /dev/null +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/Object/SDCameraObject.swift @@ -0,0 +1,10 @@ +import SpriteKit + +public class SDCameraObject: SDObject { + let cameraNode: SKCameraNode + + override public init() { + cameraNode = SKCameraNode() + super.init(node: cameraNode) + } +} diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift index c35a3142..893c9312 100644 --- a/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/SDScene.swift @@ -6,4 +6,6 @@ public protocol SDScene { func addObject(_ object: SDObject) func removeObject(_ object: SDObject) + func addCameraObject(_ cameraObject: SDCameraObject) + func setCameraObjectXPosition(to x: CGFloat) } diff --git a/SDPhysicsEngine/Sources/SDPhysicsEngine/SDSceneDelegate.swift b/SDPhysicsEngine/Sources/SDPhysicsEngine/SDSceneDelegate.swift index 7b43f92d..16b3f1eb 100644 --- a/SDPhysicsEngine/Sources/SDPhysicsEngine/SDSceneDelegate.swift +++ b/SDPhysicsEngine/Sources/SDPhysicsEngine/SDSceneDelegate.swift @@ -3,5 +3,5 @@ import CoreGraphics public protocol SDSceneDelegate: AnyObject { func update(_ scene: SDScene, deltaTime: Double) - func contactOccured(objectA: SDObject, objectB: SDObject, contactPoint: CGPoint) + func contactOccurred(objectA: SDObject, objectB: SDObject, contactPoint: CGPoint) } diff --git a/star-dash/.swiftlint.yml b/star-dash/.swiftlint.yml index 5310eee9..3d4ab71e 100644 --- a/star-dash/.swiftlint.yml +++ b/star-dash/.swiftlint.yml @@ -2,7 +2,6 @@ excluded: - Pods opt_in_rules: - - anyobject_protocol - array_init - attributes - closure_body_length @@ -20,7 +19,6 @@ opt_in_rules: - empty_xctest_method - expiring_todo - explicit_init - - explicit_self - fallthrough - fatal_error_message - file_name @@ -65,8 +63,6 @@ opt_in_rules: - unneeded_parentheses_in_closure_argument - unowned_variable_capture - untyped_error_in_catch - - unused_declaration - - unused_import - vertical_parameter_alignment_on_call - xct_specific_matcher - yoda_condition @@ -81,3 +77,8 @@ disabled_rules: line_length: warning: 120 error: 150 + +analyzer_rules: + - explicit_self + - unused_declaration + - unused_import diff --git a/star-dash/star-dash.xcodeproj/project.pbxproj b/star-dash/star-dash.xcodeproj/project.pbxproj index b72f66df..011cb206 100644 --- a/star-dash/star-dash.xcodeproj/project.pbxproj +++ b/star-dash/star-dash.xcodeproj/project.pbxproj @@ -858,8 +858,6 @@ E69EE9322BAC6CBB00033AB5 /* GameInfo.swift in Sources */, 46D418222BA5D4E60091A38B /* Obstacle+Collidable.swift in Sources */, E638B9CF2BAB3C5D00931CC2 /* TeleportEvent.swift in Sources */, - E6A745162BA057040080C1BE /* MTKRenderer.swift in Sources */, - E6A745182BA057040080C1BE /* Renderer.swift in Sources */, 143AA3972BA4E0D9009C28E7 /* PickupCollectibleEvent.swift in Sources */, 46D418242BA5D5280091A38B /* Tool+Collidable.swift in Sources */, E64361142BA4C2CD003850FD /* CreationModule.swift in Sources */, diff --git a/star-dash/star-dash/GameEngine/GameEngine.swift b/star-dash/star-dash/GameEngine/GameEngine.swift index 7923be09..fd9e361f 100644 --- a/star-dash/star-dash/GameEngine/GameEngine.swift +++ b/star-dash/star-dash/GameEngine/GameEngine.swift @@ -73,6 +73,14 @@ class GameEngine { 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)) diff --git a/star-dash/star-dash/Persistence/Database.swift b/star-dash/star-dash/Persistence/Database.swift index aad42064..95742493 100644 --- a/star-dash/star-dash/Persistence/Database.swift +++ b/star-dash/star-dash/Persistence/Database.swift @@ -233,40 +233,36 @@ struct Database { extension Database { func insertJsonData() { - do { - if let fileURL = Bundle.main.url(forResource: "data", withExtension: "json") { - // Read JSON data from the file - do { - let jsonData = try Data(contentsOf: fileURL) - // Decode JSON data into LevelData - let levelData = try JSONDecoder().decode(LevelData.self, from: jsonData) - let levelPersistable = LevelPersistable( - id: levelData.id, - name: levelData.name, - size: levelData.size - ) - insert(persistable: levelPersistable) - for persistable in levelData.collectibles { - insert(persistable: persistable) - } - for persistable in levelData.tools { - insert(persistable: persistable) - } - for persistable in levelData.obstacles { - insert(persistable: persistable) - } - for persistable in levelData.monsters { - insert(persistable: persistable) - } - - } catch { - print("Error reading or decoding JSON: \(error)") + if let fileURL = Bundle.main.url(forResource: "data", withExtension: "json") { + // Read JSON data from the file + do { + let jsonData = try Data(contentsOf: fileURL) + // Decode JSON data into LevelData + let levelData = try JSONDecoder().decode(LevelData.self, from: jsonData) + let levelPersistable = LevelPersistable( + id: levelData.id, + name: levelData.name, + size: levelData.size + ) + insert(persistable: levelPersistable) + for persistable in levelData.collectibles { + insert(persistable: persistable) + } + for persistable in levelData.tools { + insert(persistable: persistable) + } + for persistable in levelData.obstacles { + insert(persistable: persistable) + } + for persistable in levelData.monsters { + insert(persistable: persistable) } - } else { - print("JSON file not found.") + + } catch { + print("Error reading or decoding JSON: \(error)") } - } catch { - print(error) + } else { + print("JSON file not found.") } } diff --git a/star-dash/star-dash/Rendering/MTKRenderer/ControlView.swift b/star-dash/star-dash/Rendering/MTKRenderer/ControlView.swift index 6952acc6..dd2dc7c5 100644 --- a/star-dash/star-dash/Rendering/MTKRenderer/ControlView.swift +++ b/star-dash/star-dash/Rendering/MTKRenderer/ControlView.swift @@ -58,7 +58,8 @@ class ControlView: UIView { // MARK: Gesture handler methods - @objc func jumpButtonTapped() { + @objc + func jumpButtonTapped() { controlViewDelegate?.jumpButtonPressed() } @@ -92,7 +93,8 @@ class ControlView: UIView { joystickView?.returnJoystick() } - @objc func handlePan(_ gesture: UIPanGestureRecognizer) { + @objc + func handlePan(_ gesture: UIPanGestureRecognizer) { guard let joystickView = self.joystickView else { return } diff --git a/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift b/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift index fc3dc768..49361cc9 100644 --- a/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift +++ b/star-dash/star-dash/Rendering/MTKRenderer/MTKRenderer.swift @@ -7,7 +7,7 @@ import MetalKit the game on to the iOS device. The `SKScene` is rendered through a MetalKit while the controls - and game information overlay is rendered throuhg UIKit. + and game information overlay is rendered through UIKit. */ class MTKRenderer: NSObject, Renderer { var scene: SKScene diff --git a/star-dash/star-dash/ViewController.swift b/star-dash/star-dash/ViewController.swift index ac4b904e..9f9b5cf9 100644 --- a/star-dash/star-dash/ViewController.swift +++ b/star-dash/star-dash/ViewController.swift @@ -43,6 +43,10 @@ class ViewController: UIViewController { return } + let camera = SDCameraObject() + camera.position = CGPoint(x: scene.size.width / 2, y: scene.size.height / 2) + scene.addCameraObject(camera) + let background = SDSpriteObject(imageNamed: "GameBackground") background.position = CGPoint(x: scene.size.width / 2, y: scene.size.height / 2) background.zPosition = -1 @@ -80,6 +84,18 @@ extension ViewController: SDSceneDelegate { gameEngine?.update(by: deltaTime) gameBridge?.syncFromEntities() + updateCameraObjectPosition(scene) + updateOverlay() + } + + private func updateCameraObjectPosition(_ scene: SDScene) { + guard let playerPosition = gameEngine?.playerPosition() else { + return + } + scene.setCameraObjectXPosition(to: playerPosition.x) + } + + private func updateOverlay() { guard let gameInfo = gameEngine?.gameInfo() else { return } @@ -89,7 +105,7 @@ extension ViewController: SDSceneDelegate { )) } - func contactOccured(objectA: SDObject, objectB: SDObject, contactPoint: CGPoint) { + func contactOccurred(objectA: SDObject, objectB: SDObject, contactPoint: CGPoint) { guard let entityA = gameBridge?.entityId(of: objectA.id), let entityB = gameBridge?.entityId(of: objectB.id) else { return diff --git a/star-dash/star-dashUITests/star_dashUITests.swift b/star-dash/star-dashUITests/star_dashUITests.swift index 48efc1a4..5379bb05 100644 --- a/star-dash/star-dashUITests/star_dashUITests.swift +++ b/star-dash/star-dashUITests/star_dashUITests.swift @@ -9,15 +9,15 @@ import XCTest final class star_dashUITests: XCTestCase { - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. + // override func setUpWithError() throws { + // // Put setup code here. This method is called before the invocation of each test method in the class. - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false + // // In UI tests it is usually best to stop immediately when a failure occurs. + // continueAfterFailure = false - // In UI tests it’s important to set the initial state - such as interface orientation - - // required for your tests before they run. The setUp method is a good place to do this. - } + // // In UI tests it’s important to set the initial state - such as interface orientation - + // // required for your tests before they run. The setUp method is a good place to do this. + // } // override func tearDownWithError() throws { // // Put teardown code here. This method is called after the invocation of each test method in the class.