feat: initial implementation of image capture

This commit is contained in:
2025-10-25 17:20:17 +02:00
parent 9f86d060f0
commit cd866cc511
5 changed files with 27 additions and 10 deletions

View File

@@ -1,5 +1,7 @@
from __future__ import annotations
from math import radians
from typing import Optional
from typing import TYPE_CHECKING, Optional
import pygame
@@ -8,6 +10,9 @@ from src.remote_controller import RemoteController
from src.utils import get_segments_intersection, segments_intersect
from src.vec import Vec
if TYPE_CHECKING:
from src.game import Game
def sign(x): return 0 if x == 0 else (-1 if x < 0 else 1)
@@ -27,7 +32,8 @@ class Car:
RAYS_FOV = 180
RAYS_MAX_DIST = 100
def __init__(self, pos: Vec, direction: Vec) -> None:
def __init__(self, game: Game, pos: Vec, direction: Vec) -> None:
self.game: Game = game
self.initial_pos: Vec = pos.copy()
self.initial_dir: Vec = direction.copy()
self.pos: Vec = pos
@@ -42,7 +48,7 @@ class Car:
self.rays: list[float] = [0] * self.N_RAYS
self.rays_end: list[Vec] = [Vec() for _ in range(self.N_RAYS)]
self.controller: RemoteController = RemoteController(self)
self.controller: RemoteController = RemoteController(self.game, self)
self.controller.start_server()
def update(self, dt: float):

View File

@@ -19,10 +19,11 @@ class Game:
self.win: pygame.Surface = pygame.display.set_mode(
self.DEFAULT_SIZE, pygame.RESIZABLE
)
self.game_surf: pygame.Surface = pygame.Surface(self.DEFAULT_SIZE)
pygame.display.set_caption("Rally Racer")
self.running: bool = True
self.track: Track = Track.load("simple")
self.car: Car = Car(self.track.start_pos, self.track.start_dir)
self.car: Car = Car(self, self.track.start_pos, self.track.start_dir)
self.camera: Camera = Camera()
self.clock: pygame.time.Clock = pygame.time.Clock()
@@ -49,6 +50,7 @@ class Game:
if event.type == pygame.QUIT:
self.quit()
elif event.type == pygame.VIDEORESIZE:
self.game_surf = pygame.Surface((event.w, event.h))
self.camera.set_size(Vec(event.w, event.h))
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
@@ -68,9 +70,10 @@ class Game:
self.car.controller.close()
def render(self):
self.win.fill(self.BACKGROUND_COLOR)
self.track.render(self.win, self.camera)
self.car.render(self.win, self.camera, self.show_raycasts)
self.game_surf.fill(self.BACKGROUND_COLOR)
self.track.render(self.game_surf, self.camera)
self.car.render(self.game_surf, self.camera, self.show_raycasts)
self.win.blit(self.game_surf, (0, 0))
if self.show_fps:
self.render_fps()
if self.show_speed:

View File

@@ -17,7 +17,7 @@ from src.snapshot import Snapshot
class RecorderClient(QObject):
DATA_CHUNK_SIZE = 4096
DATA_CHUNK_SIZE = 65536
data_received: pyqtSignal = pyqtSignal(Snapshot)
def __init__(self, host: str, port: int) -> None:

View File

@@ -12,11 +12,12 @@ from src.utils import RepeatTimer
if TYPE_CHECKING:
from src.car import Car
from src.game import Game
class RemoteController:
DEFAULT_PORT = 5000
DATA_CHUNK_SIZE = 4096
DATA_CHUNK_SIZE = 65536
CONTROL_ATTRIBUTES: dict[CarControl, str] = {
CarControl.FORWARD: "forward",
@@ -27,7 +28,8 @@ class RemoteController:
SNAPSHOT_INTERVAL = 0.1
def __init__(self, car: Car, port: int = DEFAULT_PORT) -> None:
def __init__(self, game: Game, car: Car, port: int = DEFAULT_PORT) -> None:
self.game: Game = game
self.car: Car = car
self.port: int = port
self.server: socket.socket = socket.socket(
@@ -134,5 +136,6 @@ class RemoteController:
return
snapshot: Snapshot = Snapshot.from_car(self.car)
snapshot.add_image(self.game)
payload: bytes = snapshot.pack()
self.client.sendall(struct.pack(">I", len(payload)) + payload)

View File

@@ -5,11 +5,13 @@ from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Optional
import numpy as np
import pygame
from src.vec import Vec
if TYPE_CHECKING:
from src.car import Car
from src.game import Game
def iter_unpack(format, data):
@@ -99,3 +101,6 @@ class Snapshot:
car.pos = self.position.copy()
car.direction = self.direction.copy()
car.speed = 0
def add_image(self, game: Game):
self.image = pygame.surfarray.array3d(game.game_surf)