diff --git a/CREDITS b/CREDITS index 015b4a1..5d0aae0 100644 --- a/CREDITS +++ b/CREDITS @@ -1,4 +1,10 @@ -The Roboto Black font used in this project is licensed under the Open Font License. Read assets/fonts/OFL.txt for more information. +The cursor used for virtual controller support is from the Pixel UI pack +by Kenney Vleugels for Kenney (www.kenney.nl) +with help by Lynn Evers (Twitter: @EversLynn) +Licensed (Creative Commons Zero, CC0) https://creativecommons.org/publicdomain/zero/1.0/ + +The Roboto Black font used in this project is licensed under the Open Font License. +Read assets/fonts/OFL.txt for more information. Huge Thanks to Python for being the programming language used in this game. https://www.python.org/ diff --git a/assets/graphics/cursor.png b/assets/graphics/cursor.png new file mode 100644 index 0000000..2d85afb Binary files /dev/null and b/assets/graphics/cursor.png differ diff --git a/game/iter_fractal_viewer.py b/game/iter_fractal_viewer.py index f0015f9..474295a 100644 --- a/game/iter_fractal_viewer.py +++ b/game/iter_fractal_viewer.py @@ -2,7 +2,7 @@ import arcade, arcade.gui, pyglet, json from game.shader import create_iter_calc_shader from utils.constants import button_style, initial_real_imag -from utils.preload import button_texture, button_hovered_texture +from utils.preload import button_texture, button_hovered_texture, cursor_texture class IterFractalViewer(arcade.gui.UIView): def __init__(self, pypresence_client, fractal_name: str): @@ -20,9 +20,14 @@ class IterFractalViewer(arcade.gui.UIView): self.zoom = 1.0 self.zoom_start_position = () self.zoom_rect = None + self.has_controller = False + self.dragging_with_controller = False def on_show_view(self): super().on_show_view() + self.window.on_stick_motion = self.on_stick_motion + self.window.on_button_press = self.on_button_press + self.window.on_button_release = self.on_button_release self.shader_program, self.fractal_image = create_iter_calc_shader( self.fractal_name, @@ -57,6 +62,29 @@ class IterFractalViewer(arcade.gui.UIView): self.back_button.on_click = lambda event: self.main_exit() self.anchor.add(self.back_button, anchor_x="left", anchor_y="top", align_x=5, align_y=-5) + if self.window.get_controllers(): + self.sprite_list = arcade.SpriteList() + self.cursor_sprite = arcade.Sprite(cursor_texture) + self.sprite_list.append(self.cursor_sprite) + self.has_controller = True + + def on_button_press(self, controller, button_name): + if button_name == "a" and self.has_controller: + self.zoom_start_position = self.cursor_sprite.center_x, self.cursor_sprite.center_y + self.dragging_with_controller = True + + def on_button_release(self, controller, button_name): + if button_name == "a" and self.dragging_with_controller: + self.dragging_with_controller = False + self.on_mouse_release(self.cursor_sprite.center_x, self.cursor_sprite.center_y, None, None) + + def on_stick_motion(self, controller, name, vector): + if name == "leftstick": + self.cursor_sprite.center_x += vector.x * 5 + self.cursor_sprite.center_y += vector.y * 5 + if self.dragging_with_controller: + self.on_mouse_drag(self.cursor_sprite.center_x, self.cursor_sprite.center_y, 0, 0, None, None) + def create_image(self): with self.shader_program: self.shader_program['u_maxIter'] = int(self.max_iter) @@ -71,7 +99,7 @@ class IterFractalViewer(arcade.gui.UIView): self.zoom = 1 - self.zoom_label.text = f"Zoom: {self.zoom:.4f}" + self.zoom_label.text = f"Zoom: {self.zoom:.2f}" self.zoom_start_position = None self.zoom_rect = None @@ -80,7 +108,7 @@ class IterFractalViewer(arcade.gui.UIView): self.pypresence_client.update( state=f'Viewing {self.fractal_name.replace("_", " ").capitalize()}', - details=f'Zoom: {self.zoom:.4f}\nMax Iterations: {self.max_iter}', + details=f'Zoom: {self.zoom:.2f}\nMax Iterations: {self.max_iter}', start=self.pypresence_client.start_time ) @@ -152,5 +180,8 @@ class IterFractalViewer(arcade.gui.UIView): self.fractal_sprite.draw() self.ui.draw() + if self.has_controller: + self.sprite_list.draw() + if self.zoom_rect: arcade.draw_rect_outline(self.zoom_rect, color=arcade.color.GRAY) diff --git a/game/sierpinsky_carpet.py b/game/sierpinsky_carpet.py index 7a6fc27..13377bf 100644 --- a/game/sierpinsky_carpet.py +++ b/game/sierpinsky_carpet.py @@ -2,7 +2,7 @@ import arcade, arcade.gui, pyglet, json from game.shader import create_sierpinsky_carpet_shader from utils.constants import button_style -from utils.preload import button_texture, button_hovered_texture +from utils.preload import button_texture, button_hovered_texture, cursor_texture class SierpinskyCarpetViewer(arcade.gui.UIView): def __init__(self, pypresence_client): @@ -16,6 +16,9 @@ class SierpinskyCarpetViewer(arcade.gui.UIView): self.depth = self.settings_dict.get("sierpinsky_depth", 10) self.zoom = 1.0 self.click_center = (self.width / 2, self.height / 2) + self.has_controller = False + + self.window.on_stick_motion = self.on_stick_motion def on_show_view(self): super().on_show_view() @@ -30,6 +33,17 @@ class SierpinskyCarpetViewer(arcade.gui.UIView): self.setup_ui() + if self.window.get_controllers(): + self.sprite_list = arcade.SpriteList() + self.cursor_sprite = arcade.Sprite(cursor_texture) + self.sprite_list.append(self.cursor_sprite) + self.has_controller = True + + def on_stick_motion(self, controller, name, vector): + if name == "leftstick": + self.cursor_sprite.center_x += vector.x * 5 + self.cursor_sprite.center_y += vector.y * 5 + def main_exit(self): from menus.main import Main self.window.show_view(Main(self.pypresence_client)) @@ -53,8 +67,6 @@ class SierpinskyCarpetViewer(arcade.gui.UIView): self.shader_program.dispatch(self.sierpinsky_carpet_image.width, self.sierpinsky_carpet_image.height, 1, barrier=pyglet.gl.GL_ALL_BARRIER_BITS) def on_mouse_press(self, x: int, y: int, button: int, modifiers: int) -> bool | None: - super().on_mouse_press(x, y, button, modifiers) - if button == arcade.MOUSE_BUTTON_LEFT: zoom = self.settings_dict.get("sierpinsky_zoom_increase", 2) elif button == arcade.MOUSE_BUTTON_RIGHT: @@ -72,7 +84,13 @@ class SierpinskyCarpetViewer(arcade.gui.UIView): self.pypresence_client.update(state='Viewing Sierpinsky Carpet', details=f'Zoom: {self.zoom}\nDepth: {self.depth}', start=self.pypresence_client.start_time) + def on_button_press(self, controller, name): + if name == "a": + self.on_mouse_press(self.cursor_sprite.left, self.cursor_sprite.bottom, arcade.MOUSE_BUTTON_LEFT, 0) + def on_draw(self): self.window.clear() self.sierpinsky_carpet_sprite.draw() self.ui.draw() + if self.has_controller: + self.sprite_list.draw() diff --git a/utils/preload.py b/utils/preload.py index 18b76e3..ebd06b6 100644 --- a/utils/preload.py +++ b/utils/preload.py @@ -2,3 +2,4 @@ import arcade.gui, arcade button_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture("assets/graphics/button.png")) button_hovered_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture("assets/graphics/button_hovered.png")) +cursor_texture = arcade.load_texture("assets/graphics/cursor.png") \ No newline at end of file