Swift SKSpriteNode位置问题 - 记录正确,放置错误

时间:2014-06-13 06:15:52

标签: ios iphone objective-c swift

情况

我正在使用 Lynda.com video series (iOS Game Dev. With Sprite Kit) ,该教程是Objective-C的最后一代,作为一项培训练习,我将其转换为Swift并使用新功能。目标是一个旧学校破砖游戏。

我有一个更新的 full project repository on GitHub here

问题

在GameScene.swift文件中的

,我写了一个方法addBricks(size: CGSize)

func addBricks (size: CGSize){

    println(" the input parameter size: \(size)")

    var maxRows = 1
    var maxCols = 1
    var xPos : CGFloat
    var yPos : CGFloat

    for (var rows = 0; rows < maxRows; rows++){
        for (var i = 0; i < maxCols ; i++){

            var brick: SKSpriteNode = SKSpriteNode(imageNamed: "brick")
            brick.physicsBody = SKPhysicsBody(rectangleOfSize: brick.frame.size)

            xPos = CGFloat(size.width) / CGFloat(maxCols+1) * CGFloat(i + 1)
            yPos = CGFloat(size.height) - CGFloat(80 * rows) - 100.0

            brick.physicsBody.dynamic = false
            brick.physicsBody.categoryBitMask = brickCategory

            brick.shadowCastBitMask = 1
            brick.lightingBitMask = 1

            //brick.position = CGPointMake(CGFloat(xPos), CGFloat(yPos))
            brick.position = CGPointMake(320.0, 1036.0)

            println("Brick position - xpos: \(xPos), ypos: \(yPos) || overall:\(brick.position)")

            self.addChild(brick)

        }
    }

}

我首先在didMoveToView()的场景中调用它,一切都很好,我的砖块节点放在适当的位置。在我的游戏逻辑中,我稍后从didBeginContact()调用此方法,当一个逻辑检查后球击中桨时,看不到剩下的砖。在&#34;当你用完砖块时,添加更多&#34; 感觉......

func didBeginContact(contact: SKPhysicsContact!){

    var notTheBall : SKPhysicsBody

    // check the contacts and find the one thats not the ball
    if ( contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask ){
        notTheBall = contact.bodyB
    } else {
        notTheBall = contact.bodyA
    }

    /* more logic here for other contacts */

    if ( notTheBall.categoryBitMask == paddleCategory ){

        self.runAction(playSFXBlip)

        //println("\(self.children.count) and \(staticSize)")

        if ( self.children.count <= 5 ){
            addBricks(self.frame.size)
        }

    }

}

在对addBricks()的任何后续方法调用中,所有砖块都放置在视图左下角的0,0点处,即使控制台显示它们位于不同的位置:

enter image description here

自我对象是SKScene println(self)的当前实例 - &gt; <SKScene> name:'(null)' frame:{{0, 0}, {640, 1136}}

我试过了:

  • 将我的位置计算的所有元素投射为Float s和CGFloat s
  • 通过设置静态浮点值来调试addBricks方法
  • 在联系方法之外创建框架大小的属性,并将该大小传递给addBricks。
  • google-ing和咨询the Swift Programming Language Guide以及相关内容的文档

导致不恰当定位的原因是什么?在此先感谢抱歉TL;DR

2 个答案:

答案 0 :(得分:3)

问题是,您正在尝试在didBeginContact方法中设置节点的位置。您不能在已经拥有物理实体的didBeginContact中定位节点。

理想的解决方案是在没有物理实体的情况下添加砖块,然后将其设置到您喜欢的位置,最后添加物理实体。

另一种解决方案是创建一些在运行didBeginContact后调用的代码。例如

func didBeginContact(contact: SKPhysicsContact!){

    var notTheBall : SKPhysicsBody

    if ( contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask ){
        notTheBall = contact.bodyB
    } else {
        notTheBall = contact.bodyA
    }

    if ( notTheBall.categoryBitMask == paddleCategory ){
        addBricksInUpdate = true
    }
}

func update:(currentTime: CFTimeInterval) {
    if (addBricksInUpdate) {
        if ( self.children.count <= 5 ){
            addBricks(self.frame.size)
        }
    }
}

答案 1 :(得分:2)

我不太了解什么&#34; self&#34;当你打电话,或者自己的属性和价值是什么时,但是当子节点出现在左下角时,通常是出于以下两个原因之一:

1 - 对象已放置在(0,0) - 要么是因为它们的位置,要么是因为某些其他约束(如size或rect)返回零值。所以你有一个父级的大小(0,0),或转换坐标等。

[OR]

2-对象的父节点从&#34;屏幕&#34;偏移/缩放/定位。以这样的方式,你输入的孩子的位置值让孩子们看起来像是在左下角,即使他们实际上是相对于父母或者父母的位置放置的坐标空间。通过查看不同的坐标是否仍将对象放在同一位置,可以轻松检查这一点。

因此,检查父级的锚点,无论是场景还是节点。并检查父母的大小和位置。我听说过提到sks文件有一些奇怪的默认大小设置,关于精灵套件和场景大小,但尚未打开一个快速的项目。