Created
March 8, 2015 00:07
-
-
Save lantins/2216a4befe96ea3cca81 to your computer and use it in GitHub Desktop.
snipped of simple collision detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)collisionDetection | |
{ | |
if (state != kSPECTRA_STATE_ACTIVE) { | |
return; | |
} | |
NSMutableIndexSet *bulletsToRemove = [[NSMutableIndexSet alloc] init]; | |
NSMutableIndexSet *asteroidsToRemove = [[NSMutableIndexSet alloc] init]; | |
if (player.isNormal) { | |
// asteroid vs player collision. | |
for (Sprite *asteroid in asteroidSprites) { | |
// continue to the next element if no collision. | |
if ([self checkForCollisionWrapped:asteroid :player.shipSprite] == false) continue; | |
// stop engine, if its running. | |
[self shutdownEngine]; | |
// uoh, the player died. | |
[player died]; | |
// ship hitting roid should act the same as a bullet, split it. | |
[asteroidsToRemove addIndex:[asteroidSprites indexOfObject:asteroid]]; | |
// only allow one asteroid to be destoryed. | |
break; | |
} | |
} | |
// bullet vs asteroid collision. | |
for (AsteroidSprite *asteroid in asteroidSprites) { | |
for (Sprite *bullet in bulletSprites) { | |
// continue to the next element if no collision. | |
if ([self checkForCollisionWrapped:asteroid :bullet] == false) continue; | |
// remember to remove bullet later. | |
[bulletsToRemove addIndex:[bulletSprites indexOfObject:bullet]]; | |
[asteroidsToRemove addIndex:[asteroidSprites indexOfObject:asteroid]]; | |
// add to player score. | |
[player destroyedAsteroid:asteroid]; | |
// play explosion sound. | |
[[soundSystem explodeSound] play]; | |
// only allow one asteroid to be destoryed. | |
break; | |
} | |
} | |
// split into smaller asteroids if it was shot. | |
unsigned asteroidIndex; | |
for (asteroidIndex = [asteroidsToRemove firstIndex]; asteroidIndex != NSNotFound; asteroidIndex = [asteroidsToRemove indexGreaterThanIndex: asteroidIndex]) { | |
AsteroidSprite *hitAsteroid = [asteroidSprites objectAtIndex:asteroidIndex]; | |
// explosion sprite. | |
ExplosionSprite *explosion; | |
for (int i = 0; i < 20; i++) { | |
explosion = [[ExplosionSprite alloc] init]; | |
explosion.x = hitAsteroid.x; | |
explosion.y = hitAsteroid.y; | |
[effectSprites addObject:explosion]; | |
} | |
// if the asteroid is level 3, do not spawn any more smaller asteroids. | |
if (hitAsteroid.level == 3) { | |
break; | |
} | |
GLint newLevel = hitAsteroid.level + 1; | |
// create smaller asteroids. | |
AsteroidSprite *asteroid; | |
for (int i = 0; i < 2; i++) { | |
asteroid = [[AsteroidSprite alloc] initAtLevel:newLevel]; | |
asteroid.x = hitAsteroid.x; | |
asteroid.y = hitAsteroid.y; | |
// add to array. | |
[asteroidSprites addObject:asteroid]; | |
} | |
} | |
// delete shot asteroids. | |
[asteroidSprites removeObjectsAtIndexes:asteroidsToRemove]; | |
[bulletSprites removeObjectsAtIndexes:bulletsToRemove]; | |
} | |
- (BOOL)checkForCollision:(Sprite *)sprite1 :(Sprite *)sprite2 | |
{ | |
// difference between centres. | |
GLfloat dist_x = sprite1.x - sprite2.x; | |
GLfloat dist_y = sprite1.y - sprite2.y; | |
// distance with pythagoras. | |
GLfloat dist = sqrt((dist_x * dist_x) + (dist_y * dist_y)); | |
// collision? | |
return dist <= ((sprite1.collisionRadius) + (sprite2.collisionRadius)); | |
} | |
- (BOOL)checkForCollisionWrapped:(Sprite *)sprite1 :(Sprite *)sprite2 | |
{ | |
// check current location. | |
if ([self checkForCollision:sprite1 :sprite2]) { | |
return true; | |
} | |
BOOL checkWrapped = false; | |
GLfloat collisionRadius = [sprite1 collisionRadius]; | |
Sprite *wrappedSprite = [[Sprite alloc] init]; | |
wrappedSprite.x = sprite1.x; | |
wrappedSprite.y = sprite1.y; | |
if (sprite1.x < collisionRadius) { | |
checkWrapped = true; | |
wrappedSprite.x = kSPECTRA_WORLD_X_MAX + sprite1.x; | |
} | |
if (sprite1.x > (kSPECTRA_WORLD_X_MAX - collisionRadius)) { | |
checkWrapped = true; | |
wrappedSprite.x = sprite1.x - collisionRadius - (kSPECTRA_WORLD_X_MAX - collisionRadius); | |
} | |
if (sprite1.y < collisionRadius) { | |
checkWrapped = true; | |
wrappedSprite.y = kSPECTRA_WORLD_Y_MAX + sprite1.y; | |
} | |
if (sprite1.y > (kSPECTRA_WORLD_Y_MAX - collisionRadius)) { | |
checkWrapped = true; | |
wrappedSprite.y = sprite1.y - collisionRadius - (kSPECTRA_WORLD_Y_MAX - collisionRadius); | |
} | |
// check wrapped location if required. | |
if (checkWrapped) { | |
return [self checkForCollision:wrappedSprite :sprite2]; | |
} | |
// otherwise, no collision. | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment