Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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


}
like image 817
Jesse Onolemen Avatar asked Jan 30 '15 22:01

Jesse Onolemen


2 Answers

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

enter image description here

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.

like image 76
Epic Byte Avatar answered Oct 22 '22 12:10

Epic Byte


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.

like image 36
hamobi Avatar answered Oct 22 '22 13:10

hamobi