Reputation: 121
Okay so i am trying to learn how to create a game... I want a node to be the camera, so that i can move it and center the view to my player node. When i subclass (i don't know if it's right to say that i subclass it, maybe not...) the player node to the world node, the application crashes. When player is simply a node, a "subclass" of GameScene (and not of the "world" node), it goes "fine", i mean i can move my player (yeah but the camera doesn't work).
so here is my code (few // lines in italian but not relevant)
import SpriteKit
class GameScene: SKScene {
var world: SKNode? //root node! ogni altro nodo del world dev'essere sottoclasse di questo
var overlay: SKNode? //node per l'HUD e altre cose che devono stare sopra al world
var camera: SKNode? //camera node. muovo questo per cambiare le zone visibili
//world sprites
var player: SKSpriteNode!
override func didMoveToView(view: SKView) {
self.anchorPoint = CGPoint(x: 0, y: 0) //center the scene's anchor point at the center of the screen
//world setup
self.world = SKNode()
self.world!.name = "world"
self.addChild(world!)
//camera setup
self.camera = SKNode()
self.camera!.name = "camera"
self.world!.addChild(self.camera!)
//UI setup
self.overlay = SKNode()
self.overlay?.zPosition = 10
self.overlay?.name = "overlay"
addChild(self.overlay!)
player = world!.childNodeWithName("player") as SKSpriteNode!
}
var directionToMove = CGVectorMake(0, 0)
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
directionToMove = CGVectorMake((directionToMove.dx + (location.x - player!.position.x)), (directionToMove.dy + (location.y - player!.position.y)))
}
}
override func update(currentTime: CFTimeInterval) {
//*these both print the string*
if player == nil {
println("player is nil")
}
if player?.physicsBody == nil {
println("player.physicsBody is nil")
}
//*here it crashes*
player!.physicsBody!.applyForce(directionToMove)
}
override func didFinishUpdate() {
if self.camera != nil {
self.centerOnNode(self.camera!)
}
}
func centerOnNode(node: SKNode) {
let cameraPositionInTheScene: CGPoint = node.scene!.convertPoint(node.position, fromNode: node.parent!)
node.parent!.position = CGPoint(x: node.parent!.position.x - cameraPositionInTheScene.x, y: node.parent!.position.y - cameraPositionInTheScene.y)
}
}
thanks in advance : )
Upvotes: 0
Views: 709
Reputation: 12773
Your player is nil
because you are accessing it from the world
node, which is empty. By default, the player is a child of scene. You can change this in the scene editor by setting the node's parent property (see Figure 1).
Figure 1. SpriteKit Scene Editor's Property Inspector
I suggest you make the following changes:
world
, overlay
, and camera
nodes in the scene editor and access them with childNodeWithName
didFinishUpdate
will automatically adjust the world to center the camera in the scene. You can add a physics body to the camera and move it by applying a force/impulse or by setting its velocity.If you add the other sprites to the world, they will move appropriately when you adjust the world's position to center the camera. You will then need to move the other sprites relative to the world. The scene is just a window to view a portion of the world at a time.
Upvotes: 1
Reputation: 8130
I'm not sure why you are using optionals everywhere. You only need to use an optional when a variable might be nil. Are your world
, overlay
, and camera
ever going to be nil? I would guess probably not.
To answer your question:
Youre trying to get player
from world
. I dont see that youve added any player
sprite to the world
node. It doesnt find it, and youre unwrapping an optional that isnt there. So you get an error.
You're going to have a lot more luck if you only use optionals when you need them. If you use them for everything youre going to add unnecessary complexity to your code.
Optionals should be the exception, not the rule. I could try to fix your code for you, but I'm not sure what you intended the player
sprite to be?
Follow simple tutorials and start small. Things will make more and more sense over time.
Upvotes: 0