Как бросить SKSpriteNode?

Так что в основном в моей игре мне нужно бросить или выбросить объект. Пока у меня есть спрайт, его можно перетащить, но его нельзя выбросить. идея игры - бросить спрайт, чтобы столкнуться с другим спрайтом. Я хочу, чтобы спрайт, который мы будем называть testNode, Чтобы перемещать то, как пользователь бросил его

Значение, когда я выпускаю спрайт, хочу, чтобы он продолжался в том направлении, в котором я его перемещал. Я потратил годы, пытаясь это выработать, но я просто не могу. Я использую SpriteKit для iOS 8+. Если кто-нибудь может помочь, пожалуйста.

Theres видео, которое я видел, но это было с GameSalad, это еще одна история. Вы можете посмотреть

https://www.youtube.com/watch?v=nn3lWa5jUGE

(Ответ, если вам может понадобиться дальнейший контакт)

import Foundation;
import SpriteKit;

class Level:SKScene {

TestNode:Test? //Test is a class I made

//Removed the update and touches began due to it being irrelevant to what I need help with. 

  override func didMoveToView(view: SKView){
    testNode = Fruit(imageNamed: "apple_idle")
    testNode?.position = CGPointMake(60, 294)
    testNode?.xScale = 0.5
    testNode?.yScale = 0.5
    self.addChild(testNode!)
  }
  override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {

    var nodeTouched = SKNode()
    var currentNodeTouched = SKNode()

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

        nodeTouched = self.nodeAtPoint(location)
        testNode?.position = location
    }
}

 override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {

    var touch: UITouch = touches.anyObject() as UITouch
    var location: CGPoint = touch.locationInNode(self) as CGPoint


}

Ответ 1

Вот краткий пример, который я написал о перемещении спрайта с помощью прикосновения, моделируя его скорость в игровом цикле, а не напрямую устанавливая позицию. Это делает спрайт более динамичным (т.е. Вы можете "бросить" его и позволить ему взаимодействовать с другими физическими телами, поскольку вы перетаскиваете спрайт). Никаких вычислений угла не требуется, я просто вычисляю необходимую скорость для перемещения спрайта в положение касания в течение некоторого интервала времени. В этом случае я устанавливаю время как 1/60, так что движение применяется мгновенно, поэтому объект кажется очень отзывчивым.

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) {
        let touch = touches.first as! UITouch
        let location = touch.locationInNode(self)
        if sprite.frame.contains(location) {
            touchPoint = location
            touching = true
        }
    }
    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        let touch = touches.first as! UITouch
        let location = touch.locationInNode(self)
        touchPoint = location
    }
    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        touching = false
    }

    override 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
        }
    }
}

enter image description here

Вы можете точно настроить вычисления phyiscs, чтобы получить желаемый эффект, который вы ищете. Но этого кода должно быть достаточно, чтобы вы начали. Некоторые улучшения, о которых я мог думать, возможно, ограничивают скорость, поэтому объект не может двигаться слишком быстро при отпускании. Добавление задержки к тач-таску, чтобы перемещение спрайта, но затем случайное прерывание в конце, продолжает бросать объект.

Ответ 2

Если вы перетаскиваете спрайт, то это не должно быть слишком сложно. похоже, что вам нужно добавить какую-то физику в вашу игру.

добавьте это в testNode после установки yScale

testNode.physicsBody = SKPhysicsBody(rectangleOfSize: testNode.size)

теперь запускайте игру. вы должны увидеть падение testNode в нижней части экрана. Вы не хотите, чтобы это произошло, поэтому мы создадим границу экрана как физическое тело.

Добавьте это вверху didMoveToView

self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)

Это заставит края экрана содержать ваш testNode. вы должны иметь возможность забрать его и бросить сейчас

вам, возможно, придется немного подкорректировать эту формулу, чтобы действительно выбросить спрайт.

вам, вероятно, придется сравнить свою последнюю позицию касания против вашего текущего положения касания, получить угол между ними и применить импульс к спрайту.

Ответ 3

Вот версия ответа Swift 3.0/4.0

class GameScene: SKScene {
var sprite: SKSpriteNode!
var touchPoint: CGPoint = CGPoint()
var touching: Bool = false
override func didMove(to view: SKView) {
    let physicsFrame = CGRect(x: 0, y: 50, width: self.frame.size.width, height: self.frame.size.height - 100)
    self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: physicsFrame)
    sprite = SKSpriteNode(color: UIColor.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?) {
    let touch = touches.first!
    let location = touch.location(in:self)
    if sprite.frame.contains(location) {
        touchPoint = location
        touching = true
    }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch = touches.first!
    let location = touch.location(in: self)
    touchPoint = location
}

override func touchesEnded(_ 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
    }
}}