2014-04-02 38 views
6

我有一個具有動態物理主體的節點。我想讓它變得靜止,並在與其他機構接觸時改變它的位置。SpriteKit:無法更改聯繫人回調中的節點位置

我設法使人體靜電與這個問題提供瞭解決方案:Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)

但是,如果我改變節點的position財產的接觸回調方法之一(例如didBeginContact)的新位置不考慮到。

我怎麼能做到這一點?

+0

您可以發佈失敗更新的位置代碼,以及你如何實現你解掛? – LearnCocos2D

+0

@ LearnCocos2D JKallio給出的解決方案正常工作(重新分配physicalBody到其節點) – fiddler

回答

6

我認爲這是SpriteKit中的一個錯誤。 (我可以用SpriteKit 7.1重現這個問題)。

這裏是一個快速的解決方法:

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

它工作正常。我只是改變了最後一行:'contact.bodyB.node.physicsBody = contact.bodyB.node.physicsBody;' – fiddler

0

JKallio的解決方案並沒有爲我(在OS X 10.10.5的Xcode 7.2.1,中定位iOS 8.1)工作。我發現我能夠在update:方法中改變位置,所以我通過在didBeginContact中設置了一個標誌並更改了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 

注意_victim作爲節點和標誌兩者。

我的解決方案比JKallio更復雜;在來這之前嘗試一個。

0

作爲變通方法的另一種選擇,我改爲在SKSpriteNode的子類中爲要移動的對象調用方法,並傳入該對象。位置設置正確。

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

這裏是點類:

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