void Ship::collide(ew::Collidable const* other) { if(dead) return; Vec2D position = getPosition(); if(typeid(*other) == typeid(Asteroid)) { if(immortalityLeft > 0) return; Asteroid const* asteroid = static_cast<Asteroid const*>(other); if(shape.collidesWith(asteroid->getShape())) { if(shields <= 0) { die(); } else { shields -= 1; float speed = asteroid->getVelocity().projection(position.subtract(asteroid->getPosition())).subtract(v).length(); v = position.subtract(asteroid->getPosition()).uniti().scale(speed); } } return; } if(typeid(*other) == typeid(UfoLaser)) { if(immortalityLeft > 0) return; UfoLaser const* ufoLaser = static_cast<UfoLaser const*>(other); if(shape.collidesWith(ufoLaser->getShape())) { if(shields <= 0) { die(); } else { shields -= 1; v += ufoLaser->getVelocity().scale(0.1); } } return; } if(typeid(*other) == typeid(Ufo)) { if(immortalityLeft > 0) return; Ufo const* ufo = static_cast<Ufo const*>(other); if(shape.collidesWith(ufo->getShape())) { if(shields <= 0) { die(); } else { shields -= 1; } } return; } if(typeid(*other) == typeid(Powerup)) { Powerup const* powerup = static_cast<Powerup const*>(other); if(powerup->alive() && shape.collidesWith(powerup->getShape())) { if(powerup->getType() == Powerup::LASER) { increaseLaserLevel(); } else if(powerup->getType() == Powerup::SPREAD) { increaseSpreadLevel(); } else if(powerup->getType() == Powerup::BEAM) { increaseBeamLevel(); } else if(powerup->getType() == Powerup::PLASMA) { increasePlasmaLevel(); } else if(powerup->getType() == Powerup::EXTRALIFE) { gameWorld->player.lives += 1; new GameNotification(gameWorld, "1up", POWERUP_TEXT_SIZE, 1.0, getPosition()); } else if(powerup->getType() == Powerup::LOSELIFE) { gameWorld->player.lives -= 1; new GameNotification(gameWorld, "-1up", POWERUP_TEXT_SIZE, 1.0, getPosition()); } else if(powerup->getType() == Powerup::SHIELD) { shields += 1; new GameNotification(gameWorld, "Shield +1", POWERUP_TEXT_SIZE, 1.0, getPosition()); } } return; } }