2

Using SpriteKit, Swift 2, Xcode

I'm trying to change one of my Node's size after it has been called even if it isn't unique (Theres a bunch of them).

In less confusing terms I'm trying to change a Node's size without doing it in the initial declaration. This is what I have tried:

self.childNodeWithName("player")?.size.width = 10

However this doesn't work since childNodeWithName returns a Node and not a SKSpriteNode. Since Nodes have no access to "size," this solution doesn't work. I've also tried using

self.childNodeWithName("player")?.setScale(0.5)

Now the problem with this is that I cannot reference this as a number. I'm trying to continuously cut its size in half every time I call this, but I also need to be able to reference its size as a number. To my knowledge setScale doesn't offer this capability.

Any Ideas? Thanks!

Marshall D
  • 454
  • 3
  • 20

1 Answers1

1

Sure, you could set a variable to that node. Also cast it to an SKSpriteNode. Then you can do anything an SKSpriteNode can. Here's a simple test case:

let aNode = SKSpriteNode(color: UIColor.blue, size: CGSize(width: 10, height: 10))
aNode.name = "test"
aNode.zPosition = 10
addChild(aNode)

let theNode = childNodeWithName("test") as! SKSpriteNode
theNode.setScale(40)
print(theNode.size) // prints (400, 400)

A solution if you need the physics body to change with it:

let player = childNodeWithName("player") as! SKSpriteNode
let originalArea: CGFloat = player.size.width*player.size.width
let newArea: CGFloat = originalArea / 2.0
let newLength: CGFloat = CGFloat(sqrt(Double(newSize)))

var newScale = newLength/player.size.width
newScale *= player.xScale
player.setScale(newScale)

This is just some math for finding the ratio between the new desired size (In your case, to cut the area in half), and then it adjusts the new scale by this value. When using setScale the physics body changes with it.

Chris Slowik
  • 2,859
  • 1
  • 14
  • 27
  • Great this is exactly what I was looking for! Now in my code I'm able to change a node's size. However, its physics body does not change with it. I tried using `player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)` but this resets all of the physicsBody's attributes which I really need to avoid. Anyway to do this? – Marshall D Jan 29 '16 at 21:50
  • Oof. that's a fun one. You can't set physics body size, or scale it.. that's correct. My guess is because it would make collision detection a quagmire. Off the top of my head I can't picture how to do this but i'll think about it. This might help: http://stackoverflow.com/questions/28448629/physics-body-size-not-changing-with-skspritenode-size-change-in-touch-moved-meth?rq=1 – Chris Slowik Jan 29 '16 at 22:10
  • Yea I was worried that would be the answer. I'm thinking I could use the setScale and just put it through and algorithm that gets me the desired result. I.E: I take the desired size, divide it by the current size, and then use that as the scale. I think that should give me the same result (especially since I was more concerned about referencing the size rather than just changing it) – Marshall D Jan 29 '16 at 22:41
  • Ok I've done it with: `player.setScale(CGFloat((player.size.width*player.size.height)/2)/(player.size.width*player.size.height))` But it only works once since the scale changes and not the player size. It would get too difficult to then begin recalculating sizes based on scales and saving those for each node however.. – Marshall D Jan 29 '16 at 22:56
  • Ok after some more tinkering I think that the size does actually change... But this doesn't make much sense, since it doesn't work. To fix the last problem I tried multiplying the parameters within the setScale by its current scale but this still didn't work. – Marshall D Jan 29 '16 at 23:10
  • 1
    *Face Palms* I had a leftover line that just set the scale to .5... I'm going to add my solution to your answer – Marshall D Jan 30 '16 at 16:21