from math import radians import pygame from src.camera import Camera from src.utils import segments_intersect from src.vec import Vec class Car: MAX_SPEED = 0.05 MAX_BACK_SPEED = -0.025 ROTATE_SPEED = radians(1) COLOR = (230, 150, 80) WIDTH = 0.4 LENGTH = 0.6 COLLISION_MARGIN = 0.4 def __init__(self, pos: Vec, direction: Vec) -> None: self.pos: Vec = pos self.direction: Vec = direction self.speed: float = 0 self.forward: bool = False self.backward: bool = False self.left: bool = False self.right: bool = False self.colliding: bool = False def update(self): if self.forward: self.speed += 0.001 self.speed = min(self.MAX_SPEED, self.speed) if self.backward: self.speed -= 0.002 self.speed = max(self.MAX_BACK_SPEED, self.speed) rotate_angle: float = 0 if self.left: rotate_angle -= self.ROTATE_SPEED if self.right: rotate_angle += self.ROTATE_SPEED # if self.backward: # rotate_angle *= -1 if rotate_angle != 0: self.direction = self.direction.rotate(rotate_angle) self.speed *= 0.98 if abs(self.speed) < 1e-8: self.speed = 0 self.pos += self.direction * self.speed def render(self, surf: pygame.Surface, camera: Camera): pts: list[Vec] = self.get_corners() pts = [camera.world2screen(p) for p in pts] pygame.draw.polygon(surf, self.COLOR, pts) def get_corners(self) -> list[Vec]: u: Vec = self.direction * self.LENGTH / 2 v: Vec = self.direction.perp * self.WIDTH / 2 pt: Vec = self.pos p1: Vec = pt + u + v p2: Vec = pt - u + v p3: Vec = pt - u - v p4: Vec = pt + u - v return [p1, p2, p3, p4] def check_collisions(self, polygons: list[list[Vec]]): self.colliding = False corners: list[Vec] = self.get_corners() sides: list[tuple[Vec, Vec]] = [ (corners[i], corners[(i + 1) % 4]) for i in range(4) ] for polygon in polygons: n_pts: int = len(polygon) for i in range(n_pts): pt1: Vec = polygon[i] pt2: Vec = polygon[(i + 1) % n_pts] d: Vec = pt2 - pt1 for s1, s2 in sides: if segments_intersect(s1, s2, pt1, pt2): self.colliding = True self.direction = d.normalized n: Vec = self.direction.perp dist: float = (self.pos - pt1).dot(n) if dist < 0: n *= -1 dist = -dist self.speed = 0 self.pos = self.pos + n * (self.COLLISION_MARGIN - dist) return