2015-01-30 16 views
9

Quindi, fondamentalmente nel mio gioco ho bisogno di lanciare o lanciare un oggetto. Finora ho uno sprite, può essere trascinato ma non può essere lanciato. l'idea dei giochi è lanciare uno sprite per scontrarsi con un altro sprite. Voglio lo sprite che chiameremo testNode, per spostare il modo in cui l'utente l'ha lanciatocome lanciare SKSpriteNode?

significato, quando rilascio lo sprite lo voglio continuare nella direzione in cui l'ho spostato. Ho passato anni a cercare di risolvere questo problema, ma non ci riesco. Sto usando SpriteKit per iOS 8+. Se qualcuno può aiutarmi, per favore.

C'è un video che ho visto ma era con GameSalad che è un'altra storia. Si può avere uno sguardo

https://www.youtube.com/watch?v=nn3lWa5jUGE

(Rispondi se potrebbe essere necessario un ulteriore contatto)

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 


} 

risposta

20

Ecco un rapido esempio che ho scritto di spostare uno sprite con il tocco simulando la sua velocità nel ciclo di gioco anziché impostare direttamente la posizione. Questo rende lo sprite più dinamico (cioè puoi "lanciarlo" e lasciarlo interagire con altri corpi fisici mentre trascini lo sprite). Non sono necessari calcoli di angoli, sto semplicemente calcolando la velocità necessaria per spostare lo sprite sulla posizione di tocco in un intervallo di tempo. In questo caso, ho impostato il tempo come 1/60 in modo che il movimento sia applicato istantaneamente in modo che l'oggetto appaia molto reattivo.

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

È possibile ottimizzare i calcoli phyiscs voi stessi per ottenere l'effetto desiderato che stai cercando. Ma questo codice dovrebbe essere sufficiente per iniziare. Alcuni miglioramenti che potrei pensare sono probabilmente limitando la velocità in modo che l'oggetto non possa muoversi troppo velocemente quando rilasciato. Aggiungendo un ritardo al tocco, trascina in modo tale che lo spostamento dello sprite ma poi si fermi accidentalmente alla fine continua a lanciare l'oggetto.

+1

Grazie mille molto questo ha funzionato perfettamente non sai quanto mi servisse! –

+1

@ Jesster2k10 Fantastico, felice ha funzionato. Inoltre, contrassegnare la risposta come accettata se si ritiene che abbia risposto alla domanda. Se hai bisogno di ulteriore aiuto, fammi sapere. –

+0

Ho contrassegnato come accettato! il mio unico problema è che se si tocca un punto qualsiasi dello schermo, lo sprite verrà spostato lì. Non voglio davvero che ciò accada. Voglio solo spostarlo se lo sprite viene toccato. ecco di più di una spiegazione. https://www.dropbox.com/s/evkzetluuucld8k/Apple.mov?dl=0 –

2

Se stai trascinando lo sprite, allora questo non dovrebbe essere troppo difficile . sembra che tu debba aggiungere un po 'di fisica al tuo gioco.

aggiungere questo al testNode dopo aver impostato yScale

testNode.physicsBody = SKPhysicsBody(rectangleOfSize: testNode.size) 

ora eseguire il gioco. dovresti vedere drop drop nella parte inferiore dello schermo. Non vuoi che ciò accada, quindi faremo in modo che il confine dello schermo agisca come un corpo fisico.

Aggiungere questo nella parte superiore del didMoveToView

self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame) 

Questo renderà i bordi dello schermo contengono tuo testNode. dovresti essere in grado di prenderlo e rilasciarlo ora

potresti dover modificare questa formula un po 'per lanciare davvero lo sprite.

probabilmente devi confrontare l'ultima posizione di tocco con la posizione corrente del tocco, ottenere l'angolo tra quelli e applicare un impulso allo sprite.

+0

Accidenti, non mi aspettavo una risposta così rapida. Lo proverò –

+0

anche cosa intendi con "Tweak with this formula?" –

+0

Voglio dire che dovrai scrivere più codice e fare più ricerche ma questo ti farà iniziare – hamobi

0

Ecco Swift 3.0/4.0 versione della risposta

class GameScene: SKScene { 
var sprite: SKSpriteNode! 
var touchPoint: CGPoint = CGPoint() 
var touching: Bool = false 
override func didMove(to view: SKView) { 
    let physicsFrame = CGRect(x: 0, y: 50, width: self.frame.size.width, height: self.frame.size.height - 100) 
    self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: physicsFrame) 
    sprite = SKSpriteNode(color: UIColor.red, size: CGSize(width: 50, height: 50)) 
    sprite.physicsBody = SKPhysicsBody.init(rectangleOf: 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<UITouch>, with event: UIEvent?) { 
    let touch = touches.first! 
    let location = touch.location(in:self) 
    if sprite.frame.contains(location) { 
     touchPoint = location 
     touching = true 
    } 
} 
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    let touch = touches.first! 
    let location = touch.location(in: self) 
    touchPoint = location 
} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    touching = false 
} 
override func update(_ currentTime: TimeInterval) { 
    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 
    } 
}}