From 616cda232a470b860c424f525763a377bed9c21e Mon Sep 17 00:00:00 2001 From: tobias <thinkdifferent055@gmail.com> Date: Mon, 19 Jun 2017 16:42:34 +0200 Subject: [PATCH] Add level file loading, add walls to scene --- Pacman3D-iOS.xcodeproj/project.pbxproj | 31 +++++++++ Pacman3D-iOS/GameViewController.swift | 15 ++++- Pacman3D-iOS/Level.swift | 46 +++++++++++++ Pacman3D-iOS/StreamReader.swift | 89 +++++++++++++++++++++++++ Pacman3D-iOS/art.scnassets/ship.scn | Bin 38162 -> 38162 bytes Pacman3D-iOS/level.plv | 18 +++++ 6 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 Pacman3D-iOS/Level.swift create mode 100644 Pacman3D-iOS/StreamReader.swift create mode 100644 Pacman3D-iOS/level.plv diff --git a/Pacman3D-iOS.xcodeproj/project.pbxproj b/Pacman3D-iOS.xcodeproj/project.pbxproj index cf227c7..d723f1c 100644 --- a/Pacman3D-iOS.xcodeproj/project.pbxproj +++ b/Pacman3D-iOS.xcodeproj/project.pbxproj @@ -15,6 +15,9 @@ F6BEB8131EF7F99B00EDAA66 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F6BEB8111EF7F99B00EDAA66 /* LaunchScreen.storyboard */; }; F6BEB81E1EF7F99B00EDAA66 /* Pacman3D_iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BEB81D1EF7F99B00EDAA66 /* Pacman3D_iOSTests.swift */; }; F6BEB8291EF7F99C00EDAA66 /* Pacman3D_iOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6BEB8281EF7F99C00EDAA66 /* Pacman3D_iOSUITests.swift */; }; + F6FEE7161EF80AD500C1DE35 /* Level.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6FEE7151EF80AD500C1DE35 /* Level.swift */; }; + F6FEE7181EF80C1500C1DE35 /* StreamReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6FEE7171EF80C1500C1DE35 /* StreamReader.swift */; }; + F6FEE71B1EF8135200C1DE35 /* level.plv in Resources */ = {isa = PBXBuildFile; fileRef = F6FEE71A1EF8135200C1DE35 /* level.plv */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,6 +52,9 @@ F6BEB8241EF7F99C00EDAA66 /* Pacman3D-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Pacman3D-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; F6BEB8281EF7F99C00EDAA66 /* Pacman3D_iOSUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pacman3D_iOSUITests.swift; sourceTree = "<group>"; }; F6BEB82A1EF7F99C00EDAA66 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + F6FEE7151EF80AD500C1DE35 /* Level.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Level.swift; sourceTree = "<group>"; }; + F6FEE7171EF80C1500C1DE35 /* StreamReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StreamReader.swift; sourceTree = "<group>"; }; + F6FEE71A1EF8135200C1DE35 /* level.plv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = level.plv; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -99,6 +105,8 @@ F6BEB8051EF7F99B00EDAA66 /* Pacman3D-iOS */ = { isa = PBXGroup; children = ( + F6FEE7141EF80AB900C1DE35 /* Level */, + F6FEE7191EF80C1900C1DE35 /* Uilts */, F6BEB8061EF7F99B00EDAA66 /* AppDelegate.swift */, F6BEB8081EF7F99B00EDAA66 /* art.scnassets */, F6BEB80A1EF7F99B00EDAA66 /* GameViewController.swift */, @@ -106,6 +114,7 @@ F6BEB80F1EF7F99B00EDAA66 /* Assets.xcassets */, F6BEB8111EF7F99B00EDAA66 /* LaunchScreen.storyboard */, F6BEB8141EF7F99B00EDAA66 /* Info.plist */, + F6FEE71A1EF8135200C1DE35 /* level.plv */, ); path = "Pacman3D-iOS"; sourceTree = "<group>"; @@ -128,6 +137,22 @@ path = "Pacman3D-iOSUITests"; sourceTree = "<group>"; }; + F6FEE7141EF80AB900C1DE35 /* Level */ = { + isa = PBXGroup; + children = ( + F6FEE7151EF80AD500C1DE35 /* Level.swift */, + ); + name = Level; + sourceTree = "<group>"; + }; + F6FEE7191EF80C1900C1DE35 /* Uilts */ = { + isa = PBXGroup; + children = ( + F6FEE7171EF80C1500C1DE35 /* StreamReader.swift */, + ); + name = Uilts; + sourceTree = "<group>"; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -242,6 +267,7 @@ F6BEB8131EF7F99B00EDAA66 /* LaunchScreen.storyboard in Resources */, F6BEB8101EF7F99B00EDAA66 /* Assets.xcassets in Resources */, F6BEB80E1EF7F99B00EDAA66 /* Main.storyboard in Resources */, + F6FEE71B1EF8135200C1DE35 /* level.plv in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -266,6 +292,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F6FEE7181EF80C1500C1DE35 /* StreamReader.swift in Sources */, + F6FEE7161EF80AD500C1DE35 /* Level.swift in Sources */, F6BEB80B1EF7F99B00EDAA66 /* GameViewController.swift in Sources */, F6BEB8071EF7F99B00EDAA66 /* AppDelegate.swift in Sources */, ); @@ -520,6 +548,7 @@ F6BEB82F1EF7F99C00EDAA66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; F6BEB8301EF7F99C00EDAA66 /* Build configuration list for PBXNativeTarget "Pacman3D-iOSTests" */ = { isa = XCConfigurationList; @@ -528,6 +557,7 @@ F6BEB8321EF7F99C00EDAA66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; F6BEB8331EF7F99C00EDAA66 /* Build configuration list for PBXNativeTarget "Pacman3D-iOSUITests" */ = { isa = XCConfigurationList; @@ -536,6 +566,7 @@ F6BEB8351EF7F99C00EDAA66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/Pacman3D-iOS/GameViewController.swift b/Pacman3D-iOS/GameViewController.swift index bd6726c..bc8f7fe 100644 --- a/Pacman3D-iOS/GameViewController.swift +++ b/Pacman3D-iOS/GameViewController.swift @@ -15,6 +15,8 @@ class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + let level = Level(named: "level") + // create a new scene let scene = SCNScene(named: "art.scnassets/ship.scn")! @@ -26,6 +28,17 @@ class GameViewController: UIViewController { // place the camera cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) + for (y, line) in level.data.enumerated() { + for (x, block) in line.enumerated() { + if block == .wall { + let box = SCNBox(width: 5, height: 5, length: 5, chamferRadius: 0) + let node = SCNNode(geometry: box) + node.position = SCNVector3(x: Float(x * 5), y: 2.5, z:Float(y * 5)) + scene.rootNode.addChildNode(node) + } + } + } + // // create and add a light to the scene // let lightNode = SCNNode() // lightNode.light = SCNLight() @@ -47,7 +60,7 @@ class GameViewController: UIViewController { scnView.scene = scene // allows the user to manipulate the camera - scnView.allowsCameraControl = false + scnView.allowsCameraControl = true // show statistics such as fps and timing information scnView.showsStatistics = true diff --git a/Pacman3D-iOS/Level.swift b/Pacman3D-iOS/Level.swift new file mode 100644 index 0000000..7152595 --- /dev/null +++ b/Pacman3D-iOS/Level.swift @@ -0,0 +1,46 @@ +// +// Level.swift +// Pacman3D-iOS +// +// Created by Tobias on 19.06.17. +// Copyright © 2017 Tobias. All rights reserved. +// + +import Foundation + +class Level { + + enum TileType { + case wall + case blank + } + + let data: [[TileType]] + + init(named: String) { + if let path = Bundle.main.path(forResource: named, ofType: "plv") { + if let aStreamReader = StreamReader(path: path, delimiter: "\n") { + defer { + aStreamReader.close() + } + + var tempLines: [[TileType]] = [] + while let line = aStreamReader.nextLine() { + var tempLine: [TileType] = [] + for index in line.characters.indices { + let c = line[index] + if c == "w" { + tempLine.append(TileType.blank) + } else if c == "s" { + tempLine.append(TileType.wall) + } + } + tempLines.append(tempLine) + } + self.data = tempLines + return + } + } + data = [[]] + } +} diff --git a/Pacman3D-iOS/StreamReader.swift b/Pacman3D-iOS/StreamReader.swift new file mode 100644 index 0000000..9db2312 --- /dev/null +++ b/Pacman3D-iOS/StreamReader.swift @@ -0,0 +1,89 @@ +// +// StreamReader.swift +// Pacman3D-iOS +// +// Created by Tobias on 19.06.17. +// Copyright © 2017 Tobias. All rights reserved. +// + +import Foundation + +class StreamReader { + + let encoding: String.Encoding + let chunkSize: Int + + var fileHandle: FileHandle! + let buffer: NSMutableData! + let delimData: NSData! + var atEof: Bool = false + + init?(path: String, delimiter: String = "\n", encoding : String.Encoding = String.Encoding.utf8, chunkSize : Int = 4096) { + self.chunkSize = chunkSize + self.encoding = encoding + + if let fileHandle = FileHandle(forReadingAtPath: path), let delimData = delimiter.data(using: encoding), let buffer = NSMutableData(capacity: chunkSize) { + self.fileHandle = fileHandle + self.delimData = delimData as NSData + self.buffer = buffer + } else { + self.fileHandle = nil + self.delimData = nil + self.buffer = nil + return nil + } + } + + deinit { + self.close() + } + + /// Return next line, or nil on EOF. + func nextLine() -> String? { + precondition(fileHandle != nil, "Attempt to read from closed file") + + if atEof { + return nil + } + + // Read data chunks from file until a line delimiter is found: + var range = buffer.range(of: delimData as Data, options: [], in: NSMakeRange(0, buffer.length)) + while range.location == NSNotFound { + let tmpData = fileHandle.readData(ofLength: chunkSize) + if tmpData.count == 0 { + // EOF or read error. + atEof = true + if buffer.length > 0 { + // Buffer contains last line in file (not terminated by delimiter). + let line = String(data: buffer as Data, encoding: encoding) + buffer.length = 0 + return line + } + // No more lines. + return nil + } + buffer.append(tmpData) + range = buffer.range(of: delimData as Data, options: [], in: NSMakeRange(0, buffer.length)) + } + + // Convert complete line (excluding the delimiter) to a string: + let line = String(data: buffer.subdata(with: NSMakeRange(0, range.location)), encoding: encoding) + // Remove line (and the delimiter) from the buffer: + buffer.replaceBytes(in: NSMakeRange(0, range.location + range.length), withBytes: nil, length: 0) + + return line as String? + } + + /// Start reading from the beginning of file. + func rewind() -> Void { + fileHandle.seek(toFileOffset: 0) + buffer.length = 0 + atEof = false + } + + /// Close the underlying file. No reading must be done after calling this method. + func close() -> Void { + fileHandle?.closeFile() + fileHandle = nil + } +} diff --git a/Pacman3D-iOS/art.scnassets/ship.scn b/Pacman3D-iOS/art.scnassets/ship.scn index 676363d0e3cc356b028a3d77a92a394220005b37..e0ccee6004c3b3af27b8977878841a81cd6e3318 100644 GIT binary patch delta 25 hcmbQVifPg+rVZ0rxE44R+Mcp!U|8U=c>zn&1OR`V384T0 delta 25 hcmbQVifPg+rVZ0rxEL4;ZBN-VFfcG|Ucgc`0RU{<2jKt! diff --git a/Pacman3D-iOS/level.plv b/Pacman3D-iOS/level.plv new file mode 100644 index 0000000..a67cdea --- /dev/null +++ b/Pacman3D-iOS/level.plv @@ -0,0 +1,18 @@ +ssssssssssssssssssss +swwwwwwwwwwwwwwwwwws +swssssswsssswsswwsws +swswwwwwwwsswsssssws +swswssssswsswwwwwwws +swswssswwwsswsssssws +swswssswsssswwswwwws +swswswwwssssswswssws +swwwsswwwwwwwwwwwwws +swswssssswsssswswsws +swswssssswwwsswswsws +swswwwwwwwswsswwwsws +swsssswswsswwswsssws +swwwwswswwsswswsssws +swsswswswwwwwswsssws +swsswswssssssswsssws +swwwwwwwwwwwwwwwwwws +ssssssssssssssssssss \ No newline at end of file -- GitLab