1
votes

I have created a hero node and enemy node, when they collide,game over.But I have problem with precise collision. Sometimes there is overlap.Sometimes collision happens when one node doesn't reach the other's frame. can anybody give me some advise? appreciate your help~

my hero is affected by gravity, when tap, it will change the direction of gravity.

following is some of my code:

-(void)addRectHero {
rectHero = [SKSpriteNode spriteNodeWithImageNamed:@“hero.png”];

rectHero.scale = 0.2;
rectHero.position = CGPointMake(self.size.width/2, self.size.height*0.3);
rectHero.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rectHero.size];
rectHero.physicsBody.restitution = 0.0;
rectHero.physicsBody.allowsRotation = NO;

rectHero.physicsBody.dynamic = YES;
rectHero.physicsBody.affectedByGravity=NO;

rectHero.physicsBody.categoryBitMask = heroCategory;
rectHero.physicsBody.contactTestBitMask = enemyCategory;
rectHero.zPosition = 100;
rectHero.physicsBody.collisionBitMask = enemyCategory;
rectHero.physicsBody.usesPreciseCollisionDetection = YES;

[self addChild:rectHero];

}

-(void)createEnemy{


randomStartPoint =(float)((random()%(int)(self.size.height/3))+self.size.height/3);
startPoint = CGPointMake(self.size.width + 50, randomStartPoint);  



enemyNode = [SKSpriteNode spriteNodeWithImageNamed:@"enemy_4.png"];

enemyNode.scale =0.5;


enemyNode.position = startPoint;
enemyNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:enemyNode.size];
enemyNode.physicsBody.dynamic = NO;
enemyNode.physicsBody.categoryBitMask = enemyCategory;
enemyNode.physicsBody.contactTestBitMask = heroCategory;
enemyNode.physicsBody.collisionBitMask = heroCategory;
enemyNode.physicsBody.usesPreciseCollisionDetection = YES;
enemyNode.physicsBody.allowsRotation = NO;
enemyNode.physicsBody.restitution = 0.0;

enemyNode.name = @"enemy";


[self addChild:enemyNode];

}


-(void)didBeginContact:(SKPhysicsContact *)contact{
if (!_gameIsOn) {
    return;
}

SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask<contact.bodyB.categoryBitMask) {
    firstBody = contact.bodyA;
    secondBody = contact.bodyB;
}
else
{
    firstBody=contact.bodyB;
    secondBody=contact.bodyA;
}




if (firstBody.categoryBitMask == heroCategory && secondBody.categoryBitMask == enemyCategory) {

   [self runAction:sound_play completion:^{
        [self gameOver];

    }];

    [self stopTimer];


    }
}

I create a lot of enemies in update method: (I also tried self repeatActionForever method to create enemy but the problem still exists)

-(void)update:(CFTimeInterval)currentTime {


if (_lastTime)
{
    _dt = currentTime - _lastTime;
}
else
{
    _dt = 0;
}
_lastTime = currentTime;


if( currentTime - _lastEnemyAdded > 1 && _gameIsOn)
{
    _lastEnemyAdded = currentTime + 1;
    [self createEnemy];
    }

}
1
If you create and add a node which overlaps an existing node, you will not get a contact flag. - sangony
@sangony I mean some parts of the nodes overlap,not pass through. the collision happens but not so precisely. - karenkey
I don't understand what you are saying. Collisions either happen or they do not. What do you mean by "not so precisely" ? - sangony
@sangony sorry for the poor explanation...... in my understanding, sprite_1 should reach sprite_2's edge(every image has a certain shape ),then they collide. But my game's collision happens when the two nodes seems like a gap between them...they should move closer to collide...I am thinking whether I have set wrong method about physicsbody.... - karenkey
@sangony i want them to collide at the exact moment when sprite_1's image edge reaches sprite_2's image edge. - karenkey

1 Answers

0
votes

In your ViewController make sure you have skView.showsPhysics = YES; Run your game again and look if your physics bodies are what you expect them to be. It sounds like you are creating a larger physics body than what you want.

If the issue ends up being a larger than desired physics body, try creating a physics body like this:

// to create a circular physics body
self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10 center:CGPointMake(0, 0)];

// to create a rect physics body
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(20, 20) center:CGPointMake(0, 0)];

Use the center coordinates to properly center the body.

To create a physics body made up of more than one shape, you can do something like this:

SKPhysicsBody *firstBody = [SKPhysicsBody bodyWithCircleOfRadius:20 center:CGPointMake(0, 0)];
SKPhysicsBody *secondBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(20, 20) center:CGPointMake(0, 20)];
self.physicsBody = [SKPhysicsBody bodyWithBodies:@[firstBody, secondBody]];