4

As we know SKScene's origin is at bottom-left.

But i try a simple level loading from a file which contains a matrix of 0 and 1. While 0 is nothing, 1 means a wall (simple rectangle).

As the content of the file obviously goes from top-left to bottom-right, i would like to draw from top-left on the scene.

But my first character from file is drawn on bottom-left on the scene. I tried setting the scene's yScale to -1 hoping its inverting the y-axis, but that didn't work.

What is the cleanest way so on this SKScene i always start drawing from top-left? I still want to keep my anchorPoint at 0.5,0.5.

So drawing from top-left would be located at x=-widthOfScreen/2 and y=heightOfScreen/2

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
NovumCoder
  • 4,349
  • 9
  • 43
  • 58
  • Take a look to this answer http://stackoverflow.com/a/20734093/1894067 – Alessandro Ornano Aug 03 '16 at 06:15
  • nope, as i wrote yScale on SKScene does not work. Getting msg on console: SKScene: Setting the scale of a SKScene has no effect. – NovumCoder Aug 03 '16 at 18:42
  • Interesting but without see your code i think guys in answer cannot better understand how to help you, try to add some code to reply this issue – Alessandro Ornano Aug 03 '16 at 18:50
  • You can use an intermediate node that has a yScale of -1 to achieve this, but if you want your drawings to match the coordinate system of everything else in your scene, your best bet is to just draw your walls in the negative direction instead of the positive direction and not try to transform everything. It would keep things simpler in the long run, I'd wager, because it's probably a single minus sign somewhere in your level loading code compared to having to deal with an extra layer of transformations throughout your code. – cc. Aug 04 '16 at 22:26

3 Answers3

6

I'm not sure if this is what you're going for, but if you just want to change the coordinate system around what you can do is create an extension for CGPoint, something like

//CGPoint+SpriteKit.swift
extension CGPoint {
    func flipCoordinates() -> CGPoint {
        return CGPoint(x: x, y: UIScreen.mainScreen().bounds.height - y)
    }
}

I think this should work, since your anchor point is (0.5, 0.5)

Hayden Holligan
  • 1,822
  • 2
  • 19
  • 26
  • Not exactly what i did, but i simply flipped the Y coord when drawing the tiles (level) and elements. Everything else i keep drawing the usual way, since anchorpoint is at 0.5,0.5. But flipping at one point instead of transforming everything is the easiest way to go. Thanks. – NovumCoder Aug 06 '16 at 12:11
  • great solution,I spent my 1 day to know why my line display on top while draw at bottom & when draw at top it display at bottom with same space from screen edges...it helps me to solve SKScene issue – Dharini Jun 10 '19 at 08:59
  • Wanted to translate SCNView coordinates to SKView! and this works perfectly!! Thank you Hayden, spend more than an hour trying to do this cause I stupid. – user3069232 Feb 27 '23 at 10:33
0

Since SKSpriteNode will let you flip its content using a scale of -1, you can place all your nodes under a master SKSpriteNode with a yScale of -1.

 final class GameScene: SKScene 
 {    
     var masterNode:SKSpriteNode! = nil
     override func addChild(node: SKNode) 
     {
        if masterNode == nil
        { 
           masterNode = SKSpriteNode()
           masterNode.position    = CGPoint(x:0, y:size.height)
           masterNode.anchorPoint = CGPointZero
           masterNode.yScale      = -1
           super.addChild(masterNode)        
        } 
        masterNode.addChild(node)
     }
 }

Note that you will need to keep the masterNode's y position aligned with the view size if/when the size changes.

Alain T.
  • 40,517
  • 4
  • 31
  • 51
0

Similar to Alain T's answer but instead using a SKCameraNode with yScale = -1 so you don't need to override the addChild function or have an extra node layer.

let localCamera = SKCameraNode()
override func didMove(to view: SKView) {
    super.didMove(to: view)

    localCamera.yScale = -1
    localCamera.position = CGPoint(x: size.width/2, y: size.height/2)
    addChild(localCamera)
    self.camera = localCamera
// ...
}
richy
  • 2,716
  • 1
  • 33
  • 42