From 02cdafa89520c08b77127ca5ad20aea4d9f3de0a Mon Sep 17 00:00:00 2001
From: tobias <thinkdifferent055@gmail.com>
Date: Sat, 15 Jul 2017 11:33:26 +0200
Subject: [PATCH] Improve points collection

---
 Pacman3D-iOS/GameViewController.swift | 24 +++++++++++------------
 Pacman3D-iOS/Level.swift              | 28 +++++++++++++++------------
 Pacman3D-iOS/Monster.swift            |  8 ++++----
 Pacman3D-iOS/Player.swift             | 28 +++++++++++++++++++++------
 4 files changed, 53 insertions(+), 35 deletions(-)

diff --git a/Pacman3D-iOS/GameViewController.swift b/Pacman3D-iOS/GameViewController.swift
index be8c1b6..81a76e8 100644
--- a/Pacman3D-iOS/GameViewController.swift
+++ b/Pacman3D-iOS/GameViewController.swift
@@ -12,7 +12,7 @@ import SceneKit
 import SpriteKit
 import CoreMotion
 
-class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDelegate, SCNSceneRendererDelegate {
+class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDelegate, SCNSceneRendererDelegate, PlayerDelegate {
 
     var motionManager: CMMotionManager?
     var scene: SCNScene!
@@ -46,6 +46,7 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe
         
         let pacman = scene.rootNode.childNode(withName: "Pacman", recursively: true)!
         player = Player(node: pacman, scene: scene, level: level)
+        player.delegate = self
         
         // create and add a camera to the scene
         let cameraNode = SCNNode()
@@ -160,18 +161,15 @@ class GameViewController: UIViewController, SKSceneDelegate, SCNPhysicsContactDe
                 //exit(0) // TODO Game Menu
             }
         }
-        
-        if contact.nodeA.name ?? "" == "Point" && contact.nodeB.name ?? "" == "Pacman" ||
-            contact.nodeB.name ?? "" == "Point" && contact.nodeA.name ?? "" == "Pacman" {
-            player.points = player.points + 10
-            
-            pacman.position = SCNVector3(5, 2, 5)
-            pointsLabel.text = "\(player.points) Punkte"
-            if contact.nodeA.name ?? "" == "Point" {
-                contact.nodeA.removeFromParentNode()
-            } else if contact.nodeB.name ?? "" == "Point" {
-                contact.nodeB.removeFromParentNode()
-            }
+    }
+    
+    func player(_ player: Player, scoreDidUpdate score: Int) {
+        pointsLabel.text = "\(player.points) Punkte"
+    }
+    
+    func player(_ player: Player, didCollectScoreAt position: (x: Int, z: Int)) {
+        if let node = scene.rootNode.childNode(withName: "Score.\(position.x).\(position.z)", recursively: true) {
+            node.removeFromParentNode()
         }
     }
     
diff --git a/Pacman3D-iOS/Level.swift b/Pacman3D-iOS/Level.swift
index 9f31ffd..d467f12 100644
--- a/Pacman3D-iOS/Level.swift
+++ b/Pacman3D-iOS/Level.swift
@@ -14,9 +14,10 @@ class Level {
     enum TileType {
         case wall
         case blank
+        case point
     }
     
-    let data: [[TileType]]
+    private (set) var data: [[TileType]]
     
     init(named: String) {
         if let path = Bundle.main.path(forResource: named, ofType: "plv") {
@@ -31,7 +32,7 @@ class Level {
                     for index in line.characters.indices {
                         let c = line[index]
                         if c == "w" {
-                            tempLine.append(TileType.blank)
+                            tempLine.append(TileType.point)
                         } else if c == "s" {
                             tempLine.append(TileType.wall)
                         }
@@ -50,19 +51,25 @@ class Level {
             for (z, block) in line.enumerated() {
                 if block == .wall {
                     addBlock(toScene: scene, at: (x, z))
-                } else if block == .blank {
-                    //addPointObject(toScene: scene, at: (x, z))
+                } else if block == .point {
+                    addPointObject(toScene: scene, at: (x, z))
                 }
             }
         }
     }
     
+    func collectPoint(position: (x: Int, z: Int)) -> Bool {
+        if data[position.x][position.z] == .point {
+            data[position.x][position.z] = .blank
+            
+            return true
+        }
+        return false
+    }
+    
     private func addBlock(toScene scene: SCNScene, at point: (x: Int, z: Int)) {
         let box = SCNBox(width: 5, height: 2, length: 5, chamferRadius: 0)
         let node = SCNNode(geometry: box)
-        node.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry: box, options: nil))
-        node.physicsBody?.categoryBitMask = GameViewController.wallCollision
-        node.physicsBody?.contactTestBitMask = GameViewController.pacmanCollision
         node.position = SCNVector3(x: Float(point.x * 5), y: 1, z: Float(point.z * 5))
         node.name = "\(point.x) \(point.z)"
         scene.rootNode.addChildNode(node)
@@ -72,10 +79,7 @@ class Level {
         let shere = SCNSphere(radius: 0.5)
         shere.firstMaterial?.diffuse.contents = UIColor.blue
         let node = SCNNode(geometry: shere)
-        node.physicsBody = SCNPhysicsBody(type: .static, shape: nil)
-        node.physicsBody?.categoryBitMask = GameViewController.pointsCollision
-        node.physicsBody?.contactTestBitMask = GameViewController.pacmanCollision
-        node.name = "Point"
+        node.name = "Score.\(point.x).\(point.z)"
         node.position = SCNVector3(x: Float(point.x * 5), y: 1, z:Float(point.z * 5))
         scene.rootNode.addChildNode(node)
     }
@@ -85,7 +89,7 @@ class Level {
             let x = Int(arc4random_uniform(UInt32(data.count)))
             let z = Int(arc4random_uniform(UInt32(data[x].count)))
             
-            if data[x][z] == .blank {
+            if data[x][z] != .wall {
                 return (x, z)
             }
         }
diff --git a/Pacman3D-iOS/Monster.swift b/Pacman3D-iOS/Monster.swift
index 460374d..30a1113 100644
--- a/Pacman3D-iOS/Monster.swift
+++ b/Pacman3D-iOS/Monster.swift
@@ -87,16 +87,16 @@ class Monster {
         
         lastRotationPoint = (x, z)
         
-        if level.data[x - 1][z] == .blank {
+        if level.data[x - 1][z] != .wall {
             directions.append(.south)
         }
-        if level.data[x][z - 1] == .blank {
+        if level.data[x][z - 1] != .wall {
             directions.append(.west)
         }
-        if level.data[x + 1][z] == .blank {
+        if level.data[x + 1][z] != .wall {
             directions.append(.north)
         }
-        if level.data[x][z + 1] == .blank {
+        if level.data[x][z + 1] != .wall {
             directions.append(.east)
         }
         
diff --git a/Pacman3D-iOS/Player.swift b/Pacman3D-iOS/Player.swift
index b85151f..fd13e4d 100644
--- a/Pacman3D-iOS/Player.swift
+++ b/Pacman3D-iOS/Player.swift
@@ -9,8 +9,15 @@
 import Foundation
 import SceneKit
 
+protocol PlayerDelegate {
+    func player(_ player: Player, scoreDidUpdate score: Int)
+    func player(_ player: Player, didCollectScoreAt position: (x: Int, z: Int))
+}
+
 class Player {
     
+    var delegate: PlayerDelegate?
+    
     var points: Int = 0
     var life: Int = 3
     
@@ -37,11 +44,20 @@ class Player {
     }
     
     func move() {
-        print("\(direction)\t\(findFreeSpaces())")
-        if !findFreeSpaces().contains(direction) {
+        let freeSpaces = findFreeSpaces()
+        if !freeSpaces.contains(direction) {
             return
         }
         
+        let x: Int = Int(position.x / 5)
+        let z: Int = Int(position.z / 5)
+        
+        if level.collectPoint(position: (x, z)) {
+            points = points + 10
+            delegate?.player(self, didCollectScoreAt: (x, z))
+            delegate?.player(self, scoreDidUpdate: points)
+        }
+        
         if direction == .north {
             position.x += 5
         } else if direction == .east {
@@ -63,16 +79,16 @@ class Player {
         
         print("\(x) \(z)")
         
-        if level.data[x - 1][z] == .blank {
+        if level.data[x - 1][z] != .wall {
             directions.append(.south)
         }
-        if level.data[x][z - 1] == .blank {
+        if level.data[x][z - 1] != .wall {
             directions.append(.west)
         }
-        if level.data[x + 1][z] == .blank {
+        if level.data[x + 1][z] != .wall {
             directions.append(.north)
         }
-        if level.data[x][z + 1] == .blank {
+        if level.data[x][z + 1] != .wall {
             directions.append(.east)
         }
         
-- 
GitLab