2014-04-02 7 views
6

Ho un nodo con un corpo fisico dinamico. E mi piacerebbe renderlo statico e cambiare la sua posizione quando viene in contatto con un altro corpo.SpriteKit: impossibile cambiare la posizione del nodo nella callback del contatto

sono riuscito a rendere il corpo statico della soluzione proposta in questa domanda: Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)

Tuttavia se cambio la proprietà position del nodo in uno dei metodi di contatto callback (es didBeginContact) la nuova posizione non è preso in considerazione.

Come potrei ottenere quello?

+0

puoi pubblicare il codice che non riesce a aggiornare la posizione, e come è stato implementato la soluzione si è collegato al? – LearnCocos2D

+0

@ LearnCocos2D la soluzione fornita da JKallio funziona correttamente (riassegnando il physicalBody al suo nodo) – fiddler

risposta

6

Credo che questo sia un bug in SpriteKit. (Sono stato in grado di riprodurre questo problema con SpriteKit 7.1).

ecco un breve soluzione:

- (void) didBeginContact:(SKPhysicsContact *)contact 
{ 
    contact.bodyB.node.position = CGPointMake(newX, newY); 
    contact.bodyB.node.physicsBody = contact.bodyB.node.physicsBody; // <-- Add this line 
} 
+1

Funziona correttamente. Ho appena cambiato un po 'l'ultima riga: 'contact.bodyB.node.physicsBody = contact.bodyB.node.physicsBody;' – fiddler

0

soluzione JKallio non ha funzionato per me (Xcode 7.2.1 su OS X 10.10.5, il targeting iOS 8.1). Ho capito che ero in grado di cambiare la posizione nel metodo update:, quindi ho aggirato il bug impostando un flag in didBeginContact e cambiando la posizione in update:.

@implementation GameScene { 
    SKNode *_victim; 
    CGPoint _target; 
} 

- (void)didMoveToView:(SKView *)view { 
    _victim = nil; 
} 

- (void)didBeginContact:(SKPhysicsContact *)contact { 
    _victim = contact.bodyB.node; 
    _target = CGPointMake(newX, newY); 
} 

- (void)update:(CFTimeInterval)currentTime { 
    if (_victim != nil) { 
     _victim.position = _target; 
     _victim = nil; 
    } 
} 

@end 

noti che _victim serve sia il nodo e la bandiera.

La mia soluzione è più complicata di quella di JKallio; provalo prima di arrivare a questo.

0

Come altra soluzione per una soluzione alternativa, invece chiamo un metodo in una sottoclasse SKSpriteNode per l'oggetto che voglio spostare, passando in quel corpo. La posizione viene impostata correttamente.

/* In GameScene.swift */ 

func didBegin(_ contact: SKPhysicsContact) { 
    let dotBody: SKPhysicsBody 
    if contact.bodyA.categoryBitMask == 0b1 { 
     dotBody = contact.bodyB 
    } else { 
     dotBody = contact.bodyA 
    } 

    if let dot = dotBody.node as? Dot { 
     dot.move() 
    }   
} 

Ecco la classe Dot:

import SpriteKit 
class Dot : SKSpriteNode { 
    let dotTex = SKTexture(imageNamed: "dot") 
    init() { 
     super.init(texture: dotTex, color: .clear, size: dotTex.size()) 
     self.physicsBody = SKPhysicsBody(circleOfRadius: size.width/2) 
     self.physicsBody?.categoryBitMask = 0b1 << 1 
     self.physicsBody?.contactTestBitMask = 0b1 
    } 

    func move() { 
     let reset = SKAction.run { 
      self.position.x = 10000 
     } 
     self.run(reset) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 
} 
Problemi correlati