2014-04-02 8 views
6

Mam węzeł z dynamicznym ciałem fizyki. Chciałbym uczynić go statycznym i zmienić jego pozycję, gdy wchodzi w kontakt z innym ciałem.SpriteKit: nie można zmienić pozycji węzła w wywołaniu kontaktowym

udało mi się sprawić, że ciało statyczne z rozwiązaniem przewidzianym w tej kwestii: Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)

Jednak w przypadku zmiany właściwości węzła position w jednej z metod kontaktu zwrotnych (np didBeginContact) Nowa pozycja nie jest uwzględnić.

Jak mogę to osiągnąć?

+0

można pisać kod, który nie działa w celu aktualizowania położenia, a także w jaki sposób wdrażane rozwiązania, których powiązany? – LearnCocos2D

+0

@ LearnCocos2D Rozwiązanie podane przez JKallio działa poprawnie (przypisanie elementu fizycznego do węzła) – fiddler

Odpowiedz

6

Wierzę, że jest to błąd w SpriteKit. (Byłem w stanie odtworzyć ten problem z SpriteKit 7.1).

Oto szybkie obejście:

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

Działa poprawnie. Właśnie zmieniłem nieco ostatnią linię: 'contact.bodyB.node.physicsBody = contact.bodyB.node.physicsBody;' – fiddler

0

rozwiązanie JKallio za nie działa dla mnie (Xcode 7.2.1 na OS X 10.10.5, kierowanie iOS 8.1). Zorientowałem się, że udało mi się zmienić pozycję w metodzie update:, więc udało mi się obejść błąd przez ustawienie flagi w didBeginContact i zmianę pozycji w 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 

Należy pamiętać, że _victim służy zarówno jako węzeł, jak i flaga.

Moje rozwiązanie jest bardziej skomplikowane niż JKallio; spróbuj tego przed przyjściem.

0

Jako kolejna opcja obejścia problemu, zamiast tego wywołuję metodę w podklasie SKSpriteNode dla obiektu, który chcę przenieść, przekazując w tym ciele. Pozycja zostanie poprawnie ustawiona.

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

Oto klasa 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) 
    } 
} 
Powiązane problemy