Move a node to finger using Swift + SpriteKit
You can save yourself a lot of trouble by using: myShip.physicsBody.applyImpluse(vector)
. It works by acting as if you gave myShip
a push in the direction vector
points. If you calculate vector
as the x distance from your last touch location to myShip
, then it'll accelerate, decelerate, change direction, etc. pretty close to the way you're describing because it'll be giving it little pushes in the right direction on each update
.
Basically you store the last touch location then, in your update
function, you calculate the CGVector
pointing from myShip
to lastTouch
and apply that as an impulse to your physics body.
Something like:
var lastTouch: CGPoint? = nil
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
}
override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
}
// Be sure to clear lastTouch when touches end so that the impulses stop being applies
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
lastTouch = nil
}
override func update(currentTime: CFTimeInterval) {
// Only add an impulse if there's a lastTouch stored
if let touch = lastTouch {
let impulseVector = CGVector(touch.x - myShip.position.x, 0)
// If myShip starts moving too fast or too slow, you can multiply impulseVector by a constant or clamp its range
myShip.physicsBody.applyImpluse(impulseVector)
}
}
You'll also probably want to play with the linearDamping
and angularDamping
values on myShip.physicsBody
. They'll help determine how fast myShip
accelerates and decelerates.
I maxed out the values at 1.0
in my app:
myShip.physicsBody.linearDamping = 1.0
myShip.physicsBody.angularDamping = 1.0
If myShip
doesn't stop fast enough for you, you can also try applying some breaking in your update
function:
override func update(currentTime: CFTimeInterval) {
// Only add an impulse if there's a lastTouch stored
if let touch = lastTouch {
let impulseVector = CGVector(touch.x - myShip.position.x, 0)
// If myShip starts moving too fast or too slow, you can multiply impulseVector by a constant or clamp its range
myShip.physicsBody.applyImpluse(impulseVector)
} else if !myShip.physicsBody.resting {
// Adjust the -0.5 constant accordingly
let impulseVector = CGVector(myShip.physicsBody.velocity.dx * -0.5, 0)
myShip.physicsBody.applyImpulse(impulseVector)
}
}
Sprite won't move with finger/ SpriteKit / Swift 3
this code
simpleS = self.childNode(withName: "simpleS") as! SKSpriteNode
connects the sprites in your GameScene.sks with GameScene.swift
so in the first step you have to make sure that you set the right name (exactly "simpleS") in your sks file.
if you did it right, so please send the error for us.
i have built and ran your code and everything works in a right way.
another point is that if you want your sprites only moves by your finger movement you have to delete the codes in touchesBegan function, because touchesBegan moves your sprite wherever you touch.
drag a SKSprite Node or a UIImage by my finger more accurately, maintain offset?
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let touchl = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
let dx = touchl.x - previousLocation.x
let dy = touchl.y - previousLocation.y
triangle.position.x = triangle.position.x + dx
triangle.position.y = triangle.position.y + dy
}
}
Moving SpriteKit Node with Touch Gestures only moves one point with each new touch
The issue ended up being that I had a pan gesture recognizer that was conflicting with the multitouch delegate methods. I fixed by adding logic to enable/disable that gesture recognizer if the particular node I wanted to move was being touched or not.
Related Topics
Xcode 8 "The Aps-Environment Entitlement Is Missing from the App's Signature" on Submit
Xcode 11 Backward Compatibility: "Uiwindowscene Is Only Available in iOS 13 or Newer"
How to Prompt the User to Turn on Location Services After User Has Denied Their Use
iOS - Parse Issues in Nsobjcruntime, Nszone, and Nsobject
How to Get an Iphone's Device Name
Mkmapview Mkpointannotation Tap Event
How to Change Uibutton Image in Swift
How to Turn the iPhone Camera Flash On/Off
How to Run the iOS 7.1 Simulator in Xcode 7.0 Beta 2
Ib_Designable, Ibinspectable -- Interface Builder Does Not Update
Uiapplication.Registerforremotenotifications() Must Be Called from Main Thread Only
How to Add Strings on X Axis in iOS-Charts
Decode Base64Url to Base64 -- Swift
Keyboard and Cursor Show, But I Can't Type Inside Uitextfields and Uitextviews
Pixel Array to Uiimage in Swift
Add a Running Countup Display Timer to an iOS App, Like the Clock Stopwatch