IOS SpriteKit Colision Detection: Resetting Position of an Object

前端 未结 1 1469
悲哀的现实
悲哀的现实 2021-01-25 12:39

I\'m working on Collision Detection where the hope is when Object1 moves down the screen and eventually hits Object2 it triggers the didBeginContact method and in turn, the rese

相关标签:
1条回答
  • 2021-01-25 13:17

    You should take a look at run loop. Nothing is drawn before physics simulation is done. So I guess that changing position like you are doing is overwritten by physics simulation.

    This is the order of run loop:

    • update is called
    • scene evaluate actions
    • didEvaluateActions is called
    • physics simulation goes here
    • didSimulatePhysics is called
    • scene applies constraints
    • didApplyConstraints is called
    • didFinishUpdate is called
    • rendering the frame

    I could bet if you move repositioning of node in didSimulatePhysics instead of doing it in didBeginContact that everything will work. I guess this is happening because you are trying to change node's position before simulation is done. You can try this code (look at didSimulatePhysics part):

    #import "GameScene.h"
    
    typedef enum uint_8{
        ColliderWall = 1,
        ColliderPlayer = 2,
        ColliderBrick =  4
    }CollisionCategory;
    
    
    @interface Object1 : SKSpriteNode
    
    @end
    
    @implementation Object1
    
    -(instancetype)initWithColor:(UIColor *)color size:(CGSize)size{
    
        if(self = [super initWithColor:color size:size]){
    
    
            self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
    
            self.physicsBody.categoryBitMask = ColliderPlayer;
            self.physicsBody.contactTestBitMask = ColliderBrick;
            self.physicsBody.collisionBitMask = ColliderBrick | ColliderWall;
            self.physicsBody.dynamic = YES;
            self.physicsBody.affectedByGravity = YES;
            self.physicsBody.allowsRotation = NO;
    
        }
        return self;
    }
    
    
    
    @end
    
    @interface GameScene  ()<SKPhysicsContactDelegate>
    
    @property (nonatomic, strong) Object1 *player;
    @property (nonatomic, strong) SKSpriteNode *brick;
    
    @property (nonatomic, assign) BOOL shouldMove;
    
    @end
    
    @implementation GameScene
    
    -(void)didMoveToView:(SKView *)view {
        /* Setup your scene here */
    
        _shouldMove = NO;
    
        self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
        self.physicsBody.contactTestBitMask = 0;
        self.physicsBody.collisionBitMask =  ColliderPlayer;
        self.physicsBody.categoryBitMask = ColliderWall;
    
        self.physicsWorld.contactDelegate = self;
    
        _player = [[Object1 alloc] initWithColor:[SKColor greenColor] size:CGSizeMake(50,30)];
        _player.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame)- _player.size.height-30);
        [self addChild:_player];
    
        _brick = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(330,80)];
        _brick.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_brick.size];
        _brick.position = CGPointMake(CGRectGetMidX(self.frame),100);
        _brick.physicsBody.contactTestBitMask = ColliderPlayer;
        _brick.physicsBody.collisionBitMask = ColliderPlayer;
        _brick.physicsBody.categoryBitMask = ColliderBrick;
        _brick.physicsBody.affectedByGravity = NO;
        _brick.physicsBody.dynamic = NO;
    
        [self addChild:_brick];
    
    
    }
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        /* Called when a touch begins */
    
        for (UITouch *touch in touches) {
    
            [self.player.physicsBody applyImpulse:CGVectorMake(0,55)];
    
        }
    }
    
    -(void)didBeginContact:(SKPhysicsContact *)contact{
    
        NSLog(@"Contact");
    
        self.shouldMove = YES;
    
    }
    
    -(void)didSimulatePhysics{
    
        if(self.shouldMove){
    
    
            self.player.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame)- _player.size.height-30);
    
    
            self.shouldMove = NO;
        }
    }
    
    
    @end
    
    0 讨论(0)
提交回复
热议问题