Compare commits
3 Commits
ff61a7fad6
...
8989341714
| Author | SHA1 | Date | |
|---|---|---|---|
|
8989341714
|
|||
|
dde690818b
|
|||
|
f1ae12d0ec
|
@@ -2,12 +2,12 @@
|
||||
"name": "Simple Track",
|
||||
"start": {
|
||||
"pos": [
|
||||
0,
|
||||
-3
|
||||
30,
|
||||
0
|
||||
],
|
||||
"direction": [
|
||||
1,
|
||||
0
|
||||
0,
|
||||
1
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -3,59 +3,255 @@
|
||||
"type": "road",
|
||||
"pts": [
|
||||
[
|
||||
0,
|
||||
-3,
|
||||
0,
|
||||
-1,
|
||||
30.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
-2,
|
||||
1,
|
||||
-1,
|
||||
29.544,
|
||||
5.209,
|
||||
0.985,
|
||||
0.174,
|
||||
1
|
||||
],
|
||||
[
|
||||
3,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
28.191,
|
||||
10.261,
|
||||
0.94,
|
||||
0.342,
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
25.981,
|
||||
15.0,
|
||||
0.866,
|
||||
0.5,
|
||||
1
|
||||
],
|
||||
[
|
||||
0,
|
||||
3,
|
||||
0,
|
||||
1,
|
||||
22.981,
|
||||
19.284,
|
||||
0.766,
|
||||
0.643,
|
||||
1
|
||||
],
|
||||
[
|
||||
-2,
|
||||
2,
|
||||
-1,
|
||||
1,
|
||||
19.284,
|
||||
22.981,
|
||||
0.643,
|
||||
0.766,
|
||||
1
|
||||
],
|
||||
[
|
||||
-3,
|
||||
0,
|
||||
-1,
|
||||
0,
|
||||
15.0,
|
||||
25.981,
|
||||
0.5,
|
||||
0.866,
|
||||
1
|
||||
],
|
||||
[
|
||||
-2,
|
||||
-2,
|
||||
-1,
|
||||
-1,
|
||||
10.261,
|
||||
28.191,
|
||||
0.342,
|
||||
0.94,
|
||||
1
|
||||
],
|
||||
[
|
||||
5.209,
|
||||
29.544,
|
||||
0.174,
|
||||
0.985,
|
||||
1
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
30.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1
|
||||
],
|
||||
[
|
||||
-5.209,
|
||||
29.544,
|
||||
-0.174,
|
||||
0.985,
|
||||
1
|
||||
],
|
||||
[
|
||||
-10.261,
|
||||
28.191,
|
||||
-0.342,
|
||||
0.94,
|
||||
1
|
||||
],
|
||||
[
|
||||
-15.0,
|
||||
25.981,
|
||||
-0.5,
|
||||
0.866,
|
||||
1
|
||||
],
|
||||
[
|
||||
-19.284,
|
||||
22.981,
|
||||
-0.643,
|
||||
0.766,
|
||||
1
|
||||
],
|
||||
[
|
||||
-22.981,
|
||||
19.284,
|
||||
-0.766,
|
||||
0.643,
|
||||
1
|
||||
],
|
||||
[
|
||||
-25.981,
|
||||
15.0,
|
||||
-0.866,
|
||||
0.5,
|
||||
1
|
||||
],
|
||||
[
|
||||
-28.191,
|
||||
10.261,
|
||||
-0.94,
|
||||
0.342,
|
||||
1
|
||||
],
|
||||
[
|
||||
-29.544,
|
||||
5.209,
|
||||
-0.985,
|
||||
0.174,
|
||||
1
|
||||
],
|
||||
[
|
||||
-30.0,
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0,
|
||||
1
|
||||
],
|
||||
[
|
||||
-29.544,
|
||||
-5.209,
|
||||
-0.985,
|
||||
-0.174,
|
||||
1
|
||||
],
|
||||
[
|
||||
-28.191,
|
||||
-10.261,
|
||||
-0.94,
|
||||
-0.342,
|
||||
1
|
||||
],
|
||||
[
|
||||
-25.981,
|
||||
-15.0,
|
||||
-0.866,
|
||||
-0.5,
|
||||
1
|
||||
],
|
||||
[
|
||||
-22.981,
|
||||
-19.284,
|
||||
-0.766,
|
||||
-0.643,
|
||||
1
|
||||
],
|
||||
[
|
||||
-19.284,
|
||||
-22.981,
|
||||
-0.643,
|
||||
-0.766,
|
||||
1
|
||||
],
|
||||
[
|
||||
-15.0,
|
||||
-25.981,
|
||||
-0.5,
|
||||
-0.866,
|
||||
1
|
||||
],
|
||||
[
|
||||
-10.261,
|
||||
-28.191,
|
||||
-0.342,
|
||||
-0.94,
|
||||
1
|
||||
],
|
||||
[
|
||||
-5.209,
|
||||
-29.544,
|
||||
-0.174,
|
||||
-0.985,
|
||||
1
|
||||
],
|
||||
[
|
||||
-0.0,
|
||||
-30.0,
|
||||
-0.0,
|
||||
-1.0,
|
||||
1
|
||||
],
|
||||
[
|
||||
5.209,
|
||||
-29.544,
|
||||
0.174,
|
||||
-0.985,
|
||||
1
|
||||
],
|
||||
[
|
||||
10.261,
|
||||
-28.191,
|
||||
0.342,
|
||||
-0.94,
|
||||
1
|
||||
],
|
||||
[
|
||||
15.0,
|
||||
-25.981,
|
||||
0.5,
|
||||
-0.866,
|
||||
1
|
||||
],
|
||||
[
|
||||
19.284,
|
||||
-22.981,
|
||||
0.643,
|
||||
-0.766,
|
||||
1
|
||||
],
|
||||
[
|
||||
22.981,
|
||||
-19.284,
|
||||
0.766,
|
||||
-0.643,
|
||||
1
|
||||
],
|
||||
[
|
||||
25.981,
|
||||
-15.0,
|
||||
0.866,
|
||||
-0.5,
|
||||
1
|
||||
],
|
||||
[
|
||||
28.191,
|
||||
-10.261,
|
||||
0.94,
|
||||
-0.342,
|
||||
1
|
||||
],
|
||||
[
|
||||
29.544,
|
||||
-5.209,
|
||||
0.985,
|
||||
-0.174,
|
||||
1
|
||||
]
|
||||
]
|
||||
|
||||
40
scripts/track_gen.py
Normal file
40
scripts/track_gen.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import json
|
||||
from math import radians
|
||||
from pathlib import Path
|
||||
from src.utils import ROOT
|
||||
from src.vec import Vec
|
||||
|
||||
|
||||
def gen_circle(
|
||||
folder: Path, center: Vec, radius: float, n_sides: int, width: float = 1
|
||||
):
|
||||
with open(folder / "track.json", "w") as f:
|
||||
pts: list[tuple[float, ...]] = []
|
||||
|
||||
for i in range(n_sides):
|
||||
angle: float = radians(i / n_sides * 360)
|
||||
v: Vec = Vec(1, 0).rotate(angle)
|
||||
pos: Vec = center + v * radius
|
||||
normal: Vec = v
|
||||
pts.append((pos.x, pos.y, normal.x, normal.y, width))
|
||||
|
||||
for i, pt in enumerate(pts):
|
||||
pts[i] = tuple(round(v, 3) for v in pt)
|
||||
|
||||
json.dump([{"type": "road", "pts": pts}], f, indent=4)
|
||||
|
||||
with open(folder / "meta.json", "r") as f:
|
||||
meta: dict = json.load(f)
|
||||
|
||||
meta["start"] = {"pos": [radius, 0], "direction": [0, 1]}
|
||||
with open(folder / "meta.json", "w") as f:
|
||||
json.dump(meta, f, indent=4)
|
||||
|
||||
|
||||
def main():
|
||||
folder: Path = ROOT / "assets" / "tracks" / "simple"
|
||||
gen_circle(folder, Vec(0, 0), 30, 36)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
29
src/car.py
29
src/car.py
@@ -7,14 +7,19 @@ from src.utils import segments_intersect
|
||||
from src.vec import Vec
|
||||
|
||||
|
||||
sign = lambda x: 0 if x == 0 else (-1 if x < 0 else 1)
|
||||
|
||||
|
||||
class Car:
|
||||
MAX_SPEED = 0.05
|
||||
MAX_BACK_SPEED = -0.025
|
||||
ROTATE_SPEED = radians(1)
|
||||
MAX_SPEED = 5
|
||||
MAX_BACK_SPEED = -2
|
||||
ROTATE_SPEED = 1
|
||||
COLOR = (230, 150, 80)
|
||||
WIDTH = 0.4
|
||||
LENGTH = 0.6
|
||||
COLLISION_MARGIN = 0.4
|
||||
ACCELERATION = 2
|
||||
FRICTION = 3
|
||||
|
||||
def __init__(self, pos: Vec, direction: Vec) -> None:
|
||||
self.pos: Vec = pos
|
||||
@@ -26,20 +31,20 @@ class Car:
|
||||
self.right: bool = False
|
||||
self.colliding: bool = False
|
||||
|
||||
def update(self):
|
||||
def update(self, dt: float):
|
||||
if self.forward:
|
||||
self.speed += 0.001
|
||||
self.speed += self.ACCELERATION * dt
|
||||
self.speed = min(self.MAX_SPEED, self.speed)
|
||||
|
||||
if self.backward:
|
||||
self.speed -= 0.002
|
||||
self.speed -= self.ACCELERATION * 2 * dt
|
||||
self.speed = max(self.MAX_BACK_SPEED, self.speed)
|
||||
|
||||
rotate_angle: float = 0
|
||||
if self.left:
|
||||
rotate_angle -= self.ROTATE_SPEED
|
||||
rotate_angle -= self.ROTATE_SPEED * dt
|
||||
if self.right:
|
||||
rotate_angle += self.ROTATE_SPEED
|
||||
rotate_angle += self.ROTATE_SPEED * dt
|
||||
|
||||
# if self.backward:
|
||||
# rotate_angle *= -1
|
||||
@@ -47,11 +52,13 @@ class Car:
|
||||
if rotate_angle != 0:
|
||||
self.direction = self.direction.rotate(rotate_angle)
|
||||
|
||||
self.speed *= 0.98
|
||||
if abs(self.speed) < 1e-8:
|
||||
if not self.forward and not self.backward:
|
||||
self.speed -= sign(self.speed) * self.FRICTION * dt
|
||||
|
||||
if abs(self.speed) < 1e-4:
|
||||
self.speed = 0
|
||||
|
||||
self.pos += self.direction * self.speed
|
||||
self.pos += self.direction * self.speed * dt
|
||||
|
||||
def render(self, surf: pygame.Surface, camera: Camera):
|
||||
pts: list[Vec] = self.get_corners()
|
||||
|
||||
35
src/game.py
35
src/game.py
@@ -1,3 +1,4 @@
|
||||
from math import cos, radians, sin
|
||||
import pygame
|
||||
|
||||
from src.camera import Camera
|
||||
@@ -29,11 +30,13 @@ class Game:
|
||||
str(ROOT / "assets" / "fonts" / "Ubuntu-M.ttf"), 20
|
||||
)
|
||||
self.show_fps: bool = True
|
||||
self.show_speed: bool = True
|
||||
|
||||
def mainloop(self):
|
||||
while self.running:
|
||||
dt: float = self.clock.get_time() / 1000
|
||||
self.process_pygame_events()
|
||||
self.car.update()
|
||||
self.car.update(dt)
|
||||
self.car.check_collisions(self.track.get_collision_polygons())
|
||||
self.render()
|
||||
self.clock.tick(60)
|
||||
@@ -64,6 +67,8 @@ class Game:
|
||||
self.car.render(self.win, self.camera)
|
||||
if self.show_fps:
|
||||
self.render_fps()
|
||||
if self.show_speed:
|
||||
self.render_speedometer()
|
||||
|
||||
pygame.display.flip()
|
||||
|
||||
@@ -76,6 +81,10 @@ class Game:
|
||||
self.car.left = True
|
||||
elif event.key == pygame.K_d:
|
||||
self.car.right = True
|
||||
elif event.key == pygame.K_f:
|
||||
self.show_fps = not self.show_fps
|
||||
elif event.key == pygame.K_v:
|
||||
self.show_speed = not self.show_speed
|
||||
|
||||
def on_key_up(self, event: pygame.event.Event):
|
||||
if event.key == pygame.K_w:
|
||||
@@ -92,3 +101,27 @@ class Game:
|
||||
f"{self.clock.get_fps():.1f}", True, self.FPS_COLOR
|
||||
)
|
||||
self.win.blit(txt, (self.win.get_width() - txt.get_width(), 0))
|
||||
|
||||
def render_speedometer(self):
|
||||
if self.car.speed == 0:
|
||||
return
|
||||
angle: float = self.car.speed / self.car.MAX_SPEED * 180
|
||||
|
||||
pts1: list[tuple[float, float]] = []
|
||||
pts2: list[tuple[float, float]] = []
|
||||
|
||||
n: int = 30
|
||||
r: float = 50
|
||||
ox: float = r + 10
|
||||
oy: float = r + 10
|
||||
thickness: float = 5
|
||||
r2: float = r - thickness
|
||||
|
||||
for i in range(n):
|
||||
a: float = radians(angle * i / (n - 1))
|
||||
dx: float = -cos(a)
|
||||
dy: float = -sin(a)
|
||||
pts1.append((ox + r * dx, oy + r * dy))
|
||||
pts2.append((ox + r2 * dx, oy + r2 * dy))
|
||||
|
||||
pygame.draw.polygon(self.win, (200, 200, 200), pts1 + pts2[::-1])
|
||||
|
||||
@@ -28,8 +28,6 @@ class Road(TrackObject):
|
||||
p3: Vec = p1 - pt.normal * pt.width
|
||||
side1.append(camera.world2screen(p2))
|
||||
side2.append(camera.world2screen(p3))
|
||||
col: tuple[float, float, float] = (i * 10 + 150, 100, 100)
|
||||
pygame.draw.circle(surf, col, camera.world2screen(p1), 5)
|
||||
|
||||
n: int = len(self.pts)
|
||||
for i in range(n):
|
||||
|
||||
Reference in New Issue
Block a user