Exemple #1
0
class Arrive(Maneuver):
    def __init__(self,
                 car: Car,
                 target=vec3(0, 0, 0),
                 time=0,
                 target_direction: vec3 = None):
        super().__init__(car)

        self.target_direction = target_direction
        self.target = target
        self.time = time
        self.drive = Drive(car, target)
        self.travel = Travel(car)
        self.lerp_t = 0.6

    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_vel = norm(car.vel)
            target_direction = normalize(self.target_direction)
            shift = clamp(
                distance(car.pos, target) * self.lerp_t, 0, car_vel * 1.5)
            if shift < turn_radius(clamp(car_vel, 1400, 2000) * 1.1):
                shift = 0
            translated_target = target - target_direction * shift

            translated_time = self.time - distance(
                translated_target, target) / max(1, clamp(car_vel, 500, 2300))
        else:
            translated_target = target
            translated_time = self.time

        self.drive.target_pos = translated_target
        dist_to_target = distance(car.pos, translated_target)
        target_speed = clamp(
            dist_to_target / max(0.001, translated_time - car.time), 0, 2300)

        self.drive.target_speed = target_speed

        if car.boost < 1 and dist_to_target > 3000:
            self.travel.target = target
            self.travel.step(dt)
            self.controls = self.travel.controls
        else:
            self.drive.step(dt)
            self.controls = self.drive.controls

        self.finished = self.car.time >= self.time
        return self.finished

    def render(self, draw: DrawingTool):
        self.drive.render(draw)

        if self.target_direction is not None:
            draw.color(draw.lime)
            draw.triangle(self.target - self.target_direction * 250,
                          self.target_direction)
Exemple #2
0
class Arrive(Maneuver):
    """
    Arrive at a target position at a certain time (game seconds).
    You can also specify `target_direction`, and it will try to arrive
    at an angle. However this does work well only if the car is already
    roughly facing the specified direction, and only if it's far enough.
    """
    def __init__(self, car: Car):
        super().__init__(car)
        self.drive = Drive(car)
        self.travel = Travel(car)
        self.action = self.drive

        self.target_direction: Optional[None] = None
        self.target: vec3 = None
        self.arrival_time: float = 0
        self.backwards: bool = False

        self.lerp_t = 0.57
        self.allow_dodges_and_wavedashes: bool = True
        self.additional_shift = 0

    def interruptible(self) -> bool:
        return self.action.interruptible()

    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_speed = norm(car.velocity)
            target_direction = normalize(self.target_direction)

            # in order to arrive in a direction, we need to shift the target in the opposite direction
            # the magnitude of the shift is based on how far are we from the target
            shift = clamp(
                ground_distance(car.position, target) * self.lerp_t, 0,
                car_speed * 1.5)

            # if we're too close to the target, aim for the actual target so we don't miss it
            if shift - self.additional_shift < turn_radius(
                    clamp(car_speed, 1400, 2000) * 1.1):
                shift = 0
            else:
                shift += self.additional_shift

            shifted_target = target - target_direction * shift

            time_shift = ground_distance(shifted_target, target) * 0.7 / clamp(
                car_speed, 500, 2300)
            shifted_arrival_time = self.arrival_time - time_shift

        else:
            shifted_target = target
            shifted_arrival_time = self.arrival_time

        self.drive.target_pos = shifted_target
        self.travel.target = shifted_target

        dist_to_target = ground_distance(car.position, shifted_target)
        time_left = nonzero(shifted_arrival_time - car.time)
        target_speed = clamp(dist_to_target / time_left, 0, 2300)
        self.drive.target_speed = target_speed
        self.drive.backwards = self.backwards

        if ((self.allow_dodges_and_wavedashes
             and norm(car.velocity) < target_speed - 600 and car.boost < 20
             and not self.backwards)
                or not self.travel.driving  # a dodge/wavedash is in progress
            ):
            self.action = self.travel
        else:
            self.action = self.drive

        self.action.step(dt)
        self.controls = self.action.controls

        self.finished = self.car.time >= self.arrival_time

    def render(self, draw: DrawingTool):
        self.drive.render(draw)

        if self.target_direction is not None:
            draw.color(draw.lime)
            draw.triangle(self.target - self.target_direction * 250,
                          self.target_direction)
Exemple #3
0
class Arrive(Maneuver):
    '''
    Arrive at a target position at a certain time (game seconds).
    You can also specify `target_direction`, and it will try to arrive
    at an angle. However this does work well only if the car is already
    roughly facing the specified direction, and only if it's far enough.
    '''
    def __init__(self, car: Car):
        super().__init__(car)

        self.target_direction: vec3 = None
        self.target: vec3 = None
        self.time: float = 0
        self.drive = Drive(car)
        self.travel = Travel(car)
        self.lerp_t = 0.6
        self.allow_dodges_and_wavedashes: bool = True
        self.additional_shift = 0

    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_vel = norm(car.velocity)
            target_direction = normalize(self.target_direction)
            shift = clamp(
                distance(car.position, target) * self.lerp_t, 0, car_vel * 1.5)
            if shift - self.additional_shift < turn_radius(
                    clamp(car_vel, 1400, 2000) * 1.1):
                shift = 0
            else:
                shift += self.additional_shift
            translated_target = target - target_direction * shift

            translated_time = self.time - distance(
                translated_target, target) * 0.7 / max(
                    1, clamp(car_vel, 500, 2300))
        else:
            translated_target = target
            translated_time = self.time

        self.drive.target_pos = translated_target
        dist_to_target = distance(car.position, translated_target)
        target_speed = clamp(
            dist_to_target / max(0.001, translated_time - car.time), 0, 2300)

        self.drive.target_speed = target_speed

        if (self.allow_dodges_and_wavedashes and car.boost < 5 and
                dist_to_target > clamp(norm(car.velocity) + 600, 1400, 2300)
                and norm(car.velocity) < target_speed - 600
                or not self.travel.driving):
            self.travel.target = target
            self.travel.step(dt)
            self.controls = self.travel.controls
        else:
            self.drive.step(dt)
            self.controls = self.drive.controls

        self.finished = self.car.time >= self.time
        return self.finished

    def render(self, draw: DrawingTool):
        self.drive.render(draw)

        if self.target_direction is not None:
            draw.color(draw.lime)
            draw.triangle(self.target - self.target_direction * 250,
                          self.target_direction)