def has_planet(self, x, y): if x <= 0 or x >= self._game.map.width or y <= 0 or y >= self._game.map.height: return True pos = Position(x, y) for planet in self._game.map.all_planets(): if pos.calculate_distance_between( planet) <= planet.radius + .50001: return True return False
def avoid_collision(self, ship, entity, collision): logging.info('Avoid Collision') logging.info(ship) logging.info(entity) logging.info(collision) # We want to modifiy how much the ship moves based on # If the ship is close to the target, deviate less # If the ship is going slow, deviate less (will not move if speed is 0) if ship.distance_to_target == 0 and entity.distance_to_target == 0: # They both reached their targets init_ship_modifier = (ship.magnitude / hlt.constants.MAX_SPEED) init_entity_modifier = (entity.magnitude / hlt.constants.MAX_SPEED) else: init_ship_modifier = (ship.magnitude / hlt.constants.MAX_SPEED) * \ (ship.distance_to_target / (ship.distance_to_target + entity.distance_to_target)) init_entity_modifier = (entity.magnitude / hlt.constants.MAX_SPEED) * \ (entity.distance_to_target / (entity.distance_to_target + ship.distance_to_target)) if init_ship_modifier == 0 and init_entity_modifier == 0: return # They are already colliding... ship_modifier = init_ship_modifier / (init_ship_modifier + init_entity_modifier) entity_modifier = init_entity_modifier / (init_ship_modifier + init_entity_modifier) logging.info('ship_modifer: {} entity_modifer: {}'.format( ship_modifier, entity_modifier)) if ship.magnitude == 0 and entity.magnitude == 0: raise (Exception('Both ships are not moving...')) # Note: By always taking the shortest path to something the rotation + distance modifier # should (almost) always keep the ship in range of the target # TODO: Check if the ships paths cross (below only works for co-liniar # Find where the collision first happened t = collision[3] ship_position = Position(ship.x + ship.vel_x * t, ship.y + ship.vel_y * t) entity_position = Position(entity.x + entity.vel_x * t, entity.y + entity.vel_y * t) logging.info( 'collision happened at ship_position: {} entity_position: {}'. format(ship_position, entity_position)) # Work out the closest point they meet ship_velocity_step = Position(ship.vel_x / VELOCITY_STEPS, ship.vel_y / VELOCITY_STEPS) entity_velocity_step = Position(entity.vel_x / VELOCITY_STEPS, entity.vel_y / VELOCITY_STEPS) logging.info('velocity step ship: {} entity: {}'.format( ship_velocity_step, entity_velocity_step)) min_distance = math.inf velocity_step = None min_ship_position = None min_entity_position = None for step in range(VELOCITY_STEPS): current_ship_position = Position( ship_position.x + ship_velocity_step.x * step, ship_position.y + ship_velocity_step.y * step) current_entity_position = Position( entity_position.x + entity_velocity_step.x * step, entity_position.y + entity_velocity_step.y * step) distance = current_ship_position.calculate_distance_between( current_entity_position) if distance < min_distance: min_distance = distance velocity_step = step min_ship_position = current_ship_position min_entity_position = current_entity_position logging.info('min distance {}'.format(min_distance)) # Required distance required_distance = ship.radius + entity.radius distance_to_deflect = required_distance - min_distance logging.info('required_distance {}, distance_to_reflect'.format( required_distance, distance_to_deflect)) if ship.docking_status != ship.DockingStatus.UNDOCKED: logging.info('Ship is docked') elif ship.magnitude == 0: logging.info( 'Entity is not moving atm (it may have just started to dock)') else: new_ship_angle = self.get_deflected_angle( ship, entity, distance_to_deflect * ship_modifier) ship.thrust(ship.magnitude, new_ship_angle) #logging.info('new_ship_angle {}, ship.magnitude'.format(ship.magnitude, new_ship_angle)) if isinstance(entity, hlt.entity.Planet): logging.info('Entity is planet') elif entity.docking_status != entity.DockingStatus.UNDOCKED: logging.info('Entity is docked') elif entity.magnitude == 0: logging.info( 'Entity is not moving atm (it may have just started to dock)') else: new_entity_angle = self.get_deflected_angle( entity, ship, distance_to_deflect * entity_modifier) entity.thrust(entity.magnitude, new_entity_angle) logging.info('new_entity_angle {}, entity.magnitude'.format( new_entity_angle, entity.magnitude))