在一段时间内手动移动节点

时间:2023-01-23 13:12:31

I currently have the following functions declared which moves a node to a target location which is called in the update function of the scene (In this situation, I can't use SKAction.moveTo)

我目前有以下函数声明,将节点移动到场景更新函数中调用的目标位置(在这种情况下,我不能使用skaction . mo否决权)

func moveTowardsPosition(targetPosition: CGPoint, withTimeInterval timeInterval: NSTimeInterval) {
    let currentPosition = self.position
    var deltaX = targetPosition.x - currentPosition.x
    var deltaY = targetPosition.y - currentPosition.y
    var maximumDistance = 3 * CGFloat(timeInterval)
    moveFromCurrentPosition(currentPosition, byDeltaX: deltaX, deltaY: deltaY, maximumDistance: maximumDistance)
}

func moveFromCurrentPosition(currentPosition: CGPoint, byDeltaX dx: CGFloat, deltaY dy: CGFloat, maximumDistance: CGFloat) {
    let targetPosition = CGPointMake(currentPosition.x + dx, currentPosition.y + dy)
    var distRemaining = hypot(dx, dy)
    if distRemaining < maximumDistance {
        position = targetPosition
    } else {
        let x = currentPosition.x * maximumDistance
        let y = currentPosition.y * maximumDistance
        position = CGPointMake(x, y)
    }
}

(These are slightly modified from Apples "Adventure" game)

(这是苹果“冒险”游戏的稍加修改)

My problem is these lines in the moveCurrentPosition function.

我的问题是moveCurrentPosition函数中的这些行。

let x = currentPosition.x * maximumDistance
let y = currentPosition.y * maximumDistance
position = CGPointMake(x, y)

Basically, I have no idea what values to set x and y to so that position represents the correct position. In Apple's example, they are multiplying it by maximumDistance - angle. The angle var is a value that just affects the assets rotation, however my asset is 'static' and doesn't have multiple positions -- just 1.

基本上,我不知道将x和y设为什么值,所以这个位置代表正确的位置。在苹果的例子中,他们把它乘以最大距离角。角度var是一个只影响资产旋转的值,但是我的资产是“静态的”,没有多个位置——只有1个。

With that in mind, what would I set x and y to so they are representative of the correct position?

考虑到这一点,我应该将x和y设为什么以便它们代表正确的位置?

(You can see Apple's example here: https://developer.apple.com/library/prerelease/ios/samplecode/Adventure-Swift/Listings/Swift_Adventure_Adventure_Shared_Sprites_Character_swift.html)

(您可以在这里看到苹果的示例:https://developer.apple.com/library/prerase/ios/samplecode/adventure swift/listings/swift_adventure_adventure_shared_sprites_character_swift.html)

1 个解决方案

#1


2  

I currently have the following functions declared which moves a node to a target location which is called in the update function of the scene (In this situation, I can't use SKAction.moveTo)

我目前有以下函数声明,将节点移动到场景更新函数中调用的目标位置(在这种情况下,我不能使用skaction . mo否决权)

You are correct not to use the SKActions in a scenario like this. I see you are trying to move a node to a position without using SKActions. I don't really understand the problem you are having with the code you posted. However I have written a small sample project that demonstrates moving a node to a position in the update function without SKActions. In this sample project, I have a sprite that moves to the current touch position. You can set the speed at which the node travels as well as the rate at which the velocity is applied. You can try messing with the rate to get the correct feel for your game. You will also need to handle the case when the node arrives at the target location (again, this will depend on your game).

在这样的场景中不使用skaction是正确的。我看到您正在尝试不使用SKActions将节点移动到某个位置。我真的不明白你发布的代码有什么问题。但是,我编写了一个小示例项目,演示如何在不使用SKActions的情况下将节点移动到update函数中的位置。在这个示例项目中,我有一个移动到当前触摸位置的精灵。你可以设置节点运动的速度以及速度的应用速度。你可以试着调整速度,以获得对游戏的正确感觉。当节点到达目标位置时,您还需要处理这种情况(同样,这将取决于您的游戏)。

Let me know if this helps at all and/or if you have any questions.

如果你有任何问题的话,请告诉我。

import SpriteKit
class GameScene: SKScene {
    var sprite: SKSpriteNode!
    var travelPoint: CGPoint = CGPoint() //The point to travel to.
    let travelSpeed = CGVector(dx: 200, dy: 200) //The speed at which to travel.
    let rate:CGFloat = 0.1 //1.0 Completely responsive. 0.0 Completely unresponsive. I set this value to < 1 to smooth the application of motion.
    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)
        sprite.physicsBody?.affectedByGravity = false
        self.addChild(sprite)
    }
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        let touch = touches.first as! UITouch
        let location = touch.locationInNode(self)
            travelPoint = location
    }
    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        let touch = touches.first as! UITouch
        let location = touch.locationInNode(self)
        travelPoint = location
    }
    override func update(currentTime: CFTimeInterval) {
        let disp = CGVector(dx: travelPoint.x-sprite.position.x, dy: travelPoint.y-sprite.position.y)
        let angle = atan2(disp.dy, disp.dx)
        let vel = CGVector(dx: cos(angle)*travelSpeed.dx, dy: sin(angle)*travelSpeed.dy)
        let relVel = CGVector(dx: vel.dx-sprite.physicsBody!.velocity.dx, dy: vel.dy-sprite.physicsBody!.velocity.dy)
        sprite.physicsBody!.velocity = CGVector(dx: sprite.physicsBody!.velocity.dx+relVel.dx*rate, dy: sprite.physicsBody!.velocity.dy+relVel.dy*rate)
    }
}

在一段时间内手动移动节点

#1


2  

I currently have the following functions declared which moves a node to a target location which is called in the update function of the scene (In this situation, I can't use SKAction.moveTo)

我目前有以下函数声明,将节点移动到场景更新函数中调用的目标位置(在这种情况下,我不能使用skaction . mo否决权)

You are correct not to use the SKActions in a scenario like this. I see you are trying to move a node to a position without using SKActions. I don't really understand the problem you are having with the code you posted. However I have written a small sample project that demonstrates moving a node to a position in the update function without SKActions. In this sample project, I have a sprite that moves to the current touch position. You can set the speed at which the node travels as well as the rate at which the velocity is applied. You can try messing with the rate to get the correct feel for your game. You will also need to handle the case when the node arrives at the target location (again, this will depend on your game).

在这样的场景中不使用skaction是正确的。我看到您正在尝试不使用SKActions将节点移动到某个位置。我真的不明白你发布的代码有什么问题。但是,我编写了一个小示例项目,演示如何在不使用SKActions的情况下将节点移动到update函数中的位置。在这个示例项目中,我有一个移动到当前触摸位置的精灵。你可以设置节点运动的速度以及速度的应用速度。你可以试着调整速度,以获得对游戏的正确感觉。当节点到达目标位置时,您还需要处理这种情况(同样,这将取决于您的游戏)。

Let me know if this helps at all and/or if you have any questions.

如果你有任何问题的话,请告诉我。

import SpriteKit
class GameScene: SKScene {
    var sprite: SKSpriteNode!
    var travelPoint: CGPoint = CGPoint() //The point to travel to.
    let travelSpeed = CGVector(dx: 200, dy: 200) //The speed at which to travel.
    let rate:CGFloat = 0.1 //1.0 Completely responsive. 0.0 Completely unresponsive. I set this value to < 1 to smooth the application of motion.
    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)
        sprite.physicsBody?.affectedByGravity = false
        self.addChild(sprite)
    }
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        let touch = touches.first as! UITouch
        let location = touch.locationInNode(self)
            travelPoint = location
    }
    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        let touch = touches.first as! UITouch
        let location = touch.locationInNode(self)
        travelPoint = location
    }
    override func update(currentTime: CFTimeInterval) {
        let disp = CGVector(dx: travelPoint.x-sprite.position.x, dy: travelPoint.y-sprite.position.y)
        let angle = atan2(disp.dy, disp.dx)
        let vel = CGVector(dx: cos(angle)*travelSpeed.dx, dy: sin(angle)*travelSpeed.dy)
        let relVel = CGVector(dx: vel.dx-sprite.physicsBody!.velocity.dx, dy: vel.dy-sprite.physicsBody!.velocity.dy)
        sprite.physicsBody!.velocity = CGVector(dx: sprite.physicsBody!.velocity.dx+relVel.dx*rate, dy: sprite.physicsBody!.velocity.dy+relVel.dy*rate)
    }
}

在一段时间内手动移动节点