feat: add strips on road

This commit is contained in:
2025-10-19 02:18:50 +02:00
parent 8989341714
commit 8ca15eaa78
2 changed files with 57 additions and 1 deletions

View File

@@ -54,6 +54,7 @@ class Car:
if not self.forward and not self.backward: if not self.forward and not self.backward:
self.speed -= sign(self.speed) * self.FRICTION * dt self.speed -= sign(self.speed) * self.FRICTION * dt
self.speed = max(0, self.speed)
if abs(self.speed) < 1e-4: if abs(self.speed) < 1e-4:
self.speed = 0 self.speed = 0

View File

@@ -10,9 +10,14 @@ from src.vec import Vec
class Road(TrackObject): class Road(TrackObject):
type = TrackObjectType.Road type = TrackObjectType.Road
STRIP_LENGTH = 0.5
STRIP_GAP = 0.5
def __init__(self, pts: list[RoadPoint]) -> None: def __init__(self, pts: list[RoadPoint]) -> None:
super().__init__() super().__init__()
self.pts: list[RoadPoint] = pts self.pts: list[RoadPoint] = pts
self.strips: list[tuple[Vec, Vec]] = []
self.compute_strips()
@classmethod @classmethod
def load(cls, data: dict) -> Road: 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, side1)
pygame.draw.lines(surf, (255, 255, 255), True, side2) 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]]: def get_collision_polygons(self) -> list[list[Vec]]:
side1: list[Vec] = [] side1: list[Vec] = []
side2: list[Vec] = [] side2: list[Vec] = []
@@ -49,9 +63,50 @@ class Road(TrackObject):
p3: Vec = p1 - pt.normal * pt.width p3: Vec = p1 - pt.normal * pt.width
side1.append(p2) side1.append(p2)
side2.append(p3) side2.append(p3)
return [side1, side2] 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: class RoadPoint:
def __init__(self, pos: Vec, normal: Vec, width: float) -> None: def __init__(self, pos: Vec, normal: Vec, width: float) -> None: