I made a platform game and pointed the camera on the main node Player.
I have gone through the Apple document which can be found here: Apple
There are around 6 Platforms, with self.frame.size.height / 4.5
space between them, which should respawn everytime they are under dy = -15
on the top of the screen again, to make it an infinite loop.
I got a the Player node, which gets an impulse everytime the screen is touched (Player jumps up and down). The whole game does only move on the y-Axis
.
The camera I created is focused on the Player, everytime the Player jumps the platforms move down and the Player moves up. However, this is only the View, and not the real world's position. That means, the given positions in SpawnPlatforms
are always the same, because they dont move, only the View that is stick to the Player moves up and down.
I want to have the Camera on my Player Node, which moves on the y-Axis, and while it goes further up, the Platforms should also move down, at the moment only the view changes and I can't work with the Updated:Method to respawn the Platforms. How can I change that?
Edit: I got my Code working with the update in the Update:Method
, but this still doesn't answer my initial Question, how to move the whole world with the Camera, not only the Camera.
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self
self.anchorPoint = CGPoint(x: 0, y: 0.30)
backgroundColor = SKColor(red: 81.0/255.0, green: 192.0/255.0, blue: 201.0/255.0, alpha: 1.0)
self.World = SKNode()
self.World.name = "World"
addChild(World)
self.Camera = SKNode()
self.Camera.name = "Camera"
self.World.addChild(Camera)
SpawnPlatforms()
SpawnPlayer()
}
func SpawnPlatforms() {
Platform0 = SKSpriteNode (color: SKColor.greenColor(), size: CGSize(width: self.frame.size.width , height: 25))
Platform0.position = CGPoint(x: self.frame.size.width / 2, y: -36)
Platform0.zPosition = 1
Platform0.physicsBody = SKPhysicsBody(rectangleOfSize:Platform0.size)
Platform0.physicsBody?.dynamic = false
Platform0.physicsBody?.allowsRotation = false
Platform0.physicsBody?.restitution = 0
Platform0.physicsBody?.usesPreciseCollisionDetection = true
Platform0.physicsBody?.categoryBitMask = Platform0Category
Platform0.physicsBody?.collisionBitMask = PlayerCategory
Platform0.physicsBody?.contactTestBitMask = PlayerCategory
World.addChild(Platform0)
....//Same code for the other Platforms1-5
}
func SpawnPlayer(){
Player = SKSpriteNode (imageNamed: "Image.png")
Player.size = CGSize(width: 64, height: 64)
Player.position = CGPoint(x: self.frame.size.width / 2, y: 0)
Player.zPosition = 2
Player.physicsBody = SKPhysicsBody(rectangleOfSize:CGSize(width: 35, height: 50))
Player.physicsBody?.dynamic = true
Player.physicsBody?.allowsRotation = false
Player.physicsBody?.restitution = 0
Player.physicsBody?.usesPreciseCollisionDetection = true
Player.physicsBody?.categoryBitMask = PlayerCategory
Player.physicsBody?.collisionBitMask = Platform0Category
Player.physicsBody?.contactTestBitMask = Platform0Category | Platform1Category | Platform2Category | Platform3Category | Platform4Category | Platform5Category
World.addChild(Player)
}
override func didSimulatePhysics() {
Camera.position = CGPoint(x: Player.position.x, y: Player.position.y)
self.centerOnNode(Camera!)
}
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = Camera.scene!.convertPoint(Camera.position, fromNode: World)
World.runAction(SKAction.moveTo(CGPoint(x:World.position.x , y:World.position.y - cameraPositionInScene.y), duration: 1.0))
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if(Player.position.y > (Platform3.position.y + 30) && Player.position.y < Platform4.position.y){
Platform1.position = CGPointMake(self.frame.size.width / 2, Platform6.position.y + self.frame.size.height / 4.5)
Platform1.color = SKColor.redColor()
}
...//Same code for the other Platforms1-5
}
Create a SKNode
and let's call it map. Add the map as a child of this scene. You add every other game node as a child of this map (platforms, player, etc).
Then, instead of moving node.parent, you move the map. This will cause that the platforms has always the same position even though you move the camera.
Plus, you can add game menus to the scene and they will not move, but the map will.
For example, the next code will move the map in update:
method with a linear velocity:
kScrollScenarioFactor
may be like 200.f
-(void)update:(CFTimeInterval)currentTime {
//Calculating time for realistic scroll speed
float scrollTime = currentTime - self.lastTime;
self.lastTime = currentTime;
self.map.position = CGPointMake(map.position.x - (scrollTime * self.kScrollScenarioFactor), map.position.y);
}
Or if you want to move the map depending on player inside update:
method, you can look at this approach:
-(void)update:(CFTimeInterval)currentTime {
//Calculating playerPosition difference
float diffX = self.lastPlayerPosition.x - self.player.position.x;
float diffY = self.lastPlayerPosition.y - self.player.position.y;
self.lastPlayerPosition = self.player.position;
//Updating map position
self.map.position = CGPointMake(map.position.x + diffX, map.position.y + diffY);
}
If you have a scrolling background then make three layers in the game:
Now, as per my understanding of your problem, all your platforms have predefined positions in the scene, which do not change. Only the position of the player node changes and hence you want the camera node to follow the player and move the world with it. If this is the case then you could try this:
SKNode’s have no visual content, but do have a position in the scene. This means you can move the node around and its child nodes will move with it
Initially add the following class properties -
var backgroundNode: SKNode!
var foregroundNode: SKNode!
var hudNode: SKNode!
var player: SKNode!
var platformType: PlatformType!
//Add Background node
func createBackgroundNode() -> SKNode {
let backgroundNode = SKNode()
let node = SKSpriteNode(imageNamed:"")
node.position = CGPoint(x: xPosition , y: yPosition)
backgroundNode.addChild(node)
return backgroundNode
}
Then call this in Game Scene
backgroundNode = createBackgroundNode()
addChild(backgroundNode)
Now to Add the player:
func createPlayer() -> SKNode {
let playerNode = SKNode()
playerNode.position = CGPoint(x: x.position, y: y.position)
let sprite = SKSpriteNode(imageNamed: "Player")
playerNode.addChild(sprite)
return playerNode
}
In order to add the player, we will create the foreground layer and then add it to it. Put this just below where you added backgroundNode.
foregroundNode = SKNode()
addChild(foregroundNode)
player = createPlayer()
foregroundNode.addChild(player)
Finally, the platform that you want to add, you can add it as:
func createPlatformAtPosition(position: CGPoint) -> PlatformNode {
let node = PlatformNode()
let thePosition = CGPoint(x: position.x, y: position.y)
node.position = thePosition
node.name = "NODE_PLATFORM"
var sprite: SKSpriteNode
sprite = SKSpriteNode(imageNamed: "Platform")
node.addChild(sprite)
return node
}
Lastly add this to Game Scene under foregroundNode.addChild(player)
let platform = createPlatformAtPosition(CGPoint(x: 300, y: 270)
foregroundNode.addChild(platform)
Hope this helps you a little.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With