如何使角色(SpriteKit)跟随触摸并保持?

时间:2015-10-02 12:33:54

标签: ios swift sprite-kit

我的游戏有一个角色,每当我触摸屏幕,就会到达那个位置。

但是我希望这个角色能够保持跟随,直到我放手为止。

我试图在更新方法中执行此操作,但无济于事。

3 个答案:

答案 0 :(得分:1)

您可以在iOS 9上使用GameplayKit。

演示电影 https://www.youtube.com/watch?v=9S9SEp6eIZw&feature=youtu.be

import SpriteKit
import GameplayKit

class GameScene: SKScene {
    let trackingAgent = GKAgent2D()

    var player = AgentNode()

    var seekGoal : GKGoal = GKGoal()

    let stopGoal = GKGoal(toReachTargetSpeed: 0)

    var seeking : Bool = false {
        willSet {
            if newValue {
                self.player.agent.behavior?.setWeight(1, forGoal: seekGoal)
                self.player.agent.behavior?.setWeight(0, forGoal: stopGoal)
            }else{
                self.player.agent.behavior?.setWeight(0, forGoal: seekGoal)
                self.player.agent.behavior?.setWeight(1, forGoal: stopGoal)
            }
        }
    }

    var agentSystem = GKComponentSystem()

    var lastUpdateTime : NSTimeInterval = 0

    override func didMoveToView(view: SKView) {
        super.didMoveToView(view)

        self.trackingAgent.position = vector_float2(Float(self.frame.midX), Float(self.frame.midY))

        self.agentSystem = GKComponentSystem(componentClass: GKAgent2D.self)

        self.player = AgentNode(scene: self, radius: Float(40.0), position: CGPoint(x: self.frame.midX, y: self.frame.midY))

        self.player.agent.behavior = GKBehavior()
        self.agentSystem.addComponent(self.player.agent)

        self.seekGoal = GKGoal(toSeekAgent: self.trackingAgent)
    }

    override func update(currentTime: CFTimeInterval) {

        if lastUpdateTime == 0 {
            lastUpdateTime = currentTime
        }

        let delta = currentTime - lastUpdateTime
        lastUpdateTime = currentTime
        self.agentSystem.updateWithDeltaTime(delta)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.seeking = true
        handleTouch(touches)
    }

    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        self.seeking = false
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.seeking = false
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        handleTouch(touches)
    }

    func handleTouch(touches:Set<UITouch>) {
        guard let touch = touches.first else {
            return
        }

        let location = touch.locationInNode(self)

        self.trackingAgent.position = vector_float2(Float(location.x), Float(location.y))
    }
}

&GT;

import Foundation
import GameplayKit
import SpriteKit

class AgentNode : SKNode, GKAgentDelegate {
    var agent = GKAgent2D()

    var triangleShape = SKShapeNode()

    override init(){
        super.init()
    }

    init(scene:SKScene, radius:Float, position:CGPoint) {
        super.init()

        self.position = position
        self.zPosition = 10;
        scene.addChild(self)

        agent.radius = radius
        agent.position = vector_float2(Float(position.x), Float(position.y))
        agent.delegate = self
        agent.maxSpeed = 100 * 4
        agent.maxAcceleration = 50 * 4

        let ship = SKSpriteNode(imageNamed:"Spaceship")
        ship.setScale(1.0 / 8.0)
        ship.zRotation = CGFloat(-M_PI / 2.0)
        self.addChild(ship)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func agentWillUpdate(agent: GKAgent) {

    }

    func agentDidUpdate(agent: GKAgent) {
        guard let agent2D = agent as? GKAgent2D else {
            return
        }

        self.position = CGPoint(x: CGFloat(agent2D.position.x), y: CGFloat(agent2D.position.y))
        self.zRotation = CGFloat(agent2D.rotation)
    }
}

答案 1 :(得分:0)

使用removeActionForKey方法。

let sprite = SKSpriteNode(imageNamed:"Spaceship")

let key = "move1"

override func didMoveToView(view: SKView) {
    sprite.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
    sprite.setScale(0.25)
    self.addChild(self.sprite)
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch in touches {
        let location = touch.locationInNode(self)

        let move = SKAction.moveTo(location, duration: 4)
        self.sprite.runAction(move, withKey: self.key)
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.sprite.removeActionForKey(self.key)
}

答案 2 :(得分:0)

我这样做了。我不知道这是不是最好的办法,但这是我找到的最佳方式:)

nodeToMove - 您要移动的节点 nodeToMove.movingSpeed - 您的节点速度

func movingWithLocation(location: CGPoint) {

    isMoving = true
    microbe.removeActionForKey("move")
    var distanceX: Float = (location.x - nodeToMove.position.x)
    var distanceY: Float = (location.y - nodeToMove.position.y)
    var distance: Float = sqrtf(fabsf(distanceX * distanceX) + fabsf(distanceY * distanceY))
    nodeToMove.runAction(SKAction.moveByX(distanceX, y: distanceY, duration: distance / (self.frame.size.width / 300 * nodeToMove.movingSpeed)), withKey: "move")
    self.runAction(SKAction.sequence([
            SKAction.waitForDuration(0.05),
            SKAction.performSelector("changeMovament", onTarget: self)]))
}

&GT;

func changeMovament() {
    isMoving = false
}

并像这样打电话

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

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

    if isMoving == false {

        self.movingWithLocation(locationWorld)
    }
}

&GT;

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

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

    if isMoving == false {

        self.movingWithLocation(locationWorld)
    }
}

别忘了!

var isMoving: Bool = false