how to throw SKSpriteNode?
So basically in my game i need to toss or throw an object. So far i have a sprite, It can be dragged but it cannot be thrown. the games idea is to throw a sprite to collide with another sprite. I want the sprite which we will call testNode, To move how where the user had thrown it
meaning, when i release the sprite i want it to continue in the direction that i moved it . I have spent ages trying to work this out but I just can't. I am using SpriteKit for iOS 8+. If anybody can help please do.
Theres a video I saw but it was with GameSalad which is another story. You can have a look
https://www.youtube.com/watch?v=nn3lWa5jUGE
(Reply if you may need further contact)
import Foundation;
import SpriteKit;
class Level:SKScene {
TestNode:Test? //Test is a class I made
//Removed the update and touches began due to it being irrelevant to what I need help with.
override func didMoveToView(view: SKView){
testNode = Fruit(imageNamed: "apple_idle")
testNode?.position = CGPointMake(60, 294)
testNode?.xScale = 0.5
testNode?.yScale = 0.5
self.addChild(testNode!)
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
var nodeTouched = SKNode()
var currentNodeTouched = SKNode()
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
nodeTouched = self.nodeAtPoint(location)
testNode?.position = location
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
var touch: UITouch = touches.anyObject() as UITouch
var location: CGPoint = touch.locationInNode(self) as CGPoint
}
Here is a quick example I wrote of moving a sprite with touch by simulating its velocity in the game-loop as opposed to setting the position directly. This makes the sprite more dynamic (i.e. you can "throw" it, and let it interact with other physics bodies as your drag the sprite). No angle calculations are needed, i'm simply calculating the necessary velocity to move the sprite to the touch position over some interval of time. In this case I set the time as 1/60 so that the motion is applied instantaneously so the object appears very responsive.
import SpriteKit
class GameScene: SKScene {
var sprite: SKSpriteNode!
var touchPoint: CGPoint = CGPoint()
var touching: Bool = false
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)
self.addChild(sprite)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let location = touch.locationInNode(self)
if sprite.frame.contains(location) {
touchPoint = location
touching = true
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let location = touch.locationInNode(self)
touchPoint = location
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
touching = false
}
override func update(currentTime: CFTimeInterval) {
if touching {
let dt:CGFloat = 1.0/60.0
let distance = CGVector(dx: touchPoint.x-sprite.position.x, dy: touchPoint.y-sprite.position.y)
let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
sprite.physicsBody!.velocity=velocity
}
}
}
You can fine-tune the phyiscs calculations yourself to get the desired effect you are looking for. But this code should be enough to get you started. Some enhancements I could think of are possibly capping the velocity so the object can't move too fast when released. Adding a delay to the touch-drag so that moving the sprite but then accidentally stopping short at the end continues to throw the object.
If you're dragging the sprite, then this shouldn't be too hard. sounds like you need to add some physics to your game.
add this to testNode after you set yScale
testNode.physicsBody = SKPhysicsBody(rectangleOfSize: testNode.size)
now run the game. you should see testNode drop to the bottom of the screen. You don't want that to happen, so we'll make the border of the screen act as a physics body.
Add this at the top of didMoveToView
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
This will make the edges of the screen contain your testNode. you should be able to pick it up and drop it now
you might have to tweak this formula a bit to really throw the sprite around.
you probably have to compare your last touch position vs your current touch position, get the angle between those and apply an impulse to the sprite.