diff --git a/Pacman3D-iOS.xcodeproj/project.pbxproj b/Pacman3D-iOS.xcodeproj/project.pbxproj index eac038b3a29accda43547801c4f2cd93c1ffdcd1..41a9bbe00b4cde4b7c7e386b02872fefee2f4044 100644 --- a/Pacman3D-iOS.xcodeproj/project.pbxproj +++ b/Pacman3D-iOS.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + F6090F531F1AA9270003F688 /* pause.png in Resources */ = {isa = PBXBuildFile; fileRef = F6090F521F1AA9270003F688 /* pause.png */; }; F6621DF41F12B09800F9E486 /* TouchInputHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6621DF31F12B09800F9E486 /* TouchInputHandler.swift */; }; F6621DF61F12B82200F9E486 /* MotionInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6621DF51F12B82200F9E486 /* MotionInput.swift */; }; F6BEB8071EF7F99B00EDAA66 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BEB8061EF7F99B00EDAA66 /* AppDelegate.swift */; }; @@ -47,6 +48,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + F6090F521F1AA9270003F688 /* pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause.png; sourceTree = "<group>"; }; F6621DF31F12B09800F9E486 /* TouchInputHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TouchInputHandler.swift; sourceTree = "<group>"; }; F6621DF51F12B82200F9E486 /* MotionInput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionInput.swift; sourceTree = "<group>"; }; F6BEB8031EF7F99B00EDAA66 /* Pacman3D-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Pacman3D-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -100,6 +102,18 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + F6090F541F1AA92D0003F688 /* Resources */ = { + isa = PBXGroup; + children = ( + F6FEE71A1EF8135200C1DE35 /* level.plv */, + F6E39CE11F1A56E500A3E7D1 /* wall.jpg */, + F6E39CE31F1A583B00A3E7D1 /* floor.jpg */, + F6090F521F1AA9270003F688 /* pause.png */, + F6E39CE91F1A7C2C00A3E7D1 /* background.jpg */, + ); + name = Resources; + sourceTree = "<group>"; + }; F6BEB7FA1EF7F99B00EDAA66 = { isa = PBXGroup; children = ( @@ -135,10 +149,7 @@ F6BEB80C1EF7F99B00EDAA66 /* Main.storyboard */, F6BEB8111EF7F99B00EDAA66 /* LaunchScreen.storyboard */, F6BEB8141EF7F99B00EDAA66 /* Info.plist */, - F6FEE71A1EF8135200C1DE35 /* level.plv */, - F6E39CE11F1A56E500A3E7D1 /* wall.jpg */, - F6E39CE31F1A583B00A3E7D1 /* floor.jpg */, - F6E39CE91F1A7C2C00A3E7D1 /* background.jpg */, + F6090F541F1AA92D0003F688 /* Resources */, ); path = "Pacman3D-iOS"; sourceTree = "<group>"; @@ -295,6 +306,7 @@ F6BEB8131EF7F99B00EDAA66 /* LaunchScreen.storyboard in Resources */, F6BEB8101EF7F99B00EDAA66 /* Assets.xcassets in Resources */, F6BEB80E1EF7F99B00EDAA66 /* Main.storyboard in Resources */, + F6090F531F1AA9270003F688 /* pause.png in Resources */, F6FEE71B1EF8135200C1DE35 /* level.plv in Resources */, F6E39CEA1F1A7C2C00A3E7D1 /* background.jpg in Resources */, F6E39CE21F1A56E500A3E7D1 /* wall.jpg in Resources */, diff --git a/Pacman3D-iOS/GameViewController.swift b/Pacman3D-iOS/GameViewController.swift index 502f4038c92cd18add05176f059d2e4a54099181..dc91c2a9305b46ddbe9ef77d1b0411a3083bbd57 100644 --- a/Pacman3D-iOS/GameViewController.swift +++ b/Pacman3D-iOS/GameViewController.swift @@ -28,14 +28,17 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe var lifeLabel: SKLabelNode! var backButton: SKSpriteNode! + var minimap: [[SKSpriteNode]] = [] + var restartButton: SKLabelNode! // MARK: - Game Objects let monsterCount = 6 + var level: Level! var player: Player! - var monsters: [Monster] = [] + var monsters: [Monster]! // MARK: - Input Handler private var touchInputHandler: TouchInputHandler! @@ -44,7 +47,9 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe override func viewDidLoad() { super.viewDidLoad() - let level = Level(named: "level") + monsters = [] + + level = Level(named: "level") // create a new scene scene = SCNScene(named: "art.scnassets/ship.scn")! @@ -88,6 +93,10 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe } // add a tap gesture recognizer + if touchInputHandler != nil { + scnView.removeGestureRecognizer(touchInputHandler) + } + touchInputHandler = TouchInputHandler(target: self, action: #selector(handleTap(_:))) touchInputHandler.scene = (self.view as? SCNView)?.overlaySKScene touchInputHandler.gameController = self @@ -138,7 +147,6 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe if contact.nodeA.name ?? "" == "Monster" && contact.nodeB.name ?? "" == "Monster" { return } - let pacman = self.scene.rootNode.childNode(withName: "Pacman", recursively: true)! if contact.nodeA.name ?? "" == "Monster" && contact.nodeB.name ?? "" == "Pacman" || contact.nodeB.name ?? "" == "Monster" && contact.nodeA.name ?? "" == "Pacman" { @@ -150,6 +158,15 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe let monster = contact.nodeA.name ?? "" == "Monster" ? contact.nodeA : contact.nodeB monster.removeFromParentNode() + for m in monsters { + if let n = m.node { + if n == monster { + monsters.remove(object: m) + break + } + } + } + if player.life <= 0 { self.scene.isPaused = true restartButton.isHidden = false @@ -181,6 +198,8 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe } lastTime = time } + + updateMinimap() } } @@ -199,7 +218,8 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe lifeLabel.position = CGPoint(x: self.view.frame.width - 50, y: 5) scene.addChild(lifeLabel) - backButton = SKSpriteNode(color: UIColor.purple, size: CGSize(width: 40, height: 40)) + backButton = SKSpriteNode(imageNamed: "pause.png") + backButton.size = CGSize(width: 60, height: 60) backButton.position = CGPoint(x: backButton.size.width / 2, y: backButton.size.height / 2) backButton.name = "Back" scene.addChild(backButton) @@ -213,9 +233,50 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe restartButton.name = "Restart" scene.addChild(restartButton) + let frame = self.view.frame + + minimap = [] + for (x, _) in level.data.enumerated() { + var nodes: [SKSpriteNode] = [] + for (z, _) in level.data[x].enumerated() { + let node = SKSpriteNode(color: UIColor.magenta, size: CGSize(width: 5, height: 5)) + let posX = frame.width - CGFloat(level.data[x].count * 5) + CGFloat(z * 5) + 2.5 + let posZ = frame.height - CGFloat(level.data.count * 5) + CGFloat(x * 5) + 2.5 + node.position = CGPoint(x: posX, y: posZ) + nodes.append(node) + scene.addChild(node) + } + minimap.append(nodes) + } + return scene } + func updateMinimap() { + for (x, _) in level.data.enumerated() { + for (z, data) in level.data[x].enumerated() { + let node = minimap[x][z] + switch data { + case .blank: + node.color = UIColor.black.withAlphaComponent(0.6) + case .point: + node.color = UIColor.blue.withAlphaComponent(0.6) + case .wall: + node.color = UIColor.gray.withAlphaComponent(0.6) + } + } + } + + for monster in monsters { + let x: Int = Int(monster.position.x / 5) + let z: Int = Int(monster.position.z / 5) + minimap[x][z].color = UIColor.red.withAlphaComponent(0.6) + } + + let x: Int = Int(player.position.x / 5) + let z: Int = Int(player.position.z / 5) + minimap[x][z].color = UIColor.yellow.withAlphaComponent(0.6) + } func restart() { viewDidLoad() diff --git a/Pacman3D-iOS/Monster.swift b/Pacman3D-iOS/Monster.swift index 30a1113c6a6d49fbf4520b50c2dc85e97c303bf8..039c011925b802dcd7422c408a9877caf56fd9ee 100644 --- a/Pacman3D-iOS/Monster.swift +++ b/Pacman3D-iOS/Monster.swift @@ -9,14 +9,14 @@ import Foundation import SceneKit -class Monster { +class Monster: Equatable { - private var position: SCNVector3 + private (set) var position: SCNVector3 private var direction: Direction = .north private let level: Level private let scene: SCNScene - private var node: SCNNode? + private (set) var node: SCNNode? init(position: SCNVector3, level: Level, scene: SCNScene) { self.position = position @@ -67,13 +67,13 @@ class Monster { } if direction == .north { - position = SCNVector3(x: node.position.x + 0.15, y: node.position.y, z: Float(z * 5)) + position = SCNVector3(x: node.position.x + 0.1, y: node.position.y, z: Float(z * 5)) } else if direction == .east { - position = SCNVector3(x: Float(x * 5), y: node.position.y, z: node.position.z + 0.15) + position = SCNVector3(x: Float(x * 5), y: node.position.y, z: node.position.z + 0.1) } else if direction == .south { - position = SCNVector3(x: node.position.x - 0.15, y: node.position.y, z: Float(z * 5)) + position = SCNVector3(x: node.position.x - 0.1, y: node.position.y, z: Float(z * 5)) } else if direction == .west { - position = SCNVector3(x: Float(x * 5), y: node.position.y, z: node.position.z - 0.15) + position = SCNVector3(x: Float(x * 5), y: node.position.y, z: node.position.z - 0.1) } node.position = position } @@ -102,4 +102,8 @@ class Monster { return directions } + + public static func ==(lhs: Monster, rhs: Monster) -> Bool { + return lhs.node == rhs.node + } } diff --git a/Pacman3D-iOS/MotionInput.swift b/Pacman3D-iOS/MotionInput.swift index 822bdafe61883547576a854b979efb1ba26532bc..bd56d8fe92c774bd214ef8a95a2583cb81a94dcb 100644 --- a/Pacman3D-iOS/MotionInput.swift +++ b/Pacman3D-iOS/MotionInput.swift @@ -26,7 +26,7 @@ class MotionInput { let direction: Float = rotate < 0 ? 1.0 : -1.0 if abs(rotate) > 0.3 { if !self.isRotating { - let action = SCNAction.rotateBy(x: 0, y: CGFloat(direction * Float.pi * 0.5), z: 0, duration: 0.25) + let action = SCNAction.rotateBy(x: 0, y: CGFloat(direction * Float.pi * 0.5), z: 0, duration: 0.15) pacman.runAction(action, completionHandler: nil) self.isRotating = true diff --git a/Pacman3D-iOS/pause.png b/Pacman3D-iOS/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..28b37804f7fefa1fdd7688fd35580a5a6967471f Binary files /dev/null and b/Pacman3D-iOS/pause.png differ