From d2a50413dbc8c047991eae46fde2e9f5e329cb4c Mon Sep 17 00:00:00 2001 From: Stan44 Date: Sun, 29 Dec 2024 14:50:50 -0600 Subject: [PATCH] Performance improvements, fixed lava and particle states. Plasma still broken. --- src/config/settings.py | 51 ++- src/part/coreparts/particles/basic.json | 2 +- src/part/coreparts/particles/gases.json | 6 +- src/part/coreparts/particles/liquids.json | 6 +- src/part/coreparts/special/effects.json | 8 +- src/part/coreparts/states/frozen.json | 2 +- src/part/coreparts/states/molten.json | 6 +- src/part/particles.json | 476 ++++++++++++++++++++++ src/physics/sim.py | 168 ++++---- src/rendering/rendering.py | 2 +- src/sandpypi.py | 20 +- 11 files changed, 629 insertions(+), 118 deletions(-) create mode 100644 src/part/particles.json diff --git a/src/config/settings.py b/src/config/settings.py index 7d875d5..3e7a043 100644 --- a/src/config/settings.py +++ b/src/config/settings.py @@ -34,36 +34,47 @@ engine_settings = { 'outerwall': False, # 'settings': True/False } -# For particles.json loading in settings.py: -particles_path = os.path.join(os.path.dirname(__file__), '..', 'part', 'particles.json') - - -# Load particle properties from JSON file def load_particle_properties(): particle_data = {} - parts_path = os.path.join(os.path.dirname(__file__), '..', 'part') - - def scan_directory(directory): - for root, dirs, files in os.walk(directory): + base_path = os.path.join(os.path.dirname(__file__), '..') + core_path = os.path.join(base_path, 'part', 'coreparts') + mods_path = os.path.join(base_path, 'part', 'mods') + + def load_json_files(directory): + for root, _, files in os.walk(directory): for file in files: if file.endswith('.json'): file_path = os.path.join(root, file) try: with open(file_path, 'r') as f: - mod_data = json.load(f) - relative_path = os.path.relpath(file_path, parts_path) - particle_data.update(mod_data) - print(f"Loaded {len(mod_data)} particles from {relative_path}") + data = json.load(f) + """# Debug: Print specific temperature-related properties + for particle_name, props in data.items(): + if 'temperature' in props: + print(f"Loaded {particle_name} with temp: {props['temperature']}") + if 'melt_temperature' in props: + print(f"Loaded {particle_name} with melt_temp: {props['melt_temperature']}")""" + particle_data.update(data) except (FileNotFoundError, json.JSONDecodeError) as e: - print(f"Error loading {file_path}: {e}") - - if os.path.exists(parts_path): - scan_directory(parts_path) - else: - print(f"Parts directory not found at {parts_path}") - + print(f"Error loading {file}: {e}") + + # Load core and mod particles + for path in [core_path, mods_path]: + if os.path.exists(path): + load_json_files(path) + else: + print(f"Directory not found: {path}") + + """# Final verification of critical properties + print("\nVerifying critical properties:") + for name, props in particle_data.items(): + if 'lava' in name.lower(): + print(f"Lava properties: {props}")""" + return particle_data + # Load particle properties once when module is imported particle_properties = load_particle_properties() + __all__ = ['pygame', 'np', 'random', 'time', 'engine_settings', 'particle_properties', 'cProfile', 'pstats', 'sys', 'os'] diff --git a/src/part/coreparts/particles/basic.json b/src/part/coreparts/particles/basic.json index d2c5716..1b47cc7 100644 --- a/src/part/coreparts/particles/basic.json +++ b/src/part/coreparts/particles/basic.json @@ -7,7 +7,7 @@ "velocity": 0.5, "mass": 0.5, "temperature": 20, - "melt": "molten-Glass", + "melt": "molten-glass", "melt_temperature": 1700, "friction": 0.5, "liquid": false, diff --git a/src/part/coreparts/particles/gases.json b/src/part/coreparts/particles/gases.json index 3c13456..f30c93a 100644 --- a/src/part/coreparts/particles/gases.json +++ b/src/part/coreparts/particles/gases.json @@ -2,7 +2,7 @@ "steam": { "name": "Steam", "size": 1, - "hardness": 0.0, + "hardness": 0.01, "velocity": 0.3, "conductivity": 1, "heat_capacity": 1, @@ -36,13 +36,13 @@ }, "air": { "name": "Air", - "size": 1, + "size": 0.001, "hardness": 0.0, "velocity": 0.0, "conductivity": 0, "heat_capacity": 1, "color": [255, 255, 255, 25], - "mass": 0.0, + "mass": 0.0001, "temperature": 0, "friction": 0.0, "viscosity": 0.0, diff --git a/src/part/coreparts/particles/liquids.json b/src/part/coreparts/particles/liquids.json index e1c31b5..af176dd 100644 --- a/src/part/coreparts/particles/liquids.json +++ b/src/part/coreparts/particles/liquids.json @@ -30,9 +30,11 @@ "heat_capacity": 1, "color": [255, 45, 60, 255], "mass": 0.3, - "temperature": 1400, - "solidify": "molten-rock", + "flamability": 0, + "temperature": 1200, + "solidify": "molten_rock", "solidify_temperature": 799, + "explosive": false, "friction": 0.8, "viscosity": 0.8, "liquid": true, diff --git a/src/part/coreparts/special/effects.json b/src/part/coreparts/special/effects.json index 9c0e3c7..4b69147 100644 --- a/src/part/coreparts/special/effects.json +++ b/src/part/coreparts/special/effects.json @@ -2,19 +2,19 @@ "plasma": { "name": "Plasma", "size": 1, - "hardness": 0.0, + "hardness": 0.001, "velocity": 0.0, "conductivity": 0, - "heat_capacity": 1, + "heat_capacity": 10, "color": [255, 100, 200, 255], - "mass": 0.0, + "mass": 0.001, "temperature": 3600, "friction": 0.0, "viscosity": 0.0, "liquid": false, "solid": false, "is_gas": true, - "glow_radius": 5, + "glow_radius": 1, "glow_intensity": 0.8, "glow_color": [255, 150, 220, 180] }, diff --git a/src/part/coreparts/states/frozen.json b/src/part/coreparts/states/frozen.json index 1bb830f..5af4e43 100644 --- a/src/part/coreparts/states/frozen.json +++ b/src/part/coreparts/states/frozen.json @@ -27,7 +27,7 @@ "color": [255, 255, 255, 255], "mass": 0.01, "melt": "water", - "melt_temperature": 1, + "melt_temperature": 5, "temperature": 0, "friction": 0.1, "viscosity": 0.01, diff --git a/src/part/coreparts/states/molten.json b/src/part/coreparts/states/molten.json index 9e07431..3e6a42b 100644 --- a/src/part/coreparts/states/molten.json +++ b/src/part/coreparts/states/molten.json @@ -26,7 +26,7 @@ "heat_capacity": 1, "color": [255, 200, 150, 200], "mass": 0.6, - "temperature": 600, + "temperature": 700, "solidify": "glass", "solidify_temperature": 599, "friction": 0.7, @@ -45,10 +45,8 @@ "color": [255, 140, 0, 255], "mass": 0.8, "temperature": 600, - "melt": "lava", - "melt_temperature": 1300, "solidify": "rock", - "solidify_temperature": 200, + "solidify_temperature": 300, "friction": 0.8, "viscosity": 0.8, "liquid": true, diff --git a/src/part/particles.json b/src/part/particles.json new file mode 100644 index 0000000..3266416 --- /dev/null +++ b/src/part/particles.json @@ -0,0 +1,476 @@ +{ + "sand": { + "name": "Sand", + "size": 1, + "hardness": 0.5, + "color": [255, 255, 0, 255], + "velocity": 0.5, + "wind": 1, + "mass": 0.5, + "conductivity": 0, + "heat_capacity": 1, + "flamability": 0.8, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0, + "pressure": 0, + "melt": "molten-glass", + "melt_temperature": 1700, + "conductive": false, + "liquid": false, + "solid": true, + "is_gas": false + }, + "water": { + "name": "Water", + "size": 1, + "hardness": 0.2, + "velocity": 0.3, + "conductivity": 1, + "heat_capacity": 1, + "color": [0, 0, 255, 255], + "mass": 1, + "flamability": 0, + "temperature": 22, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 1, + "viscosity": 1, + "pressure": 0.5, + "evaporate": "steam", + "evaporate_temperature": 100, + "freeze": "ice", + "freeze_temperature": 0, + "conductive": true, + "liquid": true, + "solid": false, + "is_gas": false + }, + "steam": { + "name": "Steam", + "size": 1, + "hardness": 0.0, + "velocity": 0.3, + "conductivity": 1, + "heat_capacity": 1, + "color": [255, 255, 255, 255], + "mass": 0.01, + "flamability": 0, + "temperature": 100, + "solidify_temperature": 98, + "solidify": "water", + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0.5, + "liquid": false, + "solid": false, + "is_gas": true, + "conductive": false + }, + "ice": { + "name": "Ice", + "size": 1, + "hardness": 1000, + "velocity": 0.0, + "conductivity": 0, + "heat_capacity": 0, + "color": [75, 75, 170, 255], + "mass": 1, + "flamability": 0.0, + "temperature": 0, + "melt": "water", + "melt_temperature": 0.05, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 1, + "viscosity": 1, + "liquid": false, + "solid": true, + "is_gas": false + }, + "mud": { + "name": "Mud", + "size": 1, + "hardness": 0.4, + "velocity": 0.5, + "conductivity": 1, + "heat_capacity": 1, + "color": [139, 69, 19, 255], + "mass": 0.5, + "flamability": 0, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 1, + "liquid": false, + "solid": true, + "is_gas": false + }, + "fire": { + "name": "Fire", + "size": 1, + "hardness": 0.1, + "velocity": 0.1, + "conductivity": 0, + "heat_capacity": 1, + "color": [255, 0, 0, 255], + "mass": 0.1, + "flamability": 1, + "temperature": 800, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.1, + "viscosity": 0.1, + "liquid": false, + "solid": false, + "is_gas": true + }, + "smoke": { + "name": "Smoke", + "size": 1, + "hardness": 0.1, + "velocity": 0.07, + "conductivity": 0, + "heat_capacity": 1, + "color": [115, 113, 95, 255], + "mass": 0.01, + "flamability": 0, + "temperature": 85, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.4, + "viscosity": 0.1, + "lifetime": 90, + "liquid": false, + "solid": false, + "is_gas": true + }, + "wall": { + "name": "Wall", + "size": 1, + "hardness": 1000, + "velocity": 0.0, + "conductivity": 0, + "heat_capacity": 0, + "color": [75, 75, 75, 255], + "mass": 1, + "flamability": 0, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 1, + "viscosity": 1, + "liquid": false, + "solid": true, + "is_gas": false + }, + "dirt": { + "name": "Dirt", + "size": 1, + "hardness": 0.5, + "velocity": 0.5, + "conductivity": 0, + "heat_capacity": 1, + "color": [139, 69, 19, 255], + "mass": 0.5, + "flamability": 0, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0.5, + "liquid": false, + "solid": true, + "is_gas": false + }, + "stone": { + "name": "Stone", + "size": 1, + "hardness": 0.7, + "velocity": 1.5, + "conductivity": 0, + "heat_capacity": 0, + "color": [128, 128, 128, 220], + "mass": 1, + "flamability": 0, + "melt": "molten-Stone", + "melt_temperature": 800, + "solidify": "stone", + "solidify_temperature": 799, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0.5, + "liquid": false, + "solid": true, + "is_gas": false + }, + "snow": { + "name": "Snow", + "size": 1, + "hardness": 0.1, + "velocity": 0.2, + "conductivity": 1, + "heat_capacity": 1, + "color": [255, 255, 255, 255], + "mass": 0.01, + "flamability": 0, + "melt": "water", + "melt_temperature": 1, + "temperature": 0, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.1, + "viscosity": 0.01, + "liquid": false, + "solid": true, + "is_gas": false + }, + "wood": { + "name": "Wood", + "size": 1, + "hardness": 0.5, + "velocity": 0.5, + "conductivity": 0, + "heat_capacity": 1, + "color": [139, 69, 19, 255], + "mass": 0.5, + "flamability": 0.8, + "burning_temperature": 250, + "burning_rate": 0.01, + "burning_color": [255, 69, 19, 255], + "burning": false, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0.5, + "liquid": false, + "solid": true, + "is_gas": false + }, + "burning-wood": { + "name": "Burning Wood", + "size": 1, + "hardness": 0.5, + "velocity": 0.5, + "conductivity": 0, + "heat_capacity": 1, + "color": [255, 69, 19, 255], + "mass": 0.5, + "flamability": 0.8, + "temperature": 251, + "burning": true, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0.5, + "liquid": false, + "solid": true, + "is_gas": false + }, + "air": { + "name": "Air", + "size": 1, + "hardness": 0.0, + "velocity": 0.0, + "conductivity": 0, + "heat_capacity": 1, + "color": [255, 255, 255, 25], + "mass": 0.0, + "flamability": 0, + "temperature": 0, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.0, + "viscosity": 0.0, + "liquid": false, + "solid": false, + "is_gas": true + }, + "lava": { + "name": "Lava", + "size": 1, + "hardness": 0.2, + "velocity": 0.5, + "conductivity": 0, + "heat_capacity": 1, + "color": [255, 45, 60, 255], + "mass": 0.3, + "flamability": 0, + "temperature": 1100, + "solidify": "molten-rock", + "solidify_temperature": 799, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.8, + "viscosity": 0.8, + "liquid": true, + "solid": false, + "is_gas": false + }, + "rock": { + "name": "Rock", + "size": 1, + "hardness": 0.2, + "velocity": 0.3, + "conductivity": 1, + "heat_capacity": 1, + "color": [128, 128, 128, 255], + "mass": 0.8, + "flamability": 0, + "melt": "molten-rock", + "melt_temperature": 600, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.5, + "viscosity": 0.5, + "liquid": false, + "solid": true, + "is_gas": false + }, + "molten-rock": { + "name": "Molten Rock", + "size": 1, + "hardness": 0.2, + "velocity": 0.3, + "conductivity": 1, + "heat_capacity": 1, + "color": [255, 140, 0, 255], + "mass": 0.8, + "flamability": 0, + "temperature": 600, + "melt": "lava", + "melt_temperature": 1300, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0,0,0], + "friction": 0.8, + "viscosity": 0.8, + "liquid": true, + "solid": false, + "is_gas": false, + "solidify": "rock", + "solidify_temperature": 200 + }, + "molten_stone": { + "name": "Molten Stone", + "size": 1, + "hardness": 0.2, + "velocity": 0.3, + "conductivity": 1, + "heat_capacity": 1, + "color": [255, 140, 0, 255], + "mass": 0.8, + "flamability": 0, + "temperature": 1200, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.8, + "viscosity": 0.8, + "liquid": true, + "solid": false, + "is_gas": false, + "solidify": "stone", + "solidify_temperature": 800 + }, + "molten_glass": { + "name": "Molten Glass", + "size": 1, + "hardness": 0.2, + "velocity": 0.4, + "conductivity": 0.8, + "heat_capacity": 1, + "color": [255, 200, 150, 200], + "mass": 0.6, + "flamability": 0, + "temperature": 600, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.7, + "viscosity": 0.9, + "liquid": true, + "solid": false, + "is_gas": false, + "solidify": "glass", + "solidify_temperature": 599 + }, + "glass": { + "name": "Glass", + "size": 1, + "hardness": 0.2, + "velocity": 0.4, + "conductivity": 0, + "heat_capacity": 1, + "color": [50, 45, 255, 100], + "mass": 0.6, + "flamability": 0, + "temperature": 20, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.7, + "viscosity": 0.9, + "liquid": false, + "solid": true, + "is_gas": false, + "melt": "molten-glass", + "melt_temperature": 600 + }, + "plasma": { + "name": "Plasma", + "size": 1, + "hardness": 0.0, + "velocity": 0.0, + "conductivity": 0, + "heat_capacity": 1, + "color": [255, 100, 200, 255], + "mass": 0.0, + "flamability": 0, + "temperature": 3600, + "explosive": false, + "explosion_radius": 0, + "explosion_color": [0, 0, 0], + "friction": 0.0, + "viscosity": 0.0, + "liquid": false, + "solid": false, + "is_gas": true + }, + "wind": { + "name": "Wind", + "color": [200, 200, 255, 128], + "mass": 0.01, + "is_wind": true, + "wind_strength": 2.0, + "wind_direction": [1, 0], + "radius": 50, + "special": true + } + +} + diff --git a/src/physics/sim.py b/src/physics/sim.py index 7cba078..bc864ec 100644 --- a/src/physics/sim.py +++ b/src/physics/sim.py @@ -19,7 +19,7 @@ Key Components: """ #Load the imports. -from src.config.settings import random, time, particle_properties +from config.settings import random, time, particle_properties # Load particle properties from json so we know what particles we got and how they should be simulated. @@ -139,71 +139,68 @@ class Simulation: return neighbors - def update_spatial_grid(self): # this is where we update the spatial grid. - """Update spatial grid for optimized collision detection""" + + def update_spatial_grid(self): + """Enhanced spatial grid update""" if len(self.active_particles) > 100: self.spatial_grid = {} cell_lists = {} + # Track temperature-sensitive particles + temp_sensitive_cells = set() + for x, y in self.active_particles: cell_key = (x // self.cell_size, y // self.cell_size) if cell_key not in cell_lists: cell_lists[cell_key] = [] cell_lists[cell_key].append((x, y)) + + # Mark cells with temperature-sensitive particles + particle = self.particles[x][y] + if hasattr(particle, 'solidify_temperature') or hasattr(particle, 'melt_temperature'): + temp_sensitive_cells.add(cell_key) self.spatial_grid = {k: set(v) for k, v in cell_lists.items()} - - - def _check_dormant_state(self, x, y, particle): - key = (x, y) - if particle.particle_type == 'wall': - self.dormant_particles.add(key) - return True - - if not hasattr(particle, 'last_position'): - particle.last_position = (x, y) - self.particle_movement_counter[key] = 0 - return False - - if particle.last_position == (x, y): - self.particle_movement_counter[key] = self.particle_movement_counter.get(key, 0) + 1 - if self.particle_movement_counter[key] >= self.DORMANT_THRESHOLD: - self.dormant_particles.add(key) - return True - else: - particle.last_position = (x, y) - self.particle_movement_counter[key] = 0 - self.dormant_particles.discard(key) - return False + return temp_sensitive_cells def handle_phase_transitions(self, particle, x, y): # this is where we handle all the phase transitions. """Handle all phase transitions for a particle""" + state_changed = False + + if particle.particle_type == 'lava': + if particle.temperature < particle.solidify_temperature: + state_changed = self.transform_particle(x, y, particle.solidify) + return state_changed + # Check evaporation if hasattr(particle, 'evaporate_temperature') and particle.evaporate_temperature is not None: if particle.temperature >= particle.evaporate_temperature and particle.evaporate: self.transform_particle(x, y, particle.evaporate) - + if not state_changed: # Check freezing - if hasattr(particle, 'freeze_temperature') and particle.freeze_temperature is not None: - if particle.temperature <= particle.freeze_temperature and particle.freeze: - self.transform_particle(x, y, particle.freeze) - - # Check for melting with proper attribute validation - if (hasattr(particle, 'melt') and hasattr(particle, 'melt_temperature') - and particle.melt_temperature is not None): - if particle.temperature >= particle.melt_temperature: - new_type = particle.melt - if new_type in self.particle_properties: - self.transform_particle(x, y, new_type) + if hasattr(particle, 'freeze_temperature') and particle.freeze_temperature is not None: + if particle.temperature <= particle.freeze_temperature and particle.freeze: + self.transform_particle(x, y, particle.freeze) + + # Check for melting with proper attribute validation + if (hasattr(particle, 'melt') and hasattr(particle, 'melt_temperature') + and particle.melt_temperature is not None): + if particle.temperature >= particle.melt_temperature: + new_type = particle.melt + if new_type in self.particle_properties: + self.transform_particle(x, y, new_type) - # Check for solidification with proper attribute validation - if (hasattr(particle, 'solidify') and hasattr(particle, 'solidify_temperature') - and particle.solidify_temperature is not None): - if particle.temperature <= particle.solidify_temperature: - new_type = particle.solidify - if new_type in self.particle_properties: - self.transform_particle(x, y, new_type) + # Check for solidification with proper attribute validation + if (hasattr(particle, 'solidify') and hasattr(particle, 'solidify_temperature') + and particle.solidify_temperature is not None): + if particle.temperature < particle.solidify_temperature: + new_type = particle.solidify + if new_type in self.particle_properties: + self.transform_particle(x, y, new_type) + return new_type + + def handle_particle_interactions(self, dt): # this is where we handle all the particle interactions. @@ -247,7 +244,7 @@ class Simulation: def create_mud(self, x, y): # this is where we create the mud. probably should be moved to handle_particle_interactions or process_interaction. - """Create mud particle from water and sand interaction""" + if 'mud' in self.particle_properties: properties = self.particle_properties['mud'] new_particle = Particle.from_type((x, y), 'mud', properties) @@ -543,34 +540,17 @@ class Simulation: particle.position = (new_x, new_y) + def apply_physics(self, dt, engine_settings): # this is where we apply physics. """Handle all physics effects""" new_active_particles = set() - + updates = [] + for x, y in list(self.active_particles): particle = self.particles[x][y] if not particle: continue - # Handle boundaries based on settings - if engine_settings['outerwall']: - if x <= 0 or x >= self.width-1 or y <= 0 or y >= self.height-1: - # Create wall particle at boundary if none exists - if self.particles[x][y] is None: - properties = self.particle_properties['wall'] - wall = Particle.from_type((x, y), 'wall', properties) - self.particles[x][y] = wall - new_active_particles.add((x, y)) - self.particle_count += 1 # Track new wall particle - continue - else: - # Delete particles that go out of bounds - if x <= 0 or x >= self.width-1 or y <= 0 or y >= self.height-1: - if self.particles[x][y] is not None: - self.particles[x][y] = None - self.active_particles.discard((x, y)) - self.particle_count -= 1 - continue # Skip wall physics - walls are immutable @@ -635,7 +615,7 @@ class Simulation: self.particles[x][y] = None self.active_particles.discard((x, y)) - + # Check if the new position is within bounds if 0 <= new_x < self.width and 0 <= new_y < self.height: if self.particles[new_x][new_y] is None: self.particles[x][y] = None @@ -662,18 +642,46 @@ class Simulation: self.particles[new_x][new_y] = particle new_active_particles.add((new_x, new_y)) continue - - # Update position for non-liquid particles - new_x = int(x + particle.velocity[0] * dt) - new_y = int(y + particle.velocity[1] * dt) - - if 0 <= new_x < self.width and 0 <= new_y < self.height: - if self.particles[new_x][new_y] is None: - self.particles[x][y] = None - self.particles[new_x][new_y] = particle - - else: + + new_x = int(x + particle.velocity[0] * dt) + new_y = int(y + particle.velocity[1] * dt) + + # Update position + if 0 <= new_x < self.width and 0 <= new_y < self.height: + if self.particles[new_x][new_y] is None: + updates.append((x, y, new_x, new_y, particle)) + new_active_particles.add((new_x, new_y)) + # Wake up neighboring dormant particles + self._wake_neighbors(new_x, new_y) + else: + new_active_particles.add((x, y)) + + # Apply updates and return new active set + for old_x, old_y, new_x, new_y, particle in updates: + self.particles[old_x][old_y] = None + self.particles[new_x][new_y] = particle + particle.position = (new_x, new_y) + + # Handle boundaries based on settings + + if engine_settings['outerwall']: + if x <= 0 or x >= self.width-1 or y <= 0 or y >= self.height-1: + # Create wall particle at boundary if none exists + if self.particles[x][y] is None: + properties = self.particle_properties['wall'] + wall = Particle.from_type((x, y), 'wall', properties) + self.particles[x][y] = wall new_active_particles.add((x, y)) + self.particle_count += 1 # Track new wall particle + continue + else: + # Delete particles that go out of bounds + if x <= 0 or x >= self.width-1 or y <= 0 or y >= self.height-1: + if self.particles[x][y] is not None: + self.particles[x][y] = None + self.active_particles.discard((x, y)) + self.particle_count -= 1 + continue self.active_particles = new_active_particles @@ -746,14 +754,16 @@ class Simulation: def simulate_step(self, dt, engine_settings): """Run simulation step with spatial grid updates""" + self.update_spatial_grid() - + # Update particle positions and physics self.apply_gravity(dt) self.apply_physics(dt, engine_settings) # Handle state changes and interactions self.handle_temperature(dt) + self.handle_particle_interactions(dt) self.burning() self.spread_fire() \ No newline at end of file diff --git a/src/rendering/rendering.py b/src/rendering/rendering.py index 644e7f1..05f7b89 100644 --- a/src/rendering/rendering.py +++ b/src/rendering/rendering.py @@ -22,7 +22,7 @@ The `clear_screen` function is used to reset the simulation grid and clear the d """ -from src.config.settings import pygame, random, particle_properties, engine_settings +from config.settings import pygame, random, particle_properties, engine_settings class Rendering: diff --git a/src/sandpypi.py b/src/sandpypi.py index 53ec4b9..5e8d16a 100644 --- a/src/sandpypi.py +++ b/src/sandpypi.py @@ -15,10 +15,10 @@ The main loop runs at a target frame rate of 60 FPS (this fps varies on my mood """ # Import Require files for the Engine. -from src.config.settings import pygame, engine_settings +from config.settings import pygame, engine_settings, cProfile, pstats -from src.rendering.rendering import Rendering -from src.physics.sim import Simulation +from rendering.rendering import Rendering +from physics.sim import Simulation """ This is for the future physics engine until i figure out a better method used for testing right now. @@ -312,3 +312,17 @@ def main(): pygame.display.flip() pygame.quit() + +if __name__ == "__main__": + # Profile the application + profiler = cProfile.Profile() + profiler.enable() + + main() + + profiler.disable() + # Write profiling results to file + with open('profile_results.log', 'w') as f: + stats = pstats.Stats(profiler, stream=f) + stats.sort_stats('cumulative') + stats.print_stats()