SKSpriteNode positioning math escapes me ?
More specifically, the positioning required for creating a UIBezierPath from a CGRect.
A very few short code snippets follow ...
roomWidth = UIScreen.main.bounds.width
roomHeight = UIScreen.main.bounds.height
// trackOffset = a constant
tracksWidth = roomWidth - 2*trackOffset // inset from screen edge
tracksHeight = 0.40*roomHeight - trackOffset
// the `SKSpriteNode` = myTracks
myTracks.anchorPoint = CGPoint(x: 0.5, y: 0.5)
tracksPosX = 0.0
tracksPosY = -roomHeight/2 + trackOffset + tracksHeight/2
myTracks.position = CGPoint(x: tracksPosX, y: tracksPosY)
Later, I create a UIBezierPath from my trackRect defined as follows:
trackRect = CGRect(x: tracksPosX - tracksWidth/2,
y: tracksPosY,
width: tracksWidth,
height: tracksHeight)
trainPath = UIBezierPath(ovalIn: trackRect)
But something is wrong with y: tracksPosY because with iOS, the origin is in the upper-left corner and the rectangle extends towards the lower-right corner.
Given this spec from Apple, shouldn't it read:
y: tracksPosY + tracksHeight/2?
We need to try and simplify things -- and take them step-by-step.
So, let's use a simple game scene, where we'll define a
rectand add aSKShapeNodewith a rectangle path, and aSKShapeNodewith an oval path:Looks like this:
and, as we know, y-axis is "inverted" with scene kit, so we have an origin of
80,80and positive values for width and height:If we use the same values to define the rect in a "normal" app, using
CAShapeLayers instead of scene kit nodes:we get this:
with non-inverted y-axis:
What may be confusing the issue is the fact that an inverted rectangle or oval doesn't look any different.
So, let's add an "arrow" bezier path shape:
Let's add that as another
CAShapeLayerin our "normal" app:and we get this (as expected):
If we then add that arrow bezier path as another
SKShapeNodein our scene kit app:we get this result:
and now it's pretty easy to see that the inverted y-axis also inverts the path(s) we've created.
Again, simplify what you're doing to make it easier to learn and understand what's going on. It also helps to add
print(...)statements, or Debug Breakpoints, to evaluate your calculations.Using the code you posted, if I set
trackOffset = 80.0and thenprint(trackRect)at the end, I get (on an iPhone 15 Pro):which is almost certainly not the rectangle origin you are going for.
Full code for each example...
"normal" app with
CAShapeLayer:Full code for each example...
scene kit app with
SKShapeNode: