Christopher
Christopher

Reputation: 45

Sprites show up in simulator, not on device

This simple project inserts a square sprite in the center of the field when you press the button, which calls the add() function below. In the simulator, when you add multiple sprites, it pushes the others out of the way, so when you have pressed it a bunch of times you get... screen shot from simulator, iphone 6, iOS 9.2, and this is the behavior I want.

But the same code running on my iphone, after adding the same number of sprites yields this... screen show from physical iphone 6, iOS 9.2

Here is the code from GameScene.swift:

import SpriteKit

class GameScene: SKScene {

override init(size: CGSize) {
    super.init(size:size) 
    self.physicsWorld.gravity = CGVectorMake(0, -1.0)
    let worldBorder = SKPhysicsBody(edgeLoopFromRect: self.frame)
    self.physicsBody = worldBorder
    self.physicsBody?.friction = 0.5 
}

func add()
{

    let sprite = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: 10, height: 10))
    sprite.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2)        
        sprite.physicsBody = SKPhysicsBody(circleOfRadius: 8)
        sprite.physicsBody?.friction = 0.0
        sprite.physicsBody?.affectedByGravity = false
        sprite.physicsBody?.restitution = 0.5
        sprite.physicsBody?.linearDamping = 0.5
    addChild(sprite)

}

required init?(coder aDecoder: NSCoder) 
   {
    super.init(coder: aDecoder)
   }
}

Where am I going wrong? And how to I get the behavior I want on the real iPhone?

Upvotes: 3

Views: 94

Answers (1)

Ben Kane
Ben Kane

Reputation: 10070

I'm not sure if which one is the desired behavior, but it does make sense that they wouldn't slide if you are stacking them literally right on top of each other. That being said, there is a way to get around this.

Keep in mind that nodes use floating point positioning, but of course they can only actually visibly be positioned by the pixel.

1 pixel would be 0.5 points on a 2x screen, and 0.33 points on 3x screen. With that in mind, you can use an offset of < 0.33 to get the physics bodies offset without it being visible to the user. Here's a little example:

class GameScene: SKScene {
    var xOffset: CGFloat = 0.05
    var yOffset: CGFloat = 0.3

    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
    }

    override init(size: CGSize) {
        super.init(size:size)
        self.physicsWorld.gravity = CGVectorMake(0, -1.0)
        let worldBorder = SKPhysicsBody(edgeLoopFromRect: self.frame)
        self.physicsBody = worldBorder
        self.physicsBody?.friction = 0.5
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        add()
        updateOffsets()
    }

    func add()
    {
        let sprite = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: 10, height: 10))
        sprite.position = CGPointMake((self.frame.size.width / 2) + xOffset, (self.frame.size.height / 2) + yOffset)
        sprite.physicsBody = SKPhysicsBody(circleOfRadius: 8)
        sprite.physicsBody?.friction = 0.0
        sprite.physicsBody?.affectedByGravity = false
        sprite.physicsBody?.restitution = 0.5
        sprite.physicsBody?.linearDamping = 0.5
        addChild(sprite)
    }

    private func updateOffsets() {
        xOffset = -xOffset
        yOffset = -yOffset
    }
}

Switching the offsets is the important part. If you don't do that, you'll have the same problem of stacking exactly on top of each other. The offsets I used get pretty close to the simulator behavior, but a few taps in you'll notice it's a little different. Hopefully you don't care about matching the exact same pattern you're getting in simulator. It's a very similar one with this code. If you do care, you'll notice changing the offsets will change the pattern.

Upvotes: 4

Related Questions