feat: add strips on road
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user