【问题标题】:Throwing an object with SpriteKit用 SpriteKit 抛出一个对象
【发布时间】:2015-05-22 11:03:19
【问题描述】:

我目前有以下代码。即使代码构建成功,我似乎也无法让它工作。我正在努力做到这一点,因此当您轻弹对象时,它会以您开始和结束触摸的速度移动。

import SpriteKit
class GameScene: SKScene {
    var sprite: SKSpriteNode!
    var touchPoint: CGPoint = CGPoint()
    var touching: Bool = false
    override func didMoveToView(view: SKView) {
        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 50, height: 50))
        sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
        sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
        self.addChild(sprite)
    }

    //for touch: AnyObject in touches {
    //let location = touch.locationInNode(self)
    //let touchedNode = self.nodeAtPoint(location)

     override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        for touch: AnyObject in touches {

        let location = touch.locationInNode(self)
        if sprite.frame.contains(location) {
            touchPoint = location
            touching = true
        }
    }
    func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
        let location = touch.locationInNode(self)
        touchPoint = location
    }
    func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        touching = false
    }
    func update(currentTime: CFTimeInterval) {
        if touching {
            let dt:CGFloat = 1.0/60.0
            let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
            let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
            sprite.physicsBody!.velocity = velocity
        }
    }
}}}

【问题讨论】:

  • 不是 100% 确定这会有所帮助,但我认为您只想在完成轻弹后应用速度。因为您正在应用每个更新,所以您正在应用非常小的速度。您可能想尝试在 touchesMoved 中更改精灵的位置,然后根据距起点和终点的距离在 touches 结束时应用速度。您也可以根据电影的开始时间和电影的结束时间来确定它。如果你解释你得到的结果不是它的构建,也可能会有所帮助:)
  • 在这里查看我的答案! stackoverflow.com/a/28259980/2158465

标签: ios swift sprite-kit physics


【解决方案1】:

您不小心将touchesMovedtouchesEndedupdate 放在touchesBegan 中。除此之外,您的代码有效。存在问题的提示是,您不需要在 touchesMovedtouchesEndedupdate 前加上 override

以后,我会建议使用断点和打印语句来检查您期望执行的方法,实际上是在运行。这样做你会看到touchesMovedtouchesEndedupdate 的版本没有被调用。

不管怎样,这里已经纠正了它,现在它可以完美地工作了:

import SpriteKit
class GameScene: SKScene {
    var sprite: SKSpriteNode!
    var touchPoint: CGPoint = CGPoint()
    var touching: Bool = false
    override func didMoveToView(view: SKView) {
        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 50, height: 50))
        sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
        sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
        self.addChild(sprite)
    }

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        for touch: AnyObject in touches {

            let location = touch.locationInNode(self)
            if sprite.frame.contains(location) {
                touchPoint = location
                touching = true
            }
        }
    }

    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)
            touchPoint = location
        }
    }

    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        touching = false
    }

    override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
        touching = false
    }

    override func update(currentTime: NSTimeInterval) {
        if touching {
            let dt:CGFloat = 1.0/60.0
            let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
            let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
            sprite.physicsBody!.velocity = velocity
        }
    }
}

【讨论】:

  • 非常感谢!它现在可以工作了:) 快速的问题,我将如何制作它以便精灵在你轻弹它之前不会移动?所以你不能拖动它,所以它有一个原始位置?
  • 我建议查看this 以获取有关获取手势识别器速度的信息(您可以使用与SKScene 中相同的方法)。然后你可以在touchesEnded 中给出精灵速度。另外,如果答案解决了您的问题,您会考虑将其标记为正确吗? :)
  • 很高兴为您提供帮助 :) 祝您项目顺利!
【解决方案2】:

ABakerSmith 为 Swift 4 更新的解决方案:

import SpriteKit
class GameScene: SKScene {
    var sprite: SKSpriteNode!
    var touchPoint: CGPoint = CGPoint()
    var touching: Bool = false
    override func didMove(to view: SKView) {
        self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: self.frame)
        sprite = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
        sprite.physicsBody = SKPhysicsBody.init(rectangleOf: sprite.size)
        sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
        self.addChild(sprite)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first?.location(in: self) {
            if sprite.frame.contains(touch) {
                touchPoint = touch
                touching = true
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches {
            let location = t.location(in: self)
            touchPoint = location
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        touching = false
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        touching = false
    }

    override func update(_ currentTime: TimeInterval) {
        if touching {
            let dt:CGFloat = 1.0/60.0
            let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
            let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
            sprite.physicsBody!.velocity = velocity
        }
    }
}

【讨论】:

    【解决方案3】:

    解决方案更新为不让触摸/拖动捕捉到精灵的中间。如果您正在拖动/投掷一个对象,您将希望该投掷来自用户触摸对象的位置,而不是捕捉到对象的中间。这会让它看起来更流畅

    import SpriteKit
    class GameScene: SKScene {
        var sprite: SKSpriteNode!
        var touchPoint: CGPoint = CGPoint()
        var touching: Bool = false
        var xDif = CGFloat()
        var yDif = CGFloat()
    
        override func didMove(to view: SKView) {
            self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: self.frame)
            sprite = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
            sprite.physicsBody = SKPhysicsBody.init(rectangleOf: sprite.size)
            sprite.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
            self.addChild(sprite)
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            if let touch = touches.first?.location(in: self) {
                xDif = sprite.position.x - touch.x
                yDif = sprite.position.y - touch.y
    
                if sprite.frame.contains(touch) {
                    touchPoint = touch
                    touching = true
                }
            }
        }
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
            for t in touches {
                let location = t.location(in: self)
                touchPoint = location
            }
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            touching = false
        }
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
            touching = false
        }
    
        override func update(_ currentTime: TimeInterval) {
            if touching {
                let dt:CGFloat = 1.0/60.0
                let distance = CGVector(dx: touchPoint.x-sprite.position.x + xDif, dy: touchPoint.y-sprite.position.y + yDif)
                let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
                sprite.physicsBody!.velocity = velocity
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      • 1970-01-01
      • 2013-03-31
      • 2021-05-20
      相关资源
      最近更新 更多