Make a modular BaseGame class that all Games are based on to decrease bloat, add Diaunay simulation and fix some stuff in README

This commit is contained in:
csd4ni3l
2025-09-28 21:20:15 +02:00
parent 195a429ff5
commit 311d3607f2
14 changed files with 242 additions and 407 deletions

View File

@@ -1,4 +1,18 @@
Some simulator games i tried to make to get better at math and interesting concepts. Currently includes a Boids simulator, Water Simulator, Physics Sandbox, Chladni Plate simulation, Fourier simulation, Lissajous simulation, Voronoi Diagram simulation, Lorenz Attractor simulation, Spirograph simulator and a Double Pendulum Simulator. Some simulator games i tried to make to get better at math and interesting concepts.
Currently includes:
- Boids simulator
- Water simulator
- Physics Sandbox
- Chladni Plate simulator
- Fourier simulator
- Lissajous simulator
- Voronoi Diagram simulator
- Lorenz Attractor simulator
- Spirograph simulator
- Delaunay Triangulation simulator
- Double Pendulum simulator
I wanted to add a Triple Pendulum Simulator but it was too hard.
The Water Simulator simulates 2d water splashes. The Water Simulator simulates 2d water splashes.
The Physics Sandbox includes crates, coins, and any custom SVG you want! Use w to place the current inventory item, and on the right bottom you can select new ones. The Physics Sandbox includes crates, coins, and any custom SVG you want! Use w to place the current inventory item, and on the right bottom you can select new ones.

45
game/base.py Normal file
View File

@@ -0,0 +1,45 @@
import arcade, arcade.gui, os, json
class BaseGame(arcade.gui.UIView):
def __init__(self, pypresence_client, game_name, game_key, game_dict):
super().__init__()
self.game_name = game_name
self.game_key = game_key
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details=game_name)
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
self.settings_space = self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not game_key in self.settings:
self.settings[game_key] = game_dict
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings[self.game_key][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings[self.game_key][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value)
self.settings[self.game_key][settings_key] = value
def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE:
with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))

View File

@@ -1,57 +1,30 @@
import arcade, arcade.gui, random, os, json import arcade, random
from game.boid_simulator.boid import Boid from game.boid_simulator.boid import Boid
from game.base import BaseGame
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Boid Simulator", "boid_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state='Playing a simulator', details='Boids simulator', start=self.pypresence_client.start_time)
self.boid_sprites = arcade.SpriteList()
self.current_boid_num = 1
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "boid_simulator" in self.settings:
self.settings["boid_simulator"] = {
"w_separation": 1.0, "w_separation": 1.0,
"w_alignment": 1.0, "w_alignment": 1.0,
"w_cohesion": 1.0, "w_cohesion": 1.0,
"small_radius": 100, "small_radius": 100,
"large_radius": 250 "large_radius": 250
} })
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1))) self.current_boid_num = 1
self.boid_sprites = arcade.SpriteList()
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=5, align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
self.add_setting("Separation Weight: {value}", 0.1, 5, 0.1, "w_separation") self.add_setting("Separation Weight: {value}", 0.1, 5, 0.1, "w_separation")
self.add_setting("Alignment Weight: {value}", 0.1, 5, 0.1, "w_alignment") self.add_setting("Alignment Weight: {value}", 0.1, 5, 0.1, "w_alignment")
self.add_setting("Cohesion Weight: {value}", 0.1, 5, 0.1, "w_cohesion") self.add_setting("Cohesion Weight: {value}", 0.1, 5, 0.1, "w_cohesion")
self.add_setting("Small Radius: {value}", 25, 250, 25, "small_radius") self.add_setting("Small Radius: {value}", 25, 250, 25, "small_radius")
self.add_setting("Large Radius: {value}", 50, 500, 50, "large_radius") self.add_setting("Large Radius: {value}", 50, 500, 50, "large_radius")
def save_data(self):
with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
def add_setting(self, text, min_value, max_value, step, boid_variable):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["boid_simulator"][boid_variable])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["boid_simulator"][boid_variable], min_value=min_value, max_value=max_value, step=step, size_hint=(1, 0.05)))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, boid_variable, event.new_value)
def change_value(self, label, text, boid_variable, value): def change_value(self, label, text, boid_variable, value):
label.text = text.format(value=value) super().change_value(label, text, boid_variable, value)
self.settings["boid_simulator"][boid_variable] = value
for boid in self.boid_sprites: for boid in self.boid_sprites:
setattr(boid, boid_variable, value) setattr(boid, boid_variable, value)
@@ -83,13 +56,6 @@ class Game(arcade.gui.UIView):
if self.window.mouse[arcade.MOUSE_BUTTON_LEFT]: if self.window.mouse[arcade.MOUSE_BUTTON_LEFT]:
self.create_boid(self.window.mouse.data["x"], self.window.mouse.data["y"]) self.create_boid(self.window.mouse.data["x"], self.window.mouse.data["y"])
def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE:
self.save_data()
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
def on_draw(self): def on_draw(self):
super().on_draw() super().on_draw()
self.boid_sprites.draw() self.boid_sprites.draw()

View File

@@ -1,49 +1,24 @@
import pyglet, arcade, arcade.gui, os, json, numpy as np import pyglet, arcade, arcade.gui, os, json, numpy as np
from game.chladni_plate_simulator.shader import create_shader from game.chladni_plate_simulator.shader import create_shader
from game.base import BaseGame
from utils.preload import button_texture, button_hovered_texture from utils.preload import button_texture, button_hovered_texture
from utils.constants import button_style from utils.constants import button_style
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Chladni Plate Simulator", "chladni_plate_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Chladni Plate Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "chladni_plate_simulator" in self.settings:
self.settings["chladni_plate_simulator"] = {
"k": 0.1 "k": 0.1
} })
self.sources = np.empty((0, 2), dtype=np.float32) self.sources = np.empty((0, 2), dtype=np.float32)
self.dragged_source = None self.dragged_source = None
self.needs_redraw = False self.needs_redraw = False
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["chladni_plate_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["chladni_plate_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value): def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value) super().change_value(label, text, settings_key, value)
self.settings["chladni_plate_simulator"][settings_key] = value
self.needs_redraw = True self.needs_redraw = True
@@ -86,8 +61,6 @@ class Game(arcade.gui.UIView):
def on_show_view(self): def on_show_view(self):
super().on_show_view() super().on_show_view()
self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
self.add_setting("k: {value}", 0.02, 0.5, 0.01, "k") self.add_setting("k: {value}", 0.02, 0.5, 0.01, "k")
self.add_source_button = self.settings_box.add(arcade.gui.UITextureButton(text="Add source", texture=button_texture, texture_hovered=button_hovered_texture, style=button_style, width=self.window.width * 0.2)) self.add_source_button = self.settings_box.add(arcade.gui.UITextureButton(text="Add source", texture=button_texture, texture_hovered=button_hovered_texture, style=button_style, width=self.window.width * 0.2))
@@ -96,14 +69,9 @@ class Game(arcade.gui.UIView):
self.setup() self.setup()
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: super().on_key_press(symbol, modifiers)
self.shader_program.delete()
self.sources_ssbo.delete() if symbol == arcade.key.C:
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
elif symbol == arcade.key.C:
del self.sources del self.sources
self.sources = np.empty((0, 2), dtype=np.float32) self.sources = np.empty((0, 2), dtype=np.float32)

View File

@@ -0,0 +1,87 @@
import arcade, arcade.gui, numpy as np, random, math
from scipy.spatial import Delaunay
from game.base import BaseGame
from utils.constants import button_style
from utils.preload import button_texture, button_hovered_texture
class Game(BaseGame):
def __init__(self, pypresence_client):
super().__init__(pypresence_client, "Delaunay Triangulation", "delaunay_simulator", {})
self.points = []
[self.add_point() for _ in range(4)]
self.fixed_points = [(0, 0), (0, self.window.height), (self.window.width * 0.8, 0), (self.window.width * 0.8, self.window.height)]
self.triangles = None
self.dragged_point = None
self.needs_recalc = True
def fract(self, x):
return x - math.floor(x)
def hash3(self, p: float) -> arcade.math.Vec3:
p3 = arcade.math.Vec3(p * 127.1, p * 311.7, p * 74.7)
return arcade.math.Vec3(
int(self.fract(math.sin(p3.x) * 43758.5453123) * 255),
int(self.fract(math.sin(p3.y) * 43758.5453123) * 255),
int(self.fract(math.sin(p3.z) * 43758.5453123) * 255)
)
def on_show_view(self):
super().on_show_view()
self.add_point_button = self.settings_box.add(arcade.gui.UITextureButton(width=self.window.width * 0.2, text="Add Point", texture=button_texture, texture_hovered=button_hovered_texture, style=button_style))
self.add_point_button.on_click = lambda event: self.add_point()
def change_value(self, label, text, settings_key, value):
super().change_value(label, text, settings_key, value)
self.needs_recalc = True
def add_point(self):
self.points.append((random.randint(0, (self.window.width * 0.8)), random.randint(0, self.window.height - 0)))
self.needs_recalc = True
def on_mouse_press(self, x, y, button, modifiers):
if not self.dragged_point:
for i, point in enumerate(self.points):
if arcade.math.Vec2(x, y).distance(arcade.math.Vec2(*point)) <= 10:
self.dragged_point = i
break
def on_mouse_drag(self, x, y, dx, dy, _buttons, _modifiers):
if self.dragged_point is not None:
self.points[self.dragged_point] = [x, y]
self.needs_recalc = True
def on_mouse_release(self, x, y, button, modifiers):
self.dragged_point = None
self.needs_recalc = True
def on_draw(self):
super().on_draw()
if self.triangles is not None:
for n, simplex in enumerate(self.triangles):
points = self.points + self.fixed_points
p1 = points[simplex[0]]
p2 = points[simplex[1]]
p3 = points[simplex[2]]
arcade.draw_triangle_filled(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1], self.hash3(n))
for point in self.points + self.fixed_points:
arcade.draw_circle_filled(point[0] + 5, point[1] + 5, 10, arcade.color.GRAY)
def on_update(self, delta_time):
if self.needs_recalc:
self.needs_recalc = False
self.triangles = Delaunay(np.array(self.points + self.fixed_points)).simplices

View File

@@ -1,36 +1,18 @@
import arcade, arcade.gui, json, os, math import arcade, arcade.gui, json, os, math
from utils.constants import button_style from game.base import BaseGame
from utils.preload import button_texture, button_hovered_texture
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Double Pendulum Simulator", "double_pendulum_simulator", {
"length_a": 200,
self.pypresence_client = pypresence_client "length_b": 200,
self.pypresence_client.update(state="Playing a simulator", details="Double Pendulum Simulator") "mass_a": 40,
"mass_b": 40,
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1))) "gravity": 9.81,
"speed": 1.0,
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom") "trail_size": 500
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24)) })
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "double_pendulum_simulator" in self.settings:
self.settings["double_pendulum_simulator"] = {
"length_a": 200,
"length_b": 200,
"mass_a": 40,
"mass_b": 40,
"gravity": 9.81,
"speed": 1.0,
"trail_size": 500
}
self.theta_a, self.theta_b = math.pi / 2, math.pi / 2 self.theta_a, self.theta_b = math.pi / 2, math.pi / 2
self.omega_a, self.omega_b = 0, 0 self.omega_a, self.omega_b = 0, 0
@@ -49,18 +31,6 @@ class Game(arcade.gui.UIView):
self.add_setting("Speed: {value}", 1, 100, 1, "speed") self.add_setting("Speed: {value}", 1, 100, 1, "speed")
self.add_setting("Trail Size: {value}", 0, 5000, 50, "trail_size") self.add_setting("Trail Size: {value}", 0, 5000, 50, "trail_size")
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["double_pendulum_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["double_pendulum_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value)
self.settings["double_pendulum_simulator"][settings_key] = value
def on_draw(self): def on_draw(self):
super().on_draw() super().on_draw()
@@ -124,12 +94,4 @@ class Game(arcade.gui.UIView):
if len(self.trace) > current_settings["trail_size"]: if len(self.trace) > current_settings["trail_size"]:
self.trace = self.trace[-int(current_settings["trail_size"]):] self.trace = self.trace[-int(current_settings["trail_size"]):]
else: else:
self.trace = [] self.trace = []
def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE:
with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))

View File

@@ -2,31 +2,16 @@ import arcade, arcade.gui, os, json, numpy as np
from scipy.interpolate import interp1d from scipy.interpolate import interp1d
class Game(arcade.gui.UIView): from game.base import BaseGame
class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Fourier Simulator", "fourier_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Fourier Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "fourier_simulator" in self.settings:
self.settings["fourier_simulator"] = {
"max_coefficients": 1000, "max_coefficients": 1000,
"speed": 1.0, "speed": 1.0,
"tail_size": 1000, "tail_size": 1000,
"resampling_size": 512 "resampling_size": 512
} })
self.path_points = [] self.path_points = []
@@ -40,36 +25,11 @@ class Game(arcade.gui.UIView):
def on_show_view(self): def on_show_view(self):
super().on_show_view() super().on_show_view()
self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
self.add_setting("Max Coefficients: {value}", 1, 10000, 1, "max_coefficients") self.add_setting("Max Coefficients: {value}", 1, 10000, 1, "max_coefficients")
self.add_setting("Speed: {value}", 0.1, 1.5, 0.1, "speed") self.add_setting("Speed: {value}", 0.1, 1.5, 0.1, "speed")
self.add_setting("Tail Size: {value}", 10, 1000, 10, "tail_size") self.add_setting("Tail Size: {value}", 10, 1000, 10, "tail_size")
self.add_setting("Resampling Size: {value}", 128, 8192, 128, "resampling_size") self.add_setting("Resampling Size: {value}", 128, 8192, 128, "resampling_size")
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["fourier_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["fourier_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value)
self.settings["fourier_simulator"][settings_key] = value
def main_exit(self):
with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE:
self.main_exit()
def on_mouse_press(self, x, y, button, modifiers): def on_mouse_press(self, x, y, button, modifiers):
self.path_points = [] self.path_points = []
self.drawing_trail.clear() self.drawing_trail.clear()

View File

@@ -1,27 +1,11 @@
import pyglet, arcade, arcade.gui, os, json import pyglet, arcade, arcade.gui, os, json
from game.lissajous_simulator.shader import create_shader from game.lissajous_simulator.shader import create_shader
from game.base import BaseGame
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Lissajous Simulator", "lissajous_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Lissajous Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "lissajous_simulator" in self.settings:
self.settings["lissajous_simulator"] = {
"amplitude_x": 0.8, "amplitude_x": 0.8,
"amplitude_y": 0.8, "amplitude_y": 0.8,
"frequency_x": 3.0, "frequency_x": 3.0,
@@ -29,15 +13,13 @@ class Game(arcade.gui.UIView):
"thickness": 0.005, "thickness": 0.005,
"samples": 50, "samples": 50,
"phase_shift": 6.283 "phase_shift": 6.283
} })
self.time = 0 self.time = 0
def on_show_view(self): def on_show_view(self):
super().on_show_view() super().on_show_view()
self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
self.add_setting("X Amplitude: {value}", 0, 1.5, 0.1, "amplitude_x") self.add_setting("X Amplitude: {value}", 0, 1.5, 0.1, "amplitude_x")
self.add_setting("Y Amplitude: {value}", 0, 1.5, 0.1, "amplitude_y") self.add_setting("Y Amplitude: {value}", 0, 1.5, 0.1, "amplitude_y")
@@ -51,18 +33,6 @@ class Game(arcade.gui.UIView):
self.setup() self.setup()
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["lissajous_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["lissajous_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value)
self.settings["lissajous_simulator"][settings_key] = value
def setup(self): def setup(self):
self.shader_program, self.lissajous_image = create_shader(int(self.window.width * 0.8), self.window.height) self.shader_program, self.lissajous_image = create_shader(int(self.window.width * 0.8), self.window.height)
@@ -91,7 +61,7 @@ class Game(arcade.gui.UIView):
self.shader_program.dispatch(int(self.lissajous_image.width / 32), int(self.lissajous_image.height / 32), 1) self.shader_program.dispatch(int(self.lissajous_image.width / 32), int(self.lissajous_image.height / 32), 1)
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: if symbol == arcade.key.ESCAPE: # overwrite and no super because shader program needs to be deleted.
self.shader_program.delete() self.shader_program.delete()
with open("data.json", "w") as file: with open("data.json", "w") as file:

View File

@@ -1,35 +1,18 @@
import pyglet, arcade, arcade.gui, os, json, time import pyglet, arcade, arcade.gui, os, json, time
from game.lorenz_attractor_simulator.shader import create_shader from game.lorenz_attractor_simulator.shader import create_shader
from game.base import BaseGame
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Lorenz Attractor Simulator", "lorenz_attractor_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Lorenz Attractor Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "lorenz_attractor_simulator" in self.settings:
self.settings["lorenz_attractor_simulator"] = {
"sigma": 10, "sigma": 10,
"rho": 28, "rho": 28,
"beta": 2.66666666, "beta": 2.66666666,
"steps": 50, "steps": 50,
"decay_factor": 0.999, "decay_factor": 0.999,
"speed": 1 "speed": 1
} })
self.delta_time = 0 self.delta_time = 0
self.should_clear = False self.should_clear = False
@@ -53,17 +36,8 @@ class Game(arcade.gui.UIView):
self.setup() self.setup()
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["lorenz_attractor_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["lorenz_attractor_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value): def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value) super().change_value(label, text, settings_key, value)
self.settings["lorenz_attractor_simulator"][settings_key] = value
self.should_clear = True self.should_clear = True
@@ -71,8 +45,8 @@ class Game(arcade.gui.UIView):
if time.perf_counter() - self.last_update >= 1 / 15: if time.perf_counter() - self.last_update >= 1 / 15:
if self.should_clear: if self.should_clear:
self.should_clear = False self.should_clear = False
self.delta_time = 0 self.delta_time = 0
pyglet.gl.glClearTexImage( pyglet.gl.glClearTexImage(
self.lorenz_image.id, 0, self.lorenz_image.id, 0,
pyglet.gl.GL_RGBA, pyglet.gl.GL_FLOAT, pyglet.gl.GL_RGBA, pyglet.gl.GL_FLOAT,
@@ -97,13 +71,14 @@ class Game(arcade.gui.UIView):
self.delta_time += (current_settings["speed"] * 0.00005) self.delta_time += (current_settings["speed"] * 0.00005)
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: if symbol == arcade.key.ESCAPE: # overwrite instead of super because deleting shader program is mandatory.
self.shader_program.delete()
with open("data.json", "w") as file: with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4)) file.write(json.dumps(self.settings, indent=4))
from menus.main import Main from menus.main import Main
self.window.show_view(Main(self.pypresence_client)) self.window.show_view(Main(self.pypresence_client))
def on_draw(self): def on_draw(self):
super().on_draw() super().on_draw()

View File

@@ -1,4 +1,4 @@
import arcade, arcade.gui, pymunk, pymunk.util, math, time, os, io, json, random import arcade, arcade.gui, pymunk, pymunk.util, math, time, os, io, json
from PIL import Image from PIL import Image
@@ -7,6 +7,7 @@ from arcade.gui.experimental.scroll_area import UIScrollArea, UIScrollBar
from pymunk.autogeometry import convex_decomposition from pymunk.autogeometry import convex_decomposition
from game.physics_playground.body_inventory import BodyInventory from game.physics_playground.body_inventory import BodyInventory
from game.base import BaseGame
from utils.constants import menu_background_color, button_style from utils.constants import menu_background_color, button_style
from utils.preload import button_texture, button_hovered_texture from utils.preload import button_texture, button_hovered_texture
@@ -36,23 +37,9 @@ class PhysicsCrate(SpritePhysics):
self.width = width self.width = width
self.height = height self.height = height
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Physics Playground", "physics_playground", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state='Playing a simulator', details='Physics Playground', start=self.pypresence_client.start_time)
arcade.set_background_color(arcade.color.WHITE)
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "physics_playground" in self.settings:
self.settings["physics_playground"] = {
"iterations": 50, "iterations": 50,
"gravity_x": 0, "gravity_x": 0,
"gravity_y": -930, "gravity_y": -930,
@@ -68,7 +55,9 @@ class Game(arcade.gui.UIView):
"custom_elasticity": 0.5, "custom_elasticity": 0.5,
"custom_friction": 0.9, "custom_friction": 0.9,
"custom_mass": 1 "custom_mass": 1
} })
arcade.set_background_color(arcade.color.WHITE)
self.space = pymunk.Space() self.space = pymunk.Space()
@@ -101,18 +90,11 @@ class Game(arcade.gui.UIView):
self.custom_friction = self.settings["physics_playground"].get("custom_friction", 0.9) self.custom_friction = self.settings["physics_playground"].get("custom_friction", 0.9)
self.custom_mass = self.settings["physics_playground"].get("custom_mass", 1) self.custom_mass = self.settings["physics_playground"].get("custom_mass", 1)
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.info_box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=3, align="left"), anchor_x="left", anchor_y="top") self.info_box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=3, align="left"), anchor_x="left", anchor_y="top")
self.fps_label = self.info_box.add(arcade.gui.UILabel(text="FPS: 60", text_color=arcade.color.BLACK)) self.fps_label = self.info_box.add(arcade.gui.UILabel(text="FPS: 60", text_color=arcade.color.BLACK))
self.object_count_label = self.info_box.add(arcade.gui.UILabel(text="Object count: 0", text_color=arcade.color.BLACK)) self.object_count_label = self.info_box.add(arcade.gui.UILabel(text="Object count: 0", text_color=arcade.color.BLACK))
self.processing_time_label = self.info_box.add(arcade.gui.UILabel(text="Processing time: 0 ms", text_color=arcade.color.BLACK)) self.processing_time_label = self.info_box.add(arcade.gui.UILabel(text="Processing time: 0 ms", text_color=arcade.color.BLACK))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_title_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
self.settings_box.add(arcade.gui.UISpace(size_hint=(0, 0.025)))
self.add_setting("Crate Elasticity: {value}", 0, 3, 0.1, "crate_elasticity", "elasticity", PhysicsCrate) self.add_setting("Crate Elasticity: {value}", 0, 3, 0.1, "crate_elasticity", "elasticity", PhysicsCrate)
self.add_setting("Coin Elasticity: {value}", 0, 3, 0.1, "coin_elasticity", "elasticity", PhysicsCoin) self.add_setting("Coin Elasticity: {value}", 0, 3, 0.1, "coin_elasticity", "elasticity", PhysicsCoin)
self.add_setting("Custom Elasticity: {value}", 0, 3, 0.1, "custom_elasticity", "elasticity", CustomPhysics) self.add_setting("Custom Elasticity: {value}", 0, 3, 0.1, "custom_elasticity", "elasticity", CustomPhysics)
@@ -137,10 +119,6 @@ class Game(arcade.gui.UIView):
self.add_custom_body_button.on_click = lambda event: self.custom_body_ui() self.add_custom_body_button.on_click = lambda event: self.custom_body_ui()
def save_data(self):
with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
def change_iterations(self, label, value): def change_iterations(self, label, value):
self.iterations = int(value) self.iterations = int(value)
self.space.iterations = self.iterations self.space.iterations = self.iterations
@@ -155,7 +133,7 @@ class Game(arcade.gui.UIView):
self.space.gravity = pymunk.Vec2d(self.gravity_x, self.gravity_y) self.space.gravity = pymunk.Vec2d(self.gravity_x, self.gravity_y)
label.text = f"Gravity {gravity_type.capitalize()}: {value}" label.text = f"Gravity {gravity_type.capitalize()}: {value}"
def add_setting(self, text, min_value, max_value, step, local_variable, pymunk_variable=None, instance=None, on_change=None): def add_setting(self, text, min_value, max_value, step, local_variable, pymunk_variable=None, instance=None, on_change=None): # overwrite since very different
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=getattr(self, local_variable)))) label = self.settings_box.add(arcade.gui.UILabel(text.format(value=getattr(self, local_variable))))
slider = self.settings_box.add(arcade.gui.UISlider(value=getattr(self, local_variable), min_value=min_value, max_value=max_value, step=step, size_hint=(1, 0.05))) slider = self.settings_box.add(arcade.gui.UISlider(value=getattr(self, local_variable), min_value=min_value, max_value=max_value, step=step, size_hint=(1, 0.05)))
slider._render_steps = lambda surface: None slider._render_steps = lambda surface: None
@@ -167,7 +145,7 @@ class Game(arcade.gui.UIView):
else: else:
slider.on_change = lambda event, label=label: self.change_value(label, text, local_variable, event.new_value) slider.on_change = lambda event, label=label: self.change_value(label, text, local_variable, event.new_value)
def change_value(self, label, text, local_variable, value, pymunk_variable=None, instance=None): def change_value(self, label, text, local_variable, value, pymunk_variable=None, instance=None): # overwrite since very different
label.text = text.format(value=value) label.text = text.format(value=value)
setattr(self, local_variable, value) setattr(self, local_variable, value)
@@ -431,10 +409,11 @@ class Game(arcade.gui.UIView):
self.processing_time_label.text = f"Processing time: {round((current_time - start) * 1000, 2)} ms" self.processing_time_label.text = f"Processing time: {round((current_time - start) * 1000, 2)} ms"
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: if symbol == arcade.key.ESCAPE:
arcade.set_background_color(menu_background_color) arcade.set_background_color(menu_background_color)
self.save_data() with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
from menus.main import Main from menus.main import Main
self.window.show_view(Main(self.pypresence_client)) self.window.show_view(Main(self.pypresence_client))
@@ -449,7 +428,6 @@ class Game(arcade.gui.UIView):
self.space.remove(shape) self.space.remove(shape)
self.space.remove(sprite.pymunk_obj.body) self.space.remove(sprite.pymunk_obj.body)
self.spritelist.clear() self.spritelist.clear()
def on_show_view(self): def on_show_view(self):

View File

@@ -1,35 +1,20 @@
import arcade, arcade.gui, json, os, math import arcade, arcade.gui, json, os, math
from game.base import BaseGame
from utils.constants import button_style from utils.constants import button_style
from utils.preload import button_texture, button_hovered_texture from utils.preload import button_texture, button_hovered_texture
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Spirograph Simulator", "spirograph_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Spirograph Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "spirograph_simulator" in self.settings:
self.settings["spirograph_simulator"] = {
"big_radius": 220, "big_radius": 220,
"small_radius": 65, "small_radius": 65,
"pen_distance": 100, "pen_distance": 100,
"step_size": 0.01, "step_size": 0.01,
"trail_size": 2000, "trail_size": 2000,
"mode": "inside" "mode": "inside"
} })
self.center_points = [[self.window.width * 0.4, self.window.height / 2, 0, []]] self.center_points = [[self.window.width * 0.4, self.window.height / 2, 0, []]]
@@ -38,8 +23,6 @@ class Game(arcade.gui.UIView):
def on_show_view(self): def on_show_view(self):
super().on_show_view() super().on_show_view()
self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
self.add_setting("Big Radius: {value}", 10, 500, 10, "big_radius") self.add_setting("Big Radius: {value}", 10, 500, 10, "big_radius")
self.add_setting("Small Radius: {value}", 5, 140, 5, "small_radius") self.add_setting("Small Radius: {value}", 5, 140, 5, "small_radius")
self.add_setting("Pen Distance: {value}", 0, 250, 10, "pen_distance") self.add_setting("Pen Distance: {value}", 0, 250, 10, "pen_distance")
@@ -63,18 +46,6 @@ class Game(arcade.gui.UIView):
self.mode_button.text = f"Change to {mode} mode" self.mode_button.text = f"Change to {mode} mode"
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["spirograph_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["spirograph_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value)
self.settings["spirograph_simulator"][settings_key] = value
def on_draw(self): def on_draw(self):
super().on_draw() super().on_draw()
@@ -123,14 +94,9 @@ class Game(arcade.gui.UIView):
self.center_points[n][3].pop(0) self.center_points[n][3].pop(0)
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: super().on_key_press(symbol, modifiers)
with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4))
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
elif symbol == arcade.key.C: if symbol == arcade.key.C:
self.center_points = [[self.window.width * 0.4, self.window.height / 2, 0, []]] self.center_points = [[self.window.width * 0.4, self.window.height / 2, 0, []]]
elif symbol == arcade.key.SPACE: elif symbol == arcade.key.SPACE:

View File

@@ -1,34 +1,17 @@
import pyglet, arcade, arcade.gui, os, json, numpy as np import pyglet, arcade, arcade.gui, os, json, numpy as np
from game.voronoi_diagram_simulator.shader import create_shader from game.voronoi_diagram_simulator.shader import create_shader
from game.base import BaseGame
from utils.constants import button_style from utils.constants import button_style
from utils.preload import button_texture, button_hovered_texture from utils.preload import button_texture, button_hovered_texture
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Voronoi Diagram Simulator", "voronoi_diagram_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Voronoi Diagram Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "voronoi_diagram_simulator" in self.settings:
self.settings["voronoi_diagram_simulator"] = {
"edge_thickness": 0.01, "edge_thickness": 0.01,
"edge_smoothness": 0.005 "edge_smoothness": 0.005
} })
self.points = np.empty((0, 2), dtype=np.float32) self.points = np.empty((0, 2), dtype=np.float32)
@@ -43,8 +26,6 @@ class Game(arcade.gui.UIView):
def on_show_view(self): def on_show_view(self):
super().on_show_view() super().on_show_view()
self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
self.add_setting("Edge Thickness: {value}", 0, 0.1, 0.01, "edge_thickness") self.add_setting("Edge Thickness: {value}", 0, 0.1, 0.01, "edge_thickness")
self.add_setting("Edge Smoothness: {value}", 0, 0.1, 0.01, "edge_smoothness") self.add_setting("Edge Smoothness: {value}", 0, 0.1, 0.01, "edge_smoothness")
@@ -58,17 +39,8 @@ class Game(arcade.gui.UIView):
self.needs_redraw = True self.needs_redraw = True
def add_setting(self, text, min_value, max_value, step, settings_key):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=self.settings["voronoi_diagram_simulator"][settings_key])))
slider = self.settings_box.add(arcade.gui.UISlider(value=self.settings["voronoi_diagram_simulator"][settings_key], min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, label=label: self.change_value(label, text, settings_key, event.new_value)
def change_value(self, label, text, settings_key, value): def change_value(self, label, text, settings_key, value):
label.text = text.format(value=value) super().change_value(label, text, settings_key, value)
self.settings["voronoi_diagram_simulator"][settings_key] = value
self.needs_redraw = True self.needs_redraw = True
@@ -102,7 +74,7 @@ class Game(arcade.gui.UIView):
self.needs_redraw = True self.needs_redraw = True
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: if symbol == arcade.key.ESCAPE: # overwrite is needed since shader program needs to be deleted
self.shader_program.delete() self.shader_program.delete()
with open("data.json", "w") as file: with open("data.json", "w") as file:

View File

@@ -1,34 +1,19 @@
import arcade, arcade.gui, pyglet.gl, array, random, os, json import arcade, arcade.gui, pyglet.gl, array, random, os, json
from utils.constants import WATER_ROWS, WATER_COLS from utils.constants import WATER_ROWS, WATER_COLS
from game.water_simulator.shader import create_shader from game.water_simulator.shader import create_shader
from game.base import BaseGame
class Game(arcade.gui.UIView): class Game(BaseGame):
def __init__(self, pypresence_client): def __init__(self, pypresence_client):
super().__init__() super().__init__(pypresence_client, "Water Simulator", "water_simulator", {
self.pypresence_client = pypresence_client
self.pypresence_client.update(state="Playing a simulator", details="Water Simulator")
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
self.settings_box = self.anchor.add(arcade.gui.UIBoxLayout(align="center", size_hint=(0.2, 1)).with_background(color=arcade.color.GRAY), anchor_x="right", anchor_y="bottom")
self.settings_label = self.settings_box.add(arcade.gui.UILabel(text="Settings", font_size=24))
if os.path.exists("data.json"):
with open("data.json", "r") as file:
self.settings = json.load(file)
else:
self.settings = {}
if not "water_simulator" in self.settings:
self.settings["water_simulator"] = {
"splash_strength": 0.1, "splash_strength": 0.1,
"splash_radius": 3, "splash_radius": 3,
"wave_speed": 1, "wave_speed": 1,
"damping": 0.02 "damping": 0.02
} })
self.splash_row = 0 self.splash_row = 0
self.splash_col = 0 self.splash_col = 0
self.current_splash_strength = 0 self.current_splash_strength = 0
@@ -42,8 +27,6 @@ class Game(arcade.gui.UIView):
def on_show_view(self): def on_show_view(self):
super().on_show_view() super().on_show_view()
self.settings_box.add(arcade.gui.UISpace(height=self.window.height / 75))
self.add_setting("Splash Strength: {value}", 0.1, 2.0, 0.1, "splash_strength") self.add_setting("Splash Strength: {value}", 0.1, 2.0, 0.1, "splash_strength")
self.add_setting("Splash Radius: {value}", 0.5, 10, 0.5, "splash_radius") self.add_setting("Splash Radius: {value}", 0.5, 10, 0.5, "splash_radius")
@@ -90,35 +73,17 @@ class Game(arcade.gui.UIView):
self.previous_heights_ssbo.set_data(grid.tobytes()) self.previous_heights_ssbo.set_data(grid.tobytes())
self.current_heights_ssbo.set_data(grid.tobytes()) self.current_heights_ssbo.set_data(grid.tobytes())
def add_setting(self, text, min_value, max_value, step, local_variable, on_change=None):
label = self.settings_box.add(arcade.gui.UILabel(text.format(value=getattr(self, local_variable))))
slider = self.settings_box.add(arcade.gui.UISlider(value=getattr(self, local_variable), min_value=min_value, max_value=max_value, step=step))
slider._render_steps = lambda surface: None
if on_change:
slider.on_change = lambda event, label=label: on_change(label, event.new_value)
else:
slider.on_change = lambda event, label=label: self.change_value(label, text, local_variable, event.new_value)
def change_value(self, label, text, local_variable, value):
label.text = text.format(value=value)
self.settings["water_simulator"][local_variable] = value
def main_exit(self):
self.shader_program.delete()
self.previous_heights_ssbo.delete()
self.current_heights_ssbo.delete()
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
def on_key_press(self, symbol, modifiers): def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE: if symbol == arcade.key.ESCAPE: # overwrite to remove shader program and SSBOs
self.shader_program.delete()
self.previous_heights_ssbo.delete()
self.current_heights_ssbo.delete()
with open("data.json", "w") as file: with open("data.json", "w") as file:
file.write(json.dumps(self.settings, indent=4)) file.write(json.dumps(self.settings, indent=4))
self.main_exit() from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
def on_mouse_press(self, x, y, button, modifiers): def on_mouse_press(self, x, y, button, modifiers):
col = int(x / (self.window.width * 0.8) * WATER_COLS) col = int(x / (self.window.width * 0.8) * WATER_COLS)

View File

@@ -82,6 +82,9 @@ class Main(arcade.gui.UIView):
self.double_pendulum_simulator_button = self.box.add(arcade.gui.UITextureButton(text="Double Pendulum Simulator", texture=button_texture, texture_hovered=button_hovered_texture, width=self.window.width / 2, height=self.window.height / 16, style=big_button_style)) self.double_pendulum_simulator_button = self.box.add(arcade.gui.UITextureButton(text="Double Pendulum Simulator", texture=button_texture, texture_hovered=button_hovered_texture, width=self.window.width / 2, height=self.window.height / 16, style=big_button_style))
self.double_pendulum_simulator_button.on_click = lambda event: self.double_pendulum_simulator() self.double_pendulum_simulator_button.on_click = lambda event: self.double_pendulum_simulator()
self.delaunay_simulator_button = self.box.add(arcade.gui.UITextureButton(text="Delaunay Simulator", texture=button_texture, texture_hovered=button_hovered_texture, width=self.window.width / 2, height=self.window.height / 16, style=big_button_style))
self.delaunay_simulator_button.on_click = lambda event: self.delaunay_simulator()
self.settings_button = self.box.add(arcade.gui.UITextureButton(text="Settings", texture=button_texture, texture_hovered=button_hovered_texture, width=self.window.width / 2, height=self.window.height / 16, style=big_button_style)) self.settings_button = self.box.add(arcade.gui.UITextureButton(text="Settings", texture=button_texture, texture_hovered=button_hovered_texture, width=self.window.width / 2, height=self.window.height / 16, style=big_button_style))
self.settings_button.on_click = lambda event: self.settings() self.settings_button.on_click = lambda event: self.settings()
@@ -125,6 +128,10 @@ class Main(arcade.gui.UIView):
from game.double_pendulum_simulator.game import Game from game.double_pendulum_simulator.game import Game
self.window.show_view(Game(self.pypresence_client)) self.window.show_view(Game(self.pypresence_client))
def delaunay_simulator(self):
from game.delaunay_simulator.game import Game
self.window.show_view(Game(self.pypresence_client))
def settings(self): def settings(self):
from menus.settings import Settings from menus.settings import Settings
self.window.show_view(Settings(self.pypresence_client)) self.window.show_view(Settings(self.pypresence_client))