purdyfied and added to the commit messages
may of changed a couple of other things maybe minor tweaks to physics.
This commit is contained in:
parent
1a6ef4f3c4
commit
a03ba2b950
Binary file not shown.
Binary file not shown.
21
rendering.py
21
rendering.py
@ -1,6 +1,6 @@
|
|||||||
#File Name: rendering.py
|
#File Name: rendering.py
|
||||||
|
|
||||||
from settings import pygame, json, random, particle_properties
|
from settings import pygame, random, particle_properties
|
||||||
|
|
||||||
class Rendering:
|
class Rendering:
|
||||||
|
|
||||||
@ -21,12 +21,7 @@ class Rendering:
|
|||||||
for name, properties in particle_properties.items():
|
for name, properties in particle_properties.items():
|
||||||
if 'color' in properties:
|
if 'color' in properties:
|
||||||
self.particle_colors[name.lower()] = properties['color']
|
self.particle_colors[name.lower()] = properties['color']
|
||||||
self.categories = {
|
self.categories = {'Solids': [], 'Liquids': [], 'Gases': [], 'Special': []}
|
||||||
'Solids': [],
|
|
||||||
'Liquids': [],
|
|
||||||
'Gases': [],
|
|
||||||
'Special': []
|
|
||||||
}
|
|
||||||
for particle_name, properties in self.particle_properties.items():
|
for particle_name, properties in self.particle_properties.items():
|
||||||
if properties.get('is_gas'):
|
if properties.get('is_gas'):
|
||||||
self.categories['Gases'].append(particle_name)
|
self.categories['Gases'].append(particle_name)
|
||||||
@ -63,7 +58,7 @@ class Rendering:
|
|||||||
x_offset += self.button_width + 10 # Add spacing between buttons
|
x_offset += self.button_width + 10 # Add spacing between buttons
|
||||||
|
|
||||||
|
|
||||||
def draw_particles(self, particles, active_particles, particle_size, particle_colors):
|
def draw_particles(self, particles, active_particles, particle_size, particle_colors): # this is the function that draws the particles
|
||||||
self.particle_surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
self.particle_surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
||||||
self.particle_surface.fill((0, 0, 0, 0))
|
self.particle_surface.fill((0, 0, 0, 0))
|
||||||
|
|
||||||
@ -99,7 +94,7 @@ class Rendering:
|
|||||||
self.screen.blit(self.particle_surface, (0, 0))
|
self.screen.blit(self.particle_surface, (0, 0))
|
||||||
|
|
||||||
|
|
||||||
def draw_debug_overlay(self, fps, particles):
|
def draw_debug_overlay(self, fps, particles): # this is the function that draws the debug overlay
|
||||||
# Get mouse position and convert to grid coordinates
|
# Get mouse position and convert to grid coordinates
|
||||||
mouse_x, mouse_y = pygame.mouse.get_pos()
|
mouse_x, mouse_y = pygame.mouse.get_pos()
|
||||||
grid_x = mouse_x // 3
|
grid_x = mouse_x // 3
|
||||||
@ -143,7 +138,7 @@ class Rendering:
|
|||||||
y_offset += 25
|
y_offset += 25
|
||||||
|
|
||||||
|
|
||||||
def draw_buttons(self):
|
def draw_buttons(self): # this is the function that draws the buttons
|
||||||
self.buttons = {}
|
self.buttons = {}
|
||||||
|
|
||||||
# Draw category buttons vertically on right
|
# Draw category buttons vertically on right
|
||||||
@ -181,12 +176,12 @@ class Rendering:
|
|||||||
self.screen.blit(label, (self.clear_screen_button.x + 5, self.clear_screen_button.y + 5))
|
self.screen.blit(label, (self.clear_screen_button.x + 5, self.clear_screen_button.y + 5))
|
||||||
|
|
||||||
|
|
||||||
def render_brush_curser(self, x, y, radius):
|
def render_brush_curser(self, x, y, radius): # this is the function that draws the brush curser but isn't used yet so unkown if works
|
||||||
# Draw a circle cursor for brushsize
|
# Draw a circle cursor for brushsize
|
||||||
pygame.draw.circle(self.screen, (255, 255, 255), (x, y), radius)
|
pygame.draw.circle(self.screen, (255, 255, 255), (x, y), radius)
|
||||||
|
|
||||||
|
|
||||||
def draw_brush_size_slider(self, brush_size):
|
def draw_brush_size_slider(self, brush_size): # this is the function that draws the brush size slider
|
||||||
# Draw the slider for brush size
|
# Draw the slider for brush size
|
||||||
pygame.draw.rect(self.screen, (255, 255, 255), (500, 10, 100, 20))
|
pygame.draw.rect(self.screen, (255, 255, 255), (500, 10, 100, 20))
|
||||||
pygame.draw.rect(self.screen, (0, 0, 0), (500, 10, 100, 20), 2)
|
pygame.draw.rect(self.screen, (0, 0, 0), (500, 10, 100, 20), 2)
|
||||||
@ -195,7 +190,7 @@ class Rendering:
|
|||||||
self.screen.blit(label, (500, 10))
|
self.screen.blit(label, (500, 10))
|
||||||
|
|
||||||
|
|
||||||
def clear_screen(self, sim):
|
def clear_screen(self, sim): ## this is the function that clears the screen
|
||||||
# Store current particle type
|
# Store current particle type
|
||||||
current_type = sim.current_particle_type
|
current_type = sim.current_particle_type
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ from settings import pygame
|
|||||||
from rendering import Rendering
|
from rendering import Rendering
|
||||||
from sim import Simulation
|
from sim import Simulation
|
||||||
|
|
||||||
def main():
|
def main(): # Main function to run the program
|
||||||
pygame.init()
|
pygame.init()
|
||||||
clock = pygame.time.Clock()
|
clock = pygame.time.Clock()
|
||||||
pygame.display.set_mode((1024, 768), pygame.HWSURFACE | pygame.DOUBLEBUF)
|
pygame.display.set_mode((1024, 768), pygame.HWSURFACE | pygame.DOUBLEBUF)
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
#File Name: settings.py
|
||||||
|
# Global settings and impoorts for the project.
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
|
|||||||
2
setup.py
2
setup.py
@ -1,3 +1,5 @@
|
|||||||
|
#this be a wip maybe gonna move heavy work loads to cython.
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from Cython.Build import cythonize
|
from Cython.Build import cythonize
|
||||||
|
|
||||||
|
|||||||
52
sim.py
52
sim.py
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#Load the imports. Pygame is what makes this even work and so simple may consider other engines for performance depends on learning curve.
|
#Load the imports. Pygame is what makes this even work and so simple may consider other engines for performance depends on learning curve.
|
||||||
|
|
||||||
from settings import json, random, time, particle_properties
|
from settings import random, particle_properties
|
||||||
|
|
||||||
# Load particle properties from json so we know what particles we got and how they should be simulated.
|
# Load particle properties from json so we know what particles we got and how they should be simulated.
|
||||||
class Particle:
|
class Particle:
|
||||||
@ -76,7 +76,7 @@ class Simulation:
|
|||||||
self.wind = [0.0, 0.0] # Global wind vector (x, y)
|
self.wind = [0.0, 0.0] # Global wind vector (x, y)
|
||||||
|
|
||||||
|
|
||||||
def handle_phase_transitions(self, particle, x, y):
|
def handle_phase_transitions(self, particle, x, y): # this is where we handle all the phase transitions.
|
||||||
"""Handle all phase transitions for a particle"""
|
"""Handle all phase transitions for a particle"""
|
||||||
# Check evaporation
|
# Check evaporation
|
||||||
if hasattr(particle, 'evaporate_temperature') and particle.evaporate_temperature is not None:
|
if hasattr(particle, 'evaporate_temperature') and particle.evaporate_temperature is not None:
|
||||||
@ -99,7 +99,7 @@ class Simulation:
|
|||||||
self.transform_particle(x, y, particle.solidify)
|
self.transform_particle(x, y, particle.solidify)
|
||||||
|
|
||||||
|
|
||||||
def handle_particle_interactions(self, dt):
|
def handle_particle_interactions(self, dt): # this is where we handle all the particle interactions.
|
||||||
"""Handle interactions between different particle types"""
|
"""Handle interactions between different particle types"""
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
particle = self.particles[x][y]
|
particle = self.particles[x][y]
|
||||||
@ -115,7 +115,7 @@ class Simulation:
|
|||||||
self.process_interaction(particle, neighbor, x, y, nx, ny)
|
self.process_interaction(particle, neighbor, x, y, nx, ny)
|
||||||
|
|
||||||
|
|
||||||
def process_interaction(self, particle1, particle2, x1, y1, x2, y2):
|
def process_interaction(self, particle1, particle2, x1, y1, x2, y2): # this function is part 2 of handle_particle_interactions.
|
||||||
"""Process specific interactions between two particles"""
|
"""Process specific interactions between two particles"""
|
||||||
# Water + Sand = Mud
|
# Water + Sand = Mud
|
||||||
if (particle1.particle_type == 'water' and particle2.particle_type == 'sand' or
|
if (particle1.particle_type == 'water' and particle2.particle_type == 'sand' or
|
||||||
@ -139,7 +139,7 @@ class Simulation:
|
|||||||
self.transform_particle(target_x, target_y, 'fire')
|
self.transform_particle(target_x, target_y, 'fire')
|
||||||
|
|
||||||
|
|
||||||
def create_mud(self, x, y):
|
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"""
|
"""Create mud particle from water and sand interaction"""
|
||||||
if 'mud' in self.particle_properties:
|
if 'mud' in self.particle_properties:
|
||||||
properties = self.particle_properties['mud']
|
properties = self.particle_properties['mud']
|
||||||
@ -148,7 +148,7 @@ class Simulation:
|
|||||||
self.active_particles.add((x, y))
|
self.active_particles.add((x, y))
|
||||||
|
|
||||||
|
|
||||||
def transform_particle(self, x, y, new_type):
|
def transform_particle(self, x, y, new_type): # this is where we transform the particle.
|
||||||
"""Transform a particle into a different type"""
|
"""Transform a particle into a different type"""
|
||||||
if new_type in self.particle_properties:
|
if new_type in self.particle_properties:
|
||||||
properties = self.particle_properties[new_type]
|
properties = self.particle_properties[new_type]
|
||||||
@ -157,7 +157,7 @@ class Simulation:
|
|||||||
self.active_particles.add((x, y))
|
self.active_particles.add((x, y))
|
||||||
|
|
||||||
|
|
||||||
def handle_gas_movement(self, particle, x, y):
|
def handle_gas_movement(self, particle, x, y): # this is where we handle the gas movement. this function sucks. wip
|
||||||
"""Handle gas particle movement"""
|
"""Handle gas particle movement"""
|
||||||
if particle.is_gas:
|
if particle.is_gas:
|
||||||
dx = random.uniform(-1, 1)
|
dx = random.uniform(-1, 1)
|
||||||
@ -173,7 +173,7 @@ class Simulation:
|
|||||||
self.active_particles.discard((x, y))
|
self.active_particles.discard((x, y))
|
||||||
|
|
||||||
|
|
||||||
def temperature(self, dt):
|
def temperature(self, dt): # this is where we handle the temperature.
|
||||||
"""Handle temperature changes and state transitions"""
|
"""Handle temperature changes and state transitions"""
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
particle = self.particles[x][y]
|
particle = self.particles[x][y]
|
||||||
@ -188,7 +188,7 @@ class Simulation:
|
|||||||
particle.is_gas = False
|
particle.is_gas = False
|
||||||
|
|
||||||
|
|
||||||
def calculate_forces(self, particle, x, y):
|
def calculate_forces(self, particle, x, y): # this is where we calculate the forces.
|
||||||
"""Calculate net forces acting on a particle."""
|
"""Calculate net forces acting on a particle."""
|
||||||
fx, fy = 0.0, 0.0 # Initialize forces
|
fx, fy = 0.0, 0.0 # Initialize forces
|
||||||
|
|
||||||
@ -220,7 +220,7 @@ class Simulation:
|
|||||||
return fx, fy
|
return fx, fy
|
||||||
|
|
||||||
|
|
||||||
def ignite_particle(self, particle):
|
def ignite_particle(self, particle): # this is where we ignite the particle.
|
||||||
"""Handle ignition and burning of flammable particles."""
|
"""Handle ignition and burning of flammable particles."""
|
||||||
if hasattr(particle, 'flamability') and particle.flamability > 0.5:
|
if hasattr(particle, 'flamability') and particle.flamability > 0.5:
|
||||||
if hasattr(particle, 'temperature') and particle.temperature > 150:
|
if hasattr(particle, 'temperature') and particle.temperature > 150:
|
||||||
@ -229,10 +229,10 @@ class Simulation:
|
|||||||
# Add burning effect for wood
|
# Add burning effect for wood
|
||||||
if particle.type == 'wood':
|
if particle.type == 'wood':
|
||||||
particle.burning = True
|
particle.burning = True
|
||||||
particle.burn_time = 100 # Adjust burn time as needed
|
particle.burn_time = 100 # burn time
|
||||||
|
|
||||||
|
|
||||||
def spread_fire(self):
|
def spread_fire(self): # this is where we spread the fire.
|
||||||
"""Spread fire to neighboring particles."""
|
"""Spread fire to neighboring particles."""
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
particle = self.particles[x][y]
|
particle = self.particles[x][y]
|
||||||
@ -253,7 +253,7 @@ class Simulation:
|
|||||||
self.ignite_particle(neighbor)
|
self.ignite_particle(neighbor)
|
||||||
|
|
||||||
|
|
||||||
def handle_temperature(self, dt):
|
def handle_temperature(self, dt): # this is where we handle the temperature.
|
||||||
"""Handle temperature changes and state transitions"""
|
"""Handle temperature changes and state transitions"""
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
particle = self.particles[x][y]
|
particle = self.particles[x][y]
|
||||||
@ -289,7 +289,7 @@ class Simulation:
|
|||||||
neighbor.temperature += heat_transfer
|
neighbor.temperature += heat_transfer
|
||||||
|
|
||||||
|
|
||||||
def burning(self):
|
def burning(self): # this is where we handle the burning.
|
||||||
"""Handle burning of particles."""
|
"""Handle burning of particles."""
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
particle = self.particles[x][y]
|
particle = self.particles[x][y]
|
||||||
@ -301,27 +301,27 @@ class Simulation:
|
|||||||
self.spatial_grid.pop((x, y), None)
|
self.spatial_grid.pop((x, y), None)
|
||||||
|
|
||||||
|
|
||||||
def get_cell_key(self, x, y):
|
def get_cell_key(self, x, y): # this is where we get the cell key.
|
||||||
# Convert coordinates to grid cell
|
# Convert coordinates to grid cell
|
||||||
cell_x = x // self.cell_size
|
cell_x = x // self.cell_size
|
||||||
cell_y = y // self.cell_size
|
cell_y = y // self.cell_size
|
||||||
return (cell_x, cell_y)
|
return (cell_x, cell_y)
|
||||||
|
|
||||||
|
|
||||||
def add_to_spatial_grid(self, particle, x, y):
|
def add_to_spatial_grid(self, particle, x, y): # this is where we add to the spatial grid.
|
||||||
cell_key = self.get_cell_key(x, y)
|
cell_key = self.get_cell_key(x, y)
|
||||||
if cell_key not in self.spatial_grid:
|
if cell_key not in self.spatial_grid:
|
||||||
self.spatial_grid[cell_key] = set()
|
self.spatial_grid[cell_key] = set()
|
||||||
self.spatial_grid[cell_key].add((x, y))
|
self.spatial_grid[cell_key].add((x, y))
|
||||||
|
|
||||||
|
|
||||||
def remove_from_spatial_grid(self, x, y):
|
def remove_from_spatial_grid(self, x, y): # this is where we remove from the spatial grid.
|
||||||
cell_key = self.get_cell_key(x, y)
|
cell_key = self.get_cell_key(x, y)
|
||||||
if cell_key in self.spatial_grid:
|
if cell_key in self.spatial_grid:
|
||||||
self.spatial_grid[cell_key].discard((x, y))
|
self.spatial_grid[cell_key].discard((x, y))
|
||||||
|
|
||||||
|
|
||||||
def create_particle_circle(self, center_x, center_y):
|
def create_particle_circle(self, center_x, center_y): # this is where we create the particle circle.
|
||||||
brush_size = int(self.brush_size)
|
brush_size = int(self.brush_size)
|
||||||
for dx in range(-brush_size, brush_size + 1):
|
for dx in range(-brush_size, brush_size + 1):
|
||||||
for dy in range(-brush_size, brush_size + 1):
|
for dy in range(-brush_size, brush_size + 1):
|
||||||
@ -330,7 +330,7 @@ class Simulation:
|
|||||||
center_y + dy * self.particle_size)
|
center_y + dy * self.particle_size)
|
||||||
|
|
||||||
|
|
||||||
def create_particle(self, x, y):
|
def create_particle(self, x, y): # this is where we create the particle.
|
||||||
"""Create a new particle with full property support"""
|
"""Create a new particle with full property support"""
|
||||||
particle_type = self.current_particle_type.lower()
|
particle_type = self.current_particle_type.lower()
|
||||||
if particle_type in self.particle_properties:
|
if particle_type in self.particle_properties:
|
||||||
@ -352,14 +352,14 @@ class Simulation:
|
|||||||
self.active_particles.add((grid_x, grid_y))
|
self.active_particles.add((grid_x, grid_y))
|
||||||
|
|
||||||
|
|
||||||
def update_spatial_grid(self):
|
def update_spatial_grid(self): # this is where we update the spatial grid.
|
||||||
"""Update spatial grid for optimized collision detection"""
|
"""Update spatial grid for optimized collision detection"""
|
||||||
self.spatial_grid.clear()
|
self.spatial_grid.clear()
|
||||||
for x, y in self.active_particles:
|
for x, y in self.active_particles:
|
||||||
self.add_to_spatial_grid(self.particles[x][y], x, y)
|
self.add_to_spatial_grid(self.particles[x][y], x, y)
|
||||||
|
|
||||||
|
|
||||||
def apply_gravity(self, dt):
|
def apply_gravity(self, dt): # this is where we apply gravity.
|
||||||
"""Handle only gravity and basic particle movement"""
|
"""Handle only gravity and basic particle movement"""
|
||||||
self.spatial_grid.clear()
|
self.spatial_grid.clear()
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ class Simulation:
|
|||||||
particle.position = (new_x, new_y)
|
particle.position = (new_x, new_y)
|
||||||
|
|
||||||
|
|
||||||
def handle_special_particles(self, particle, x, y):
|
def handle_special_particles(self, particle, x, y): # this is where we handle special particles.
|
||||||
"""Handle special particle behaviors"""
|
"""Handle special particle behaviors"""
|
||||||
if particle.particle_type in ['fire', 'flame', 'smoke']:
|
if particle.particle_type in ['fire', 'flame', 'smoke']:
|
||||||
if random.random() < 0.6: # % chance
|
if random.random() < 0.6: # % chance
|
||||||
@ -446,7 +446,7 @@ class Simulation:
|
|||||||
self.active_particles.add((x, y))
|
self.active_particles.add((x, y))
|
||||||
|
|
||||||
|
|
||||||
def apply_physics(self, dt):
|
def apply_physics(self, dt): # this is where we apply physics.
|
||||||
"""Handle all physics effects"""
|
"""Handle all physics effects"""
|
||||||
new_active_particles = set()
|
new_active_particles = set()
|
||||||
|
|
||||||
@ -497,7 +497,7 @@ class Simulation:
|
|||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Air handling - particles can pass through
|
# Air handling - particles can pass through should implement proper air instead of a particle
|
||||||
if particle.particle_type == 'air':
|
if particle.particle_type == 'air':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -559,7 +559,7 @@ class Simulation:
|
|||||||
self.active_particles = new_active_particles
|
self.active_particles = new_active_particles
|
||||||
|
|
||||||
|
|
||||||
def clear_particles_circle(self, center_x, center_y):
|
def clear_particles_circle(self, center_x, center_y): # this is for the brush tool
|
||||||
"""Clear particles in a circle around the given point based on brush size"""
|
"""Clear particles in a circle around the given point based on brush size"""
|
||||||
brush_size = int(self.brush_size)
|
brush_size = int(self.brush_size)
|
||||||
for dx in range(-brush_size, brush_size + 1):
|
for dx in range(-brush_size, brush_size + 1):
|
||||||
@ -575,7 +575,7 @@ class Simulation:
|
|||||||
self.remove_from_spatial_grid(grid_x, grid_y)
|
self.remove_from_spatial_grid(grid_x, grid_y)
|
||||||
|
|
||||||
|
|
||||||
def mix_liquids(self, liquid1, liquid2):
|
def mix_liquids(self, liquid1, liquid2): # this is for the mix tool
|
||||||
"""Handle liquid mixing interactions"""
|
"""Handle liquid mixing interactions"""
|
||||||
if liquid1.temperature != liquid2.temperature:
|
if liquid1.temperature != liquid2.temperature:
|
||||||
avg_temp = (liquid1.temperature + liquid2.temperature) / 2
|
avg_temp = (liquid1.temperature + liquid2.temperature) / 2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user