diff --git a/src/car.py b/src/car.py index 21f664f..50c830b 100644 --- a/src/car.py +++ b/src/car.py @@ -54,6 +54,7 @@ class Car: if not self.forward and not self.backward: self.speed -= sign(self.speed) * self.FRICTION * dt + self.speed = max(0, self.speed) if abs(self.speed) < 1e-4: self.speed = 0 diff --git a/src/objects/road.py b/src/objects/road.py index 81828f0..24b589a 100644 --- a/src/objects/road.py +++ b/src/objects/road.py @@ -10,9 +10,14 @@ from src.vec import Vec class Road(TrackObject): type = TrackObjectType.Road + STRIP_LENGTH = 0.5 + STRIP_GAP = 0.5 + def __init__(self, pts: list[RoadPoint]) -> None: super().__init__() self.pts: list[RoadPoint] = pts + self.strips: list[tuple[Vec, Vec]] = [] + self.compute_strips() @classmethod def load(cls, data: dict) -> Road: @@ -40,6 +45,15 @@ class Road(TrackObject): pygame.draw.lines(surf, (255, 255, 255), True, side1) pygame.draw.lines(surf, (255, 255, 255), True, side2) + for p1, p2 in self.strips: + pygame.draw.line( + surf, + (255, 255, 255), + camera.world2screen(p1), + camera.world2screen(p2), + 6, + ) + def get_collision_polygons(self) -> list[list[Vec]]: side1: list[Vec] = [] side2: list[Vec] = [] @@ -49,9 +63,50 @@ class Road(TrackObject): p3: Vec = p1 - pt.normal * pt.width side1.append(p2) side2.append(p3) - return [side1, side2] + def compute_strips(self): + n: int = len(self.pts) + vecs: list[Vec] = [ + self.pts[(i + 1) % n].pos - pt.pos for i, pt in enumerate(self.pts) + ] + lengths: list[float] = [v.mag() for v in vecs] + cum_sums: list[float] = [0] + for l in lengths: + cum_sums.append(cum_sums[-1] + l) + self.strips = [] + total_length: float = sum(lengths) + + def get_pt(length: float) -> tuple[int, float]: + length %= total_length + for i, cs in list(enumerate(cum_sums))[::-1]: + if cs <= length: + return (i, (length - cs) / lengths[i]) + raise ValueError() + + l0: float = 0 + while l0 < total_length: + l1: float = l0 + self.STRIP_LENGTH + i0, t0 = get_pt(l0) + i1, t1 = get_pt(l1) + p0: Vec = self.pts[i0].pos + vecs[i0] * t0 + p1: Vec = self.pts[i1].pos + vecs[i1] * t1 + if i0 == i1: + self.strips.append((p0, p1)) + elif (i0 + 1) % n == i1: + pm: Vec = self.pts[i1].pos + self.strips.append((p0, pm)) + self.strips.append((pm, p1)) + else: + self.strips.append((p0, self.pts[(i0 + 1) % n].pos)) + i = (i0 + 1) % n + while i != i1: + i2 = (i + 1) % n + self.strips.append((self.pts[i].pos, self.pts[i2].pos)) + i = i2 + self.strips.append((self.pts[i1].pos, p1)) + l0 = l1 + self.STRIP_GAP + class RoadPoint: def __init__(self, pos: Vec, normal: Vec, width: float) -> None: