sandpypi/sandpypi.py
Stan44 b9a280208b made several changes working on zoom
added proper particle count
there is a settings menu
some keybindings have been added ESC to exit
Glowing particles are now a thing
Gas effects can be toggled on and off for performance
2024-12-26 19:16:46 -06:00

158 lines
6.3 KiB
Python

#File Name: sandpypi.py
# Sandpypi by Stanton.
# Project name is a placeholder.
# This has been a multimonth or year project i have time blindness sorta.
# This is my most functional system for falling sand in python yet i took some things i learned in JS.
# This needs further optimizations to core performance sections.
from settings import pygame, engine_settings
from rendering import Rendering
from sim import Simulation
def main(): # Main function to run the program
pygame.init()
clock = pygame.time.Clock()
width = 1024
height = 768
screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
sim = Simulation(width, height)
rendering = Rendering(width, height)
mouse_down_left = False
mouse_down_right = False
mouse_down_middle = False
mouse_down_wheel_up = False
mouse_down_wheel_down = False
over_button = False
zoom_active = False
zoom_locked = False
zoom_pos = None
settings_visible = False
settings_menu_y = 100
running = True
while running:
fps = clock.get_fps()
dt = clock.tick(60) / 1000
keys = pygame.key.get_pressed()
zoom_active = keys[pygame.K_z]
# Handle events
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
if event.button == 4: # Mouse wheel up
sim.brush_size = min(sim.brush_size + 1, sim.max_brush_size)
elif event.button == 5: # Mouse wheel down
sim.brush_size = max(sim.brush_size - 1, 1)
elif event.button == 1: # Left click
over_button = False
if zoom_active:
zoom_locked = not zoom_locked
if zoom_locked:
zoom_pos = mouse_pos
# Check category buttons
for category, button in rendering.category_buttons.items():
if button.collidepoint(mouse_pos):
rendering.current_category = category
over_button = True
break
# Check particle buttons
if not over_button:
for particle_type, button in rendering.buttons.items():
if button.collidepoint(mouse_pos):
sim.current_particle_type = particle_type
over_button = True
break
# Check clear screen button
if rendering.clear_screen_button.collidepoint(mouse_pos):
rendering.clear_screen(sim)
over_button = True
if rendering.settings_button.collidepoint(event.pos):
settings_visible = not settings_visible
elif settings_visible:
# Handle settings toggles
mouse_pos = pygame.mouse.get_pos()
relative_y = mouse_pos[1] - settings_menu_y
setting_index = relative_y // 30
if 0 <= setting_index < len(engine_settings):
setting_name = list(engine_settings.keys())[setting_index]
engine_settings[setting_name] = not engine_settings[setting_name]
if not over_button:
mouse_down_left = True
elif event.button == 3: # Right click
mouse_down_right = True
elif event.button == 2: # Middle click
mouse_down_middle = True
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_down_left = False
elif event.type == pygame.MOUSEBUTTONUP and event.button == 3:
mouse_down_right = False
elif event.type == pygame.MOUSEBUTTONUP and event.button == 2:
mouse_down_middle = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
print("Escape button pressed")
print(f"Exiting Program {__file__}")
running = False
elif event.key == pygame.K_SPACE:
print(f"Pause button pressed but not functional 'Space'")
pass
elif event.key == pygame.K_c:
rendering.clear_screen(sim)
elif event.key == pygame.K_z:
zoom_active = not zoom_active
if zoom_active:
zoom_locked = False
zoom_pos = pygame.mouse.get_pos()
elif event.type == pygame.QUIT:
running = False
if mouse_down_left and not over_button:
x, y = pygame.mouse.get_pos()
sim.create_particle_circle(x, y)
if mouse_down_right:
x, y = pygame.mouse.get_pos()
sim.clear_particles_circle(x, y)
if mouse_down_middle:
x, y = pygame.mouse.get_pos()
sim.create_particle(x, y)
sim.simulate_step(dt)
rendering.draw_particles(sim.particles, sim.active_particles, sim.particle_size, rendering.particle_colors)
rendering.draw_buttons()
rendering.draw_brush_size_slider(sim.brush_size)
if zoom_active or zoom_locked:
mouse_pos = zoom_pos if zoom_locked else pygame.mouse.get_pos()
zoom_surface = rendering.draw_zoom_window(sim.particles, sim.particle_size, rendering.particle_colors, mouse_pos)
# Position zoom window
zoom_x = 10 if mouse_pos[0] > width/2 else width - 110
zoom_y = 10 if mouse_pos[1] > height/2 else height - 110
screen.blit(zoom_surface, (zoom_x, zoom_y))
if settings_visible:
settings_menu = rendering.draw_settings_menu()
rendering.screen.blit(settings_menu, (rendering.width - 320, 100))
rendering.draw_debug_overlay(fps, sim.particles)
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()