swift - Fricción en SpriteKit
sprite-kit game-physics (1)
Estoy trabajando con Swift, SpriteKit y Xcode 6, tengo un nodo circular en mi pantalla y puedo cambiar la posición del nodo con mi dedo, pero me gustaría implementar un efecto de fricción en este nodo, pero ahora no lo hago cómo hacerlo, aquí está mi código:
class PlayScene: SKScene
{
let firstCircle = SKSpriteNode(imageNamed: "Circle")
// theses 3 variables allows me to move the node according to my finger, but my finger don''t have to touch the node
var departCircleLocation = CGPoint()
var departTouchLocation = CGPoint()
var currentTouchLocation = CGPoint()
override func didMoveToView(view: SKView)
{
addChild(firstCircle)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
for touch: AnyObject in touches
{
departTouchLocation = touch.locationInNode(self)
}
departCircleLocation = firstCircle.position
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent)
{
for touch: AnyObject in touches
{
currentTouchLocation = touch.locationInNode(self)
}
moveCircle()
}
func moveCircle()
{
firstCircle.position.x = departCircleLocation.x - departTouchLocation.x + currentTouchLocation.x
firstCircle.position.y = departCircleLocation.y - departTouchLocation.y + currentTouchLocation.y
}
}
Traté de poner esto en mi código pero no funcionó:
firstCircle.physicsBody = SKPhysicsBody(circleOfRadius: 7)
firstCircle.physicsBody?.affectedByGravity = false
firstCircle.physicsBody?.friction = 0.4
No quiero la gravedad porque el juego se ve desde arriba
¿Puede alguien explicarme cómo podría implementar la fricción en este nodo? Quiero, por ejemplo, que cuando me deslizo hacia arriba con una cierta velocidad y cuando suelte el dedo, el nodo continúe subiendo un poco de tiempo, pero si vuelvo a colocar el dedo en la pantalla, la fricción se detiene de inmediato, por ejemplo :
Si pongo mi dedo 50 píxeles debajo del nodo, no hará nada, pero si muevo mi dedo (que es 50 píxeles debajo del nodo) a 80 píxeles debajo del nodo, el nodo se moverá de 30 píxeles hacia abajo, y esto funciona en cualquier x y y direcciones, puedo mover el nodo sin tocarlo, pero seguirá el camino si mi dedo, ahora si, por ejemplo, muevo mi dedo desde 30 píxeles hacia abajo muy rápidamente y si suelto mi dedo, el nodo continuará yendo abajo debido a la fuerza de fricción, pero mi dedo ya no está en la pantalla (el efecto se ve como cuando nos desplazamos por un sitio web en un iphone, hay un poco de fricción cuando sueltas el dedo debido a la velocidad de deslizamiento) pero no puedo usar UISwipeGesture porque solo detecta direcciones arriba, derecha, abajo e izquierda, no todas las direcciones como quiero. Espero que entiendas lo que estoy diciendo
Aquí hay un ejemplo de cómo mover un elemento basado en el tacto. Este enfoque utiliza la propiedad de velocity
del cuerpo físico para mover el sprite, por lo que interactuará apropiadamente con otros cuerpos físicos en la escena y se verá afectado por la amortiguación, la fricción, etc.
Primero, defina las propiedades de escala y amortiguación. La scale
controla la velocidad a la que el círculo se mueve hacia la ubicación del toque. Un valor mayor moverá el círculo a un ritmo más rápido. La propiedad de damping
se usa para disminuir la velocidad del sprite cuando finaliza el toque. Un valor menor ralentizará el sprite a un ritmo más rápido.
let scale:CGFloat = 2.0
let damping:CGFloat = 0.98
var point:CGPoint?
Guarde la ubicación cuando comienza un toque. El sprite se moverá hacia esta ubicación.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
if let touch = touches.anyObject() as UITouch? {
let location = touch.locationInNode(self)
point = location
}
}
Actualiza la ubicación cuando el toque se mueve
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
if let touch = touches.anyObject() as UITouch? {
let location = touch.locationInNode(self)
point = location
}
}
Restablece la ubicación táctil cuando el toque finaliza
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
point = nil
}
Mueva el sprite hacia la ubicación especificada
func moveNodeToPoint(sprite:SKSpriteNode, point:CGPoint) {
var dx:CGFloat = (point.x - sprite.position.x) * scale
var dy:CGFloat = (point.y - sprite.position.y) * scale
sprite.physicsBody?.velocity = CGVectorMake(dx, dy)
}
Esto se llama antes de que se represente cada cuadro. Llama a la función que actualiza la ubicación del sprite si un toque está activo, de lo contrario ralentiza el sprite con el tiempo
override func update(currentTime: CFTimeInterval) {
if (point != nil) {
moveNodeToPoint(firstCircle, point: point!)
}
else {
// This will slow the circle over time when after the touch ends
let dx = firstCircle.physicsBody!.velocity.dx * damping
let dy = firstCircle.physicsBody!.velocity.dy * damping
firstCircle.physicsBody!.velocity = CGVectorMake(dx, dy)
}
}