import pygame import time import random import sys from world.world import World, Position, Rotation from world.objects import FoodObject, DefaultCell from world.simulation_interface import Camera from config.constants import * from core.input_handler import InputHandler from core.renderer import Renderer from ui.hud import HUD class SimulationEngine: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), vsync=1) pygame.display.set_caption("Dynamic Abstraction System Testing") self.clock = pygame.time.Clock() self.camera = Camera(SCREEN_WIDTH, SCREEN_HEIGHT, RENDER_BUFFER) self.last_tick_time = time.perf_counter() self.last_tps_time = time.perf_counter() self.tick_counter = 0 self.actual_tps = 0 self.total_ticks = 0 self.world = self._setup_world() self.input_handler = InputHandler(self.camera, self.world) self.renderer = Renderer(self.screen) self.hud = HUD() self.running = True def _setup_world(self): world = World(CELL_SIZE, (CELL_SIZE * GRID_WIDTH, CELL_SIZE * GRID_HEIGHT)) random.seed(0) if FOOD_SPAWNING: world.add_object(FoodObject(Position(x=random.randint(-100, 100), y=random.randint(-100, 100)))) for _ in range(10): world.add_object(DefaultCell(Position(x=random.randint(-100, 100), y=random.randint(-100, 100)), Rotation(angle=0))) return world def run(self): while self.running: self._handle_frame() pygame.quit() sys.exit() def _handle_frame(self): deltatime = self.clock.get_time() / 1000.0 tick_interval = 1.0 / self.input_handler.tps # Handle events self.running = self.input_handler.handle_events(pygame.event.get()) if not self.input_handler.is_paused: current_time = time.perf_counter() while current_time - self.last_tick_time >= tick_interval: self.last_tick_time += tick_interval self.tick_counter += 1 self.total_ticks += 1 self.input_handler.update_selected_objects() self.world.tick_all() if current_time - self.last_tps_time >= 1.0: self.actual_tps = self.tick_counter self.tick_counter = 0 self.last_tps_time += 1.0 else: self.last_tick_time = time.perf_counter() self.last_tps_time = time.perf_counter() self._update(deltatime) self._render() def _update(self, deltatime): keys = pygame.key.get_pressed() self.input_handler.update_camera(keys, deltatime) def _render(self): self.renderer.clear_screen() self.renderer.draw_grid(self.camera, self.input_handler.show_grid) self.renderer.render_world(self.world, self.camera) self.renderer.render_interaction_radius(self.world, self.camera, self.input_handler.selected_objects, self.input_handler.show_interaction_radius) self.renderer.render_selection_rectangle(self.input_handler.get_selection_rect()) self.renderer.render_selected_objects_outline(self.input_handler.selected_objects, self.camera) self.hud.render_mouse_position(self.screen, self.camera) self.hud.render_fps(self.screen, self.clock) self.hud.render_tps(self.screen, self.actual_tps) self.hud.render_tick_count(self.screen, self.total_ticks) self.hud.render_selected_objects_info(self.screen, self.input_handler.selected_objects) self.hud.render_legend(self.screen, self.input_handler.show_legend) self.hud.render_pause_indicator(self.screen, self.input_handler.is_paused) if self.input_handler.selected_objects: self.hud.render_neural_network_visualization(self.screen, self.input_handler.selected_objects[0]) pygame.display.flip() self.clock.tick(MAX_FPS)