Home > OS >  Why does a node's position change when a CGFloat is used instead of a numeric literal?
Why does a node's position change when a CGFloat is used instead of a numeric literal?

Time:10-14

Goal

I want to set the position of a child node in my game's scene using the position property of SKSpriteNode and pass an inline mathematical expression as the argument to the y parameter. The child node I'm adding is a subclass of SKSpriteNode and it has a custom Int property called yOffset. Ideally, I want to use the yOffset to shift the node's position.

What I Tried

Initially, I was hard-coding the offset as part of the argument to CGPoint, i.e. myNode.position = CGPoint(x: myNode.position.x, y: myNode.position.y - 100) and the node was being positioned in the scene as expected.

However, as soon as I changed to using yOffset, i.e. myNode.position = CGPoint(x: myNode.position.x, y: myNode.position.y - myNode.yOffset) I get a compiler error saying 'Cannot convert value of type 'Int' to expected argument type 'CGFloat''. To fix this, I changed myNode.yOffset to CGFloat(myNode.yOffset) and it compiled fine. However, the node was now nowhere to be found within the scene. The node count still shows that the node was added, but I have no idea where it is.

To avoid a cast to CGFloat, I also tried changing yOffset to be a Double instead of an Int. The code compiled fine, but the same problem arose and the node was nowhere to be found.

What I want to know

First, why is it that when a numeric literal such as 100 is used in the calculation, the code compiles and the node appears just fine, but when the instance property yOffset (which is also an Int) is used, it needs to be cast to CGFloat? Shouldn't it compile since it is an Int just like any numeric literal?

Second, why is it that the node's position does not behave as expected when yOffset is cast to CGFloat, as compared to using a numeric literal in the argument?

Is it anything to do with a conversion from point to pixels?

CodePudding user response:

CGFloat is, dependent on system architecture, either a Double or Float under the covers, and standard library floating-point types, such as Float and Double, conform to the ExpressibleByIntegerLiteral protocol. This means you can initialise a variable or constant of any of these types by assigning an integer literal and it will be "translated" to a CGFloat by the initialiser associated with the protocol. When you supply the integer literal in-line as y: myNode.position.y - 100 this is what is happening.

When you specify the offset property as an Int you can't then use this in a calculation that is expecting a CGFloat - as it's no longer a literal value the ExpressibleByIntegerLiteral initialiser cannot be used to convert it to a CGFloat. Hence you your initial error.

Without seeing the full code, as opposed to inline snippets, it's not clear why you should be getting the placement errors when you offset using the yOffset property. There's no obvious reason. Have you looked through the code with the debugger to check what is really happening, confirm that the actual property values are what you think they are, and what the position value of the sprite is?

  • Related