Created
May 10, 2023 20:36
-
-
Save rjhoover/063328fa1a727f3e647312652652c1a7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SpriteKit | |
struct Level { | |
enum CollisionTypes: UInt32 { | |
case player = 1 | |
case wall = 2 | |
case star = 4 | |
case vortex = 8 | |
case teleport = 16 | |
case finish = 32 | |
} | |
var levelLabel: SKLabelNode! | |
var levelFileName = "level1.txt" | |
var maxLevels = 9 | |
var levelNodesArray = [SKSpriteNode]() | |
var level = 1 { | |
didSet { | |
levelLabel.text = "Level: \(level)" | |
levelFileName = "level\(level).txt" | |
} | |
} | |
var isLevelFinished = false | |
let wallImageName = "block" | |
let vortexImageName = "vortex" | |
let starImageName = "star" | |
let teleportImageName = "teleport" | |
let finishImageName = "finish" | |
let nextLevelLabelName = "nextLevel" | |
var teleportNodes: [String: SKSpriteNode?] = [:] | |
var teleportStartNode: SKSpriteNode! | |
var teleportEndNode: SKSpriteNode! | |
var startNodeKey = "teleportStart" | |
var endNodeKey = "teleportEnd" | |
var isSecondPass: Bool = false | |
let playerBallSize = 64 | |
func loadLevelFile() -> [String] { | |
print("start loading level with \(levelFileName)") | |
guard let levelURL = Bundle.main.url(forResource: levelFileName, withExtension: nil) else { | |
fatalError("Could not find \(levelFileName) in the app bundle") | |
} | |
guard let levelString = try? String(contentsOf: levelURL) else { | |
fatalError("Failed to load \(levelFileName) from the app bundle") | |
} | |
return levelString.components(separatedBy: "\n") | |
} | |
mutating func displayLevel(_ lines: [String]) { | |
print("in displayLevel, level = \(level)") | |
for (row, line) in lines.reversed().enumerated() { | |
for (column, letter) in line.enumerated() { | |
let position = CGPoint(x: (playerBallSize * column) + (playerBallSize / 2), y: (playerBallSize * row) + (playerBallSize / 2)) | |
switch letter { | |
case "x": | |
loadWall(at: position) | |
case "v": | |
loadVortex(at: position) | |
case "s": | |
loadStar(at: position) | |
case "t": | |
loadTeleport(at: position) | |
case "f": | |
loadFinish(at: position) | |
case " ": | |
let _ = "foo" | |
// nop | |
default: | |
fatalError("Unknown level symbol found: \(letter) at row \(row), col \(column) - Level file is invalid") | |
} | |
} | |
} | |
print("end displayLevel") | |
} | |
mutating func loadWall(at position: CGPoint) { | |
let node = SKSpriteNode(imageNamed: wallImageName) | |
node.name = wallImageName | |
node.position = position | |
node.zPosition = 0 | |
node.physicsBody = SKPhysicsBody(rectangleOf: node.size) | |
node.physicsBody?.isDynamic = false | |
node.physicsBody?.categoryBitMask = CollisionTypes.wall.rawValue | |
addChild(node) | |
levelNodesArray.insert(node, at: 0) | |
} | |
mutating func loadVortex(at position: CGPoint) { | |
let node = SKSpriteNode(imageNamed: vortexImageName) | |
node.name = vortexImageName | |
node.position = position | |
node.zPosition = 0 | |
node.run(SKAction.repeatForever(SKAction.rotate(byAngle: .pi, duration: 1))) | |
node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2) | |
node.physicsBody?.isDynamic = false | |
node.physicsBody?.categoryBitMask = CollisionTypes.vortex.rawValue | |
node.physicsBody?.contactTestBitMask = CollisionTypes.player.rawValue | |
node.physicsBody?.collisionBitMask = 0 | |
addChild(node) | |
levelNodesArray.insert(node, at: 0) | |
} | |
mutating func loadStar(at position: CGPoint) { | |
let node = SKSpriteNode(imageNamed: starImageName) | |
node.name = starImageName | |
node.position = position | |
node.zPosition = 0 | |
node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2) | |
node.physicsBody?.isDynamic = false | |
node.physicsBody?.categoryBitMask = CollisionTypes.star.rawValue | |
node.physicsBody?.contactTestBitMask = CollisionTypes.player.rawValue | |
node.physicsBody?.collisionBitMask = 0 | |
addChild(node) | |
levelNodesArray.insert(node, at: 0) | |
} | |
mutating func loadFinish(at position: CGPoint) { | |
let node = SKSpriteNode(imageNamed: finishImageName) | |
node.name = finishImageName | |
node.position = position | |
node.zPosition = 0 | |
node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2) | |
node.physicsBody?.isDynamic = false | |
node.physicsBody?.categoryBitMask = CollisionTypes.finish.rawValue | |
node.physicsBody?.contactTestBitMask = CollisionTypes.player.rawValue | |
node.physicsBody?.collisionBitMask = 0 | |
addChild(node) | |
levelNodesArray.insert(node, at: 0) | |
} | |
mutating func loadTeleport(at position: CGPoint) { | |
let node = SKSpriteNode(imageNamed: teleportImageName) | |
node.name = teleportImageName // default name | |
node.position = position | |
node.zPosition = 0 | |
let scaleDown = SKAction.scale(to: 0.7, duration: 0.75) | |
let scaleUp = SKAction.scale(to: 1.0, duration: 0.75) | |
let sequence = SKAction.sequence([scaleDown, scaleUp]) | |
node.run(SKAction.repeatForever(sequence)) | |
node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2) | |
node.physicsBody?.isDynamic = false | |
node.physicsBody?.categoryBitMask = CollisionTypes.teleport.rawValue | |
node.physicsBody?.contactTestBitMask = CollisionTypes.player.rawValue | |
node.physicsBody?.collisionBitMask = 0 | |
if teleportNodes[startNodeKey] != nil && isSecondPass { | |
node.name = endNodeKey | |
teleportNodes[endNodeKey] = node | |
addChild(node) | |
levelNodesArray.insert(node, at: 0) | |
} else { | |
print(" teleportNodes[startNodeKey] is nil or isSecondPass is false -- not end node scenario") | |
} | |
if teleportNodes[startNodeKey] == nil && isSecondPass == false { | |
node.name = startNodeKey | |
teleportNodes[startNodeKey] = node | |
isSecondPass = true | |
addChild(node) | |
levelNodesArray.insert(node, at: 0) | |
} else { | |
print(" start node already exists or isSecondPass is true - not start node scenario") | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In the methods:
Each method creates a new SKSpriteNode, sets some properties for the node, then tries calls addNode() on the node.
I get a compile-time error on all the 'addChild()' of "Cannot find 'addChild' in scope"
I can't figure out why I'm getting the error.