Пример #1
0
    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
Пример #2
0
    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))