SpriteKit类分离问题

时间:2017-06-05 04:45:38

标签: class sprite-kit

我有一个名为ball的属性,它有两个函数 - setup()和launch():

var ball = Ball()

在我调用ball.launch()后,我想知道它在x轴上的位置:

ball.position.x

但出于某种原因,我一直都是零。现在,我从touchesBegan发射球并试图获得touchesEnded中的位置。正如我所说,发射部分工作正常。球出现了,它按预期反弹,但我没有做任何球属性在那之后有任何影响。这是完整的代码:

Ball.swift

class Ball: SKSpriteNode {

    var ball: SKSpriteNode!

    func setUp(parentNode: SKNode) {

        ball = SKSpriteNode(imageNamed: "ball2")
        ball.name = "ball"
        ball.position = CGPoint(x: 20, y: 200)
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width / 2)
        ball.physicsBody?.restitution = 0
        ball.physicsBody?.velocity = CGVector(dx: 0, dy: 0)

        ball.physicsBody?.categoryBitMask = PhysicsCategories.Ball
        ball.physicsBody?.collisionBitMask = PhysicsCategories.Edge
        ball.physicsBody?.contactTestBitMask = PhysicsCategories.Edge
        parentNode.addChild(ball)
    }


    func launch() {
        ball.physicsBody?.applyImpulse(CGVector(dx: 25, dy: 0))
    }

}

GameScene.swift

import SpriteKit
import GameplayKit

struct PhysicsCategories {

    static let Ball:     UInt32 = 0
    static let Edge:     UInt32 = 0b1
}

class GameScene: SKScene, SKPhysicsContactDelegate {

    var ball = Ball()

    override func didMove(to view: SKView) {

        let border = SKPhysicsBody(edgeLoopFrom: self.frame)
        border.friction = 0
        border.restitution = 1
        physicsBody = border
        border.categoryBitMask = PhysicsCategories.Edge
        border.collisionBitMask = PhysicsCategories.Ball
        border.contactTestBitMask = PhysicsCategories.Ball

        physicsWorld.contactDelegate = self
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        ball.setUp(parentNode: self)
        ball.launch()
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(ball.position.x) //value is always zero
    }


    func didBegin(_ contact: SKPhysicsContact) {
        let collision = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

        switch collision {
        case PhysicsCategories.Ball | PhysicsCategories.Edge:
            ball.removeFromParent() //doesn't get removed
        default:
            break
        }
    }
}

1 个答案:

答案 0 :(得分:2)

问题是您正在尝试访问错误的属性。您在gamescene.swift中创建了Ball,但除了致电launch()之外什么也没做,但launch()只会影响 ball.ball ,因为你有创建了两个球属性。

你在gamecene中创建的球从未被添加到场景中,也从不做任何事情,因此它表明你的位置永远不会改变。

要解决此问题,您需要使用Ball类作为蓝图,以通过您的gamecene创建球属性

class Ball: SKSpriteNode {

  // You don't want to create an object of the type you are creating here...
  // as a property of the class!:
  // var ball: SKSpriteNode!

  func setUp(parentNode: SKNode) {

    self.name = "ball"
    self.position = CGPoint(x: 20, y: 200)
    self.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width / 2)
    self.physicsBody?.restitution = 0
    self.physicsBody?.velocity = CGVector(dx: 0, dy: 0)

    self.physicsBody?.categoryBitMask = PhysicsCategories.Ball
    self.physicsBody?.collisionBitMask = PhysicsCategories.Edge
    self.physicsBody?.contactTestBitMask = PhysicsCategories.Edge
    self.parentNode.addChild(ball)
  }


  func launch() {
    self.physicsBody?.applyImpulse(CGVector(dx: 25, dy: 0))
  }

}

现在,当您致电ball.launch()时,您实际修改的状态为ball,而不是ball.ball(因为我删除了ball.ball并将其更改为self =} )

以下是您正在做的事情的简单表示,以及为什么它没有按预期工作:

class Cat {

 var fluffy: Cat!

  var name = "no name"

  func changeName() {
    fluffy = Cat()
    fluffy.name = "Fluffy"
  }

}

var fluffy = Cat()
fluffy.changeName()
print(fluffy.name) // no name
print(fluffy.fluffy.name) // Fluffy
相关问题