在SpriteKit中缩放怪异

时间:2017-01-25 05:50:04

标签: swift sprite-kit position skspritenode

我正在使用Swift和SpriteKit构建应用程序。该应用程序加载一个与屏幕大小完全相同的SKSpriteNode,并将其置于屏幕上。但是,用户可以根据需要移动和缩放此SKSpriteNode。我关心SKSpriteNode的绝对位置,因为如果节点移动得太多我想把它带回中心,或者" snap"它到屏幕的边缘。 (SKSpriteNode最终会持有一张地图)。

当节点的比例正好为1.0时,位置值的工作方式与我预期的一样。但是,当我缩放节点(使用捏合手势)并且比例增长到1.0以上时,位置值没有意义。这里有一些图片来说明我的意思。

在这里,您可以看到未缩放的节点与放置的场景具有完全相同的尺寸和位置。对于每个地图以及场景,X和Y均为0:

enter image description here

但是,正如您在下一张图片中看到的那样,当我将Map缩放为更大的SKSpriteNode时,移动它以使Map的左下角完全位于屏幕的左下角,缩放节点的X和Y值关闭。我希望X为0而Y为0,但它们不是。

enter image description here

这里发生了什么,如何计算缩放节点的绝对位置?当我说"绝对"位置,也许我的意思是相对于场景的位置?无论如何,你的想法很受欢迎。

1 个答案:

答案 0 :(得分:0)

我想出来了,虽然这并不容易。原来是“AnchorPoint Dorkitis”的案例。这种情况的主要症状是基于错误假设编写代码,在我的情况下,我做的假设是:

我的节点的(X,Y)点是节点的左下角。 (假)

我一直都知道我将我的AnchorPoints(场景和SKSpriteNode)都设置为(x:0.5,y:0.5),但是我还没有沉入其中,这也改变了屏幕实际居住的(X,Y)坐标(提示:中心)。

对于那些感兴趣的人,我制定了一组很好的计算属性来返回我的场景和我的SKSpriteNode的X,Y,高度,宽度,顶部,底部,左侧和右侧值。我在这里与您分享:

var map_x: Int {
    get {
        return Int(self.position.x)
    }
}

var map_y: Int {
    get {
        return Int(self.position.y)
    }
}

var map_h: Int {
    get {
        return Int(self.frame.height)
    }
}

var map_w: Int {
    get {
        return Int(self.frame.width)
    }
}

var map_t: Int {
    get {
        return Int(self.position.y + self.frame.height/2)
    }
}

var map_b: Int {
    get {
        return Int(self.position.y - self.frame.height/2)
    }
}

var map_l: Int {
    get {
        return Int(self.position.x - self.frame.width/2)
    }
}

var map_r: Int {
    get {
        return Int(self.position.x + self.frame.width/2)
    }
}

var scene_x: Int {
    get {
        return Int((scene?.position.x)!)
    }
}

var scene_y: Int {
    get {
        return Int((scene?.position.y)!)
    }
}

var scene_h: Int {
    get {
        return Int((scene?.frame.height)!)
    }
}

var scene_w: Int {
    get {
        return Int((scene?.frame.width)!)
    }
}

var scene_t: Int {
    get {
        return Int((scene?.position.y)! + (scene?.frame.height)!/2)
    }
}

var scene_b: Int {
    get {
        return Int((scene?.position.y)! - (scene?.frame.height)!/2)
    }
}

var scene_l: Int {
    get {
        return Int((scene?.position.x)! - (scene?.frame.width)!/2)
    }
}

var scene_r: Int {
    get {
        return Int((scene?.position.x)! + (scene?.frame.width)!/2)
    }
}

我本可以使它们成为CGFloat值而不是将它们包装在Int()中但是我需要在代码中的其他地方使用它们,所以我想也可以在这里做。我认为我的下一步是用更少的代码行来弄清楚如何做到这一点:)