2014-04-02 3 views
6

Ich habe einen Knoten mit einem dynamischen Physikkörper. Und ich möchte es statisch machen und seine Position ändern, wenn es mit einem anderen Körper in Kontakt kommt.SpriteKit: kann Knotenposition im Kontaktrückruf nicht ändern

ich es geschafft, die statische Aufladung Ihres Körpers mit der Lösung in dieser Frage zur Verfügung gestellt zu machen: Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)

Allerdings, wenn ich die position Eigenschaft des Knotens in einem der Kontaktcallback-Methoden (zB didBeginContact) die neue Position nicht ändern ist berücksichtigt.

Wie konnte ich das erreichen?

+0

können Sie nach dem Code, der die Position zu aktualisieren, fehlschlägt, sowie, wie Sie die Lösung, die Sie verknüpft umgesetzt? – LearnCocos2D

+0

@ LearnCocos2D die Lösung von JKallio funktioniert gut (Zuweisung der physicsBody zu seinem Knoten) – fiddler

Antwort

6

Ich glaube, das ist ein Fehler in SpriteKit. (Ich konnte dieses Problem mit SpriteKit 7.1 reproduzieren).

Hier ist eine schnelle Abhilfe:

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

Es funktioniert gut. Ich habe nur ein bisschen die letzte Zeile geändert: 'contact.bodyB.node.physicsBody = contact.bodyB.node.physicsBody;' – fiddler

0

JKallio Lösung nicht für mich arbeiten (Xcode 7.2.1 auf OS X 10.10.5, Targeting iOS 8.1). Ich fand heraus, dass ich in der Lage war, die Position in update: Methode zu ändern, also habe ich den Fehler durch Setzen einer Flagge in didBeginContact und Ändern der Position 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 

anzumerken, dass _victim sowohl als Knoten dient und die Flagge.

Meine Lösung ist komplizierter, dass JKallio; versuchen Sie es, bevor Sie hierher kommen.

0

Als eine weitere Option für eine Problemumgehung, rufen Sie stattdessen eine Methode in einer SKSpriteNode Unterklasse für das Objekt, das ich verschieben möchte, übergeben in diesem Körper. Die Position wird korrekt eingestellt.

/* 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() 
    }   
} 

Hier ist die Dot-Klasse:

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