Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

ios - Manually move node over a period of time

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)

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.

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.

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

(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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)

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).

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

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...