Skip to content
Snippets Groups Projects
Commit 6e081d1f authored by Tobias Ullerich's avatar Tobias Ullerich
Browse files

Improve pacman moving; Cleanup code

parent bbfab917
Branches
Tags
No related merge requests found
......@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
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 */; };
F6BEB8091EF7F99B00EDAA66 /* art.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = F6BEB8081EF7F99B00EDAA66 /* art.scnassets */; };
F6BEB80B1EF7F99B00EDAA66 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BEB80A1EF7F99B00EDAA66 /* GameViewController.swift */; };
......@@ -42,6 +44,8 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
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; };
F6BEB8061EF7F99B00EDAA66 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F6BEB8081EF7F99B00EDAA66 /* art.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; path = art.scnassets; sourceTree = "<group>"; };
......@@ -116,10 +120,12 @@
F6FEE7141EF80AB900C1DE35 /* Level */,
F6FEE7191EF80C1900C1DE35 /* Uilts */,
F6BEB8061EF7F99B00EDAA66 /* AppDelegate.swift */,
F6BEB8081EF7F99B00EDAA66 /* art.scnassets */,
F6BEB80A1EF7F99B00EDAA66 /* GameViewController.swift */,
F6BEB80C1EF7F99B00EDAA66 /* Main.storyboard */,
F6621DF31F12B09800F9E486 /* TouchInputHandler.swift */,
F6621DF51F12B82200F9E486 /* MotionInput.swift */,
F6BEB8081EF7F99B00EDAA66 /* art.scnassets */,
F6BEB80F1EF7F99B00EDAA66 /* Assets.xcassets */,
F6BEB80C1EF7F99B00EDAA66 /* Main.storyboard */,
F6BEB8111EF7F99B00EDAA66 /* LaunchScreen.storyboard */,
F6BEB8141EF7F99B00EDAA66 /* Info.plist */,
F6FEE71A1EF8135200C1DE35 /* level.plv */,
......@@ -305,9 +311,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F6621DF61F12B82200F9E486 /* MotionInput.swift in Sources */,
F6E4AE451F0CF1DF004BFDBF /* Direction.swift in Sources */,
F6FEE7181EF80C1500C1DE35 /* StreamReader.swift in Sources */,
F6FEE7161EF80AD500C1DE35 /* Level.swift in Sources */,
F6621DF41F12B09800F9E486 /* TouchInputHandler.swift in Sources */,
F6BEB80B1EF7F99B00EDAA66 /* GameViewController.swift in Sources */,
F6BEB8071EF7F99B00EDAA66 /* AppDelegate.swift in Sources */,
F6E4AE431F0CEC6C004BFDBF /* Monster.swift in Sources */,
......
......@@ -22,17 +22,19 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
static let monsterCollision = 0b011 //3
static let pointsCollision = 0b100 //4
var isRotating: Bool = false
// MARK: - Overlay
var direction: Direction = .north
// overlay
var pointsLabel: SKLabelNode!
var lifeLabel: SKLabelNode!
var player: Player = Player()
// MARK: - Game Objects
var player: Player!
var monsters: [Monster] = []
// MARK: - Input Handler
private var touchInputHandler: TouchInputHandler!
private var motionInput: MotionInput?
override func viewDidLoad() {
super.viewDidLoad()
......@@ -42,6 +44,9 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
// create a new scene
scene = SCNScene(named: "art.scnassets/ship.scn")!
let pacman = scene.rootNode.childNode(withName: "Pacman", recursively: true)!
player = Player(node: pacman, scene: scene, level: level)
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
......@@ -50,42 +55,10 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
for (x, line) in level.data.enumerated() {
for (z, block) in line.enumerated() {
if block == .wall {
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(x * 5), y: 1, z:Float(z * 5))
node.name = "\(x) \(z)"
scene.rootNode.addChildNode(node)
} else if block == .blank {
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.position = SCNVector3(x: Float(x * 5), y: 1, z:Float(z * 5))
self.scene.rootNode.addChildNode(node)
}
}
}
let pacman = self.scene.rootNode.childNode(withName: "Pacman", recursively: true)!
let pacmanBox = SCNBox(width: 5, height: 2, length: 5, chamferRadius: 0)
pacmanBox.firstMaterial?.diffuse.contents = UIColor.clear
let boxNode = SCNNode(geometry: pacmanBox)
pacman.addChildNode(boxNode)
pacman.physicsBody = SCNPhysicsBody(type: .kinematic, shape: SCNPhysicsShape(geometry: pacmanBox, options: nil))
pacman.physicsBody?.categoryBitMask = GameViewController.pacmanCollision
pacman.physicsBody?.contactTestBitMask = GameViewController.wallCollision
pacman.physicsBody?.isAffectedByGravity = false
scene.physicsWorld.contactDelegate = self
level.createLevelEnviroment(scene: scene)
// // create and add a light to the scene
// let lightNode = SCNNode()
// lightNode.light = SCNLight()
......@@ -119,38 +92,14 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
scnView.backgroundColor = UIColor.black
// add a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
scnView.addGestureRecognizer(tapGesture)
touchInputHandler = TouchInputHandler(target: self, action: #selector(handleTap(_:)))
scnView.addGestureRecognizer(touchInputHandler)
self.motionInput = MotionInput(gameScene: self)
motionManager = CMMotionManager()
if (motionManager?.isAccelerometerAvailable)! {
motionManager?.accelerometerUpdateInterval = 0.1
motionManager?.startAccelerometerUpdates(to: OperationQueue.main, withHandler: { (data, error) in
let rotate = data!.acceleration.y
//print(rotate)
let pacman = self.scene.rootNode.childNode(withName: "Pacman", recursively: true)!
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)
pacman.runAction(action, completionHandler: {
self.isContact = false
})
self.isRotating = true
var directionVal = self.direction.rawValue + Int(direction)
if directionVal == 5 {
directionVal = 1
}
if directionVal == 0 {
directionVal = 4
}
self.direction = Direction(rawValue: directionVal)!
}
} else {
self.isRotating = false
}
})
motionManager?.startAccelerometerUpdates(to: OperationQueue.main, withHandler: motionInput!.handleMotionInput)
}
if (motionManager?.isDeviceMotionAvailable)! {
motionManager?.deviceMotionUpdateInterval = 0.1
......@@ -169,7 +118,7 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
})
}
for _ in 1...1 {
for _ in 1...10 {
let postion = level.nextFreeSpace()
let monster = Monster(position: SCNVector3(5 * postion.x, 1, 5 * postion.z), level: level, scene: scene)
monster.addToScene(rootScene: self.scene)
......@@ -191,8 +140,6 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
}
}
var isContact: Bool = false
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
if contact.nodeA.name ?? "" == "Monster" && contact.nodeB.name ?? "" == "Monster" {
return
......@@ -226,44 +173,22 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
contact.nodeB.removeFromParentNode()
}
}
if(contact.nodeA == pacman && contact.nodeB.physicsBody?.categoryBitMask == GameViewController.wallCollision) || (contact.nodeA.physicsBody?.categoryBitMask == GameViewController.wallCollision && contact.nodeB == pacman){
func block() {
if let box = contact.nodeA.geometry as? SCNBox {
box.firstMaterial?.diffuse.contents = UIColor.blue
}
if let box = contact.nodeB.geometry as? SCNBox {
box.firstMaterial?.diffuse.contents = UIColor.blue
}
isContact = true
}
if direction == .north {
if contact.contactNormal.x == 1.0 {
block()
}
} else if direction == .east {
if contact.contactNormal.z == -1.0 {
block()
}
} else if direction == .south {
if contact.contactNormal.x == -1.0 {
block()
}
} else if direction == .west {
if contact.contactNormal.z == 1.0 {
block()
}
}
}
}
private var lastTime: TimeInterval = 0
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
for monster in monsters {
monster.move()
}
if time - lastTime > 0.25 {
if touchInputHandler.isTouchDown {
player.move()
}
lastTime = time
}
}
func createOverlay() -> SKScene {
......@@ -283,20 +208,6 @@ class GameViewController: UIViewController, SKSceneDelegate ,SCNPhysicsContactDe
}
func handleTap(_ gestureRecognize: UIGestureRecognizer) {
if isContact {
return
}
let pacman = scene.rootNode.childNode(withName: "Pacman", recursively: true)!
if direction == .north {
pacman.position.x += 5
} else if direction == .east {
pacman.position.z -= 5
} else if direction == .south {
pacman.position.x -= 5
} else if direction == .west {
pacman.position.z += 5
}
}
override var shouldAutorotate: Bool {
......
......@@ -7,6 +7,7 @@
//
import Foundation
import SceneKit
class Level {
......@@ -44,6 +45,41 @@ class Level {
data = [[]]
}
func createLevelEnviroment(scene: SCNScene) {
for (x, line) in data.enumerated() {
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))
}
}
}
}
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)
}
private func addPointObject(toScene scene: SCNScene, at point: (x: Int, z: Int)) {
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.position = SCNVector3(x: Float(point.x * 5), y: 1, z:Float(point.z * 5))
scene.rootNode.addChildNode(node)
}
func nextFreeSpace() -> (x: Int, z: Int) {
while true {
let x = Int(arc4random_uniform(UInt32(data.count)))
......
//
// MotionInput.swift
// Pacman3D-iOS
//
// Created by Tobias on 09.07.17.
// Copyright © 2017 Tobias. All rights reserved.
//
import Foundation
import CoreMotion
import SceneKit
class MotionInput {
private let gameScene: GameViewController
private var isRotating = false
init(gameScene: GameViewController) {
self.gameScene = gameScene
}
func handleMotionInput(data: CMAccelerometerData?, error: Error?) -> Swift.Void {
let rotate = data!.acceleration.y
//print(rotate)
let pacman = gameScene.scene.rootNode.childNode(withName: "Pacman", recursively: true)!
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)
pacman.runAction(action, completionHandler: nil)
self.isRotating = true
var directionVal = gameScene.player.direction.rawValue - Int(direction)
if directionVal == 5 {
directionVal = 1
}
if directionVal == 0 {
directionVal = 4
}
gameScene.player.direction = Direction(rawValue: directionVal)!
}
} else {
self.isRotating = false
}
}
}
......@@ -7,9 +7,75 @@
//
import Foundation
import SceneKit
class Player {
var points: Int = 0
var life: Int = 3
private let level: Level
private let node: SCNNode
var direction: Direction = .north
var position: SCNVector3
init(node: SCNNode, scene: SCNScene, level: Level) {
self.node = node
self.position = node.position
self.level = level
let pacmanBox = SCNBox(width: 5, height: 2, length: 5, chamferRadius: 0)
pacmanBox.firstMaterial?.diffuse.contents = UIColor.clear
let boxNode = SCNNode(geometry: pacmanBox)
node.addChildNode(boxNode)
node.physicsBody = SCNPhysicsBody(type: .kinematic, shape: SCNPhysicsShape(geometry: pacmanBox, options: nil))
node.physicsBody?.categoryBitMask = GameViewController.pacmanCollision
node.physicsBody?.contactTestBitMask = GameViewController.wallCollision
node.physicsBody?.isAffectedByGravity = false
}
func move() {
print("\(direction)\t\(findFreeSpaces())")
if !findFreeSpaces().contains(direction) {
return
}
if direction == .north {
position.x += 5
} else if direction == .east {
position.z += 5
} else if direction == .south {
position.x -= 5
} else if direction == .west {
position.z -= 5
}
let action = SCNAction.move(to: position, duration: 0.25)
node.runAction(action, completionHandler: nil)
}
private func findFreeSpaces() -> [Direction] {
var directions: [Direction] = []
let x: Int = Int(position.x / 5)
let z: Int = Int(position.z / 5)
print("\(x) \(z)")
if level.data[x - 1][z] == .blank {
directions.append(.south)
}
if level.data[x][z - 1] == .blank {
directions.append(.west)
}
if level.data[x + 1][z] == .blank {
directions.append(.north)
}
if level.data[x][z + 1] == .blank {
directions.append(.east)
}
return directions
}
}
//
// InputHandler.swift
// Pacman3D-iOS
//
// Created by Tobias on 09.07.17.
// Copyright © 2017 Tobias. All rights reserved.
//
import UIKit
import UIKit.UIGestureRecognizerSubclass
import SceneKit
class TouchInputHandler: UIGestureRecognizer {
var isTouchDown: Bool = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
self.isTouchDown = true
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
self.isTouchDown = false
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment