菜鸟教程小白 发表于 2022-12-13 09:03:19

ios - SpriteKit 拖放穿墙


                                            <p><p>我在 SpriteKit 中使用物理进行了简单的拖放操作。它按预期工作,但是当我使用快速拖动时,元素穿过墙壁。 </p>

<p>self.runner 是墙</p>

<p>self.runner2 是方形的</p>

<p>墙的动态设置为 NO。 </p>

<p>电影展示了一切:<a href="https://www.dropbox.com/s/ozncf9i16o1z80o/spritekit_sample.mov?dl=0" rel="noreferrer noopener nofollow">https://www.dropbox.com/s/ozncf9i16o1z80o/spritekit_sample.mov?dl=0</a> </p>

<p>在模拟器和真机上测试,都是 iOS 7。</p>

<p>我想防止方 block 穿墙。有任何想法吗? </p>

<pre><code>#import &#34;MMMyScene.h&#34;

static NSString * const kRunnerImg = @&#34;wall.png&#34;;
static NSString * const kRunnerName = @&#34;runner&#34;;

static NSString * const kRunnerImg2 = @&#34;zebraRunner.png&#34;;
static NSString * const kRunnerName2 = @&#34;runner&#34;;

static const int kRunnerCategory = 1;
static const int kRunner2Category = 2;
static const int kEdgeCategory = 3;


@interface MMMyScene () &lt;SKPhysicsContactDelegate&gt;

@property (nonatomic, weak) SKNode *draggedNode;
@property (nonatomic, strong) SKSpriteNode *runner;
@property (nonatomic, strong) SKSpriteNode *runner2;

@end

@implementation MMMyScene

-(id)initWithSize:(CGSize)size {   
    if (self = ) {
      self.backgroundColor = ;

      self.runner = ;
      self.runner.texture = ;
      ;

      ;
      ;
      ;

      self.runner.physicsBody = ;
      self.runner.physicsBody.categoryBitMask = kRunnerCategory;
      self.runner.physicsBody.contactTestBitMask = kRunner2Category;
      self.runner.physicsBody.collisionBitMask =kRunner2Category;
      self.runner.physicsBody.dynamic = NO;
      self.runner.physicsBody.allowsRotation = NO;

      self.runner2 = ;
      ;

      ;
      ;

      self.runner2.physicsBody = ;
      self.runner2.physicsBody.categoryBitMask = kRunner2Category;
      self.runner2.physicsBody.contactTestBitMask = kRunnerCategory;
      self.runner2.physicsBody.collisionBitMask = kRunnerCategory;
      self.runner2.physicsBody.dynamic = YES;
      self.runner2.physicsBody.allowsRotation = NO;

      ;

      self.physicsBody = ;
      self.physicsBody.categoryBitMask = kEdgeCategory;
      self.physicsBody.collisionBitMask = 0;
      self.physicsBody.contactTestBitMask = 0;
      self.physicsWorld.gravity = CGVectorMake(0,0);
      self.physicsWorld.contactDelegate = self;      
    }

    return self;
}

- (void)didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody, *secondBody;

firstBody = contact.bodyA;
secondBody = contact.bodyB;

if(firstBody.categoryBitMask == kRunnerCategory )
{
    NSLog(@&#34;collision&#34;);
    //self.draggedNode = nil;

}
}

- (void)didMoveToView:(SKView *)view {
UIPanGestureRecognizer *gestureRecognizer = [ initWithTarget:self action:@selector(handlePanFrom:)];
[ addGestureRecognizer:gestureRecognizer];
}

- (void)panForTranslation:(CGPoint)translation {
CGPoint position = ;
if([ isEqualToString:kRunnerName]) {
    ;
}
}

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
    CGPoint touchLocation = ;
    touchLocation = ;
    ;
}
else if (recognizer.state == UIGestureRecognizerStateChanged) {
    CGPoint translation = ;
    translation = CGPointMake(translation.x, -translation.y);
    ;
    ;
}
}

- (void)selectNodeForTouch:(CGPoint)touchLocation {
SKSpriteNode *touchedNode = (SKSpriteNode *);

if(!) {
    self.draggedNode = touchedNode;
    //    self.draggedNode.physicsBody.affectedByGravity = NO;
}
}


@end
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您正在直接设置节点的位置,这会绕过碰撞检测。如果你移动得很快,下一个位置可以在墙的另一边(或者足够近,以便物理将通过将拖动的节点移动到墙的外部和上方来解决碰撞)。 </p>

<p>在动态主体上启用 <code>usesPreciseCollisionDetection</code> 可能会改善这种情况,但可能无法完全阻止它。实际上它可能没有任何区别,因为直接设置节点位置而不是使用力/脉冲移动 body 。</p>

<p>要解决此问题,您不能依赖联系人事件。而是使用 <a href="https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKPhysicsWorld_Ref/index.html#//apple_ref/occ/instm/SKPhysicsWorld/bodyAlongRayStart:end:" rel="noreferrer noopener nofollow">bodyAlongRayStart:end:</a>确定节点的当前位置和下一个位置之间是否存在阻塞体。即便如此,这只适用于您当前的设置,但无法阻止光线成功通过动态物体无法穿过的墙壁上的小间隙。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - SpriteKit 拖放穿墙,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/25936345/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/25936345/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - SpriteKit 拖放穿墙