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?