我有一个带动态物理体的节点。而且我想让它静止,并在与另一个身体接触时改变它的位置。
我设法使用此问题中提供的解决方案使身体保持静止:Sprite Kit failing assertion: (typeA == b2_dynamicBody || typeB == b2_dynamicBody)
但是,如果我在其中一个联系人回调方法中更改节点的position
属性(例如didBeginContact
),则不会考虑新位置。
我怎么能实现这个目标?
答案 0 :(得分: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 :(得分: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更复杂;在来之前尝试那个。
答案 2 :(得分: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()
}
}
这是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)
}
}