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)

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)

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Aaron
  • 757
  • 5
  • 18

1 Answers1

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)

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

Epic Byte
  • 33,840
  • 12
  • 45
  • 93
  • This is exactly what I'm after, however I'm afraid that the physics body may interfere with the ones in my subclass. In my subclass 'player' I add about 6-7 individual sprites, all of which have separate physics bodies. My first implementation of this method resulted in very erroneous results, however I will attempt again. – Aaron May 23 '15 at 18:48
  • After a decent amount of fiddling around with my architecture, I think I managed to get it to work. Thanks so much for this, I couldn't figure it out for the life of me! – Aaron May 23 '15 at 19:32
  • @Aaron Awesome, glad to hear you got stuff working. Good luck. – Epic Byte May 23 '15 at 22:02
  • Do you have a suggestion for centering a camera on the node? Apple documentation recommends to basically have the node completely static, and just moving the world to give the illusion of movement, however in this situation (Where the node can't be static) I have to find another way to center the node. – Aaron May 24 '15 at 02:04
  • @Aaron You shouldn't make the node static. You can move (i,e. position) the world such that it remains centered on your moving node. If you need help with this perhaps you should post another question. – Epic Byte May 26 '15 at 04:54