SpriteKit:无法在联系人回调中更改节点位置
Posted
技术标签:
【中文标题】SpriteKit:无法在联系人回调中更改节点位置【英文标题】:SpriteKit: cannot change node position in contact callback 【发布时间】:2014-04-02 11:38:52 【问题描述】:我有一个带有动态物理体的节点。我想让它静止并在它与另一个身体接触时改变它的位置。
我设法使用此问题中提供的解决方案使正文保持静态:Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)
但是,如果我在其中一种联系回调方法(例如 didBeginContact
)中更改节点的 position
属性,则不会考虑新位置。
我怎样才能做到这一点?
【问题讨论】:
能否贴出无法更新位置的代码,以及您如何实现链接到的解决方案? @LearnCocos2D JKallio 给出的解决方案工作正常(将physicsBody 重新分配给它的节点) 【参考方案1】:我相信这是 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
【讨论】:
它工作正常。我只是稍微改变了最后一行:contact.bodyB.node.physicsBody = contact.bodyB.node.physicsBody;
【参考方案2】:
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 的更复杂;在来之前试试那个。
【讨论】:
【参考方案3】:作为解决方法的另一个选项,我改为在 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()
这是 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)
【讨论】:
以上是关于SpriteKit:无法在联系人回调中更改节点位置的主要内容,如果未能解决你的问题,请参考以下文章
无法修改 didBeginContact 中的contact.bodyA
带有 AVAudioPlayerNode 的 SpriteKit 位置音频