From 3a7e40d8336aa606f27b1cd5d9e22f4eef51c0fc Mon Sep 17 00:00:00 2001 From: csd4ni3l Date: Sun, 7 Dec 2025 22:43:07 +0100 Subject: [PATCH] fix some file manager stuff, add sprite adding, convert values to float before using them, add TexturedRectangles so custom sprites work, remove morphing, fix DO blocks and some others not having vars, make blocks bigger, fix trash can not working most of the time, add more key inputs --- game/file_manager.py | 20 ++++---- game/play.py | 108 ++++++++++++++++++++++++++++++++----------- game/rules.py | 37 ++++++++++----- game/sprites.py | 23 ++++++--- utils/constants.py | 38 ++++++--------- 5 files changed, 146 insertions(+), 80 deletions(-) diff --git a/game/file_manager.py b/game/file_manager.py index dc60282..f6b3b3f 100644 --- a/game/file_manager.py +++ b/game/file_manager.py @@ -6,10 +6,11 @@ from utils.preload import button_texture, button_hovered_texture from arcade.gui.experimental.scroll_area import UIScrollArea, UIScrollBar class FileManager(arcade.gui.UIAnchorLayout): - def __init__(self, width, allowed_extensions): - super().__init__(size_hint=(0.95, 0.875), vertical=False) + def __init__(self, width, height, size_hint, allowed_extensions): + super().__init__(size_hint=size_hint, vertical=False) self.filemanager_width = width + self.filemanager_height = height self.current_directory = os.path.expanduser("~") self.allowed_extensions = allowed_extensions @@ -36,9 +37,9 @@ class FileManager(arcade.gui.UIAnchorLayout): self.bottom_box = self.add(arcade.gui.UIBoxLayout(space_between=5), anchor_x="center", anchor_y="bottom", align_y=5) self.filename_label = self.bottom_box.add(arcade.gui.UILabel(text="Filename:", font_name="Roboto", font_size=17)) - self.filename_input = self.bottom_box.add(arcade.gui.UIInputText(width=self.filemanager_width * 0.35, height=self.filemanager_width * 0.02).with_border(color=arcade.color.WHITE)) + self.filename_input = self.bottom_box.add(arcade.gui.UIInputText(width=self.filemanager_width * 0.35, height=self.filemanager_height * 0.05).with_border(color=arcade.color.WHITE)) - self.submit_button = self.bottom_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="Submit", style=button_style, width=self.filemanager_width * 0.5, height=self.filemanager_width * 0.025)) + self.submit_button = self.bottom_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="Submit", style=button_style, width=self.filemanager_width * 0.5, height=self.filemanager_height * 0.05)) self.submit_button.on_click = lambda event: self.submit(self.current_directory) self.submit_button.visible = False @@ -55,9 +56,7 @@ class FileManager(arcade.gui.UIAnchorLayout): def submit(self, content): self.submitted_content = content if self.mode == "import" else f"{content}/{self.filename_input.text}" - - self.disable() - + def get_content(self, directory): if not directory in self.content_cache or time.perf_counter() - self.content_cache[directory][-1] >= 30: try: @@ -109,19 +108,16 @@ class FileManager(arcade.gui.UIAnchorLayout): self.current_directory_label.text = self.current_directory - self.file_buttons.append(self.files_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="Go up", style=button_style, width=self.filemanager_width / 1.5))) + self.file_buttons.append(self.files_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text="Go up", style=button_style, width=self.filemanager_width / 1.5, height=self.filemanager_height * 0.05,))) self.file_buttons[-1].on_click = lambda event, directory=self.current_directory: self.change_directory(os.path.dirname(directory)) for file in self.get_content(self.current_directory): - self.file_buttons.append(self.files_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=file, style=button_style, width=self.filemanager_width / 1.5))) + self.file_buttons.append(self.files_box.add(arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text=file, style=button_style, width=self.filemanager_width / 1.5, height=self.filemanager_height * 0.05,))) if os.path.isdir(f"{self.current_directory}/{file}"): self.file_buttons[-1].on_click = lambda event, directory=f"{self.current_directory}/{file}": self.change_directory(directory) else: self.file_buttons[-1].on_click = lambda event, file=f"{self.current_directory}/{file}": self.submit(file) - def disable(self): - self.parent.parent.disable() # The FileManager UIManager. self.parent is the FileManager UIAnchorLayout - def change_directory(self, directory): if directory.startswith("//"): # Fix / paths directory = directory[1:] diff --git a/game/play.py b/game/play.py index b977314..d0f648f 100644 --- a/game/play.py +++ b/game/play.py @@ -3,10 +3,10 @@ import arcade, arcade.gui, pyglet, random, json from dataclasses import asdict from utils.preload import SPRITE_TEXTURES, button_texture, button_hovered_texture -from utils.constants import button_style, DO_RULES, IF_RULES, SHAPES, ALLOWED_INPUT +from utils.constants import button_style, DO_RULES, IF_RULES, SPRITES, ALLOWED_INPUT from game.rules import RuleUI, Block, VarBlock -from game.sprites import BaseShape, Rectangle, Circle, Triangle +from game.sprites import BaseShape, Rectangle, Circle, Triangle, TexturedRectangle from game.file_manager import FileManager class Game(arcade.gui.UIView): @@ -23,7 +23,7 @@ class Game(arcade.gui.UIView): self.rules_box = RuleUI(self.window) - self.file_manager = FileManager(self.window.width * 0.95, [".json"]).with_border() + self.file_manager = FileManager(self.window.width * 0.95, self.window.height * 0.875, (0.95, 0.875), [".json"]).with_border() self.ui_selector_box = self.anchor.add(arcade.gui.UIBoxLayout(vertical=False, space_between=self.window.width / 100), anchor_x="left", anchor_y="bottom", align_y=5, align_x=self.window.width / 100) self.add_ui_selector("Simulation", lambda event: self.simulation()) @@ -39,8 +39,18 @@ class Game(arcade.gui.UIView): self.rulesets = self.rules_box.rulesets - self.sprites_box = arcade.gui.UIAnchorLayout(size_hint=(0.95, 0.9)) - self.sprite_types = SHAPES + self.sprite_add_filemanager = FileManager(self.window.width * 0.9, self.window.height * 0.75, (0.9, 0.75), [".png", ".jpg", ".jpeg", ".bmp", ".gif"]) + self.sprite_add_ui = arcade.gui.UIBoxLayout(size_hint=(0.95, 0.9), space_between=10) + self.sprite_add_ui.add(arcade.gui.UILabel(text="Add Sprite", font_size=24, text_color=arcade.color.WHITE)) + + self.sprite_add_ui.add(arcade.gui.UILabel(text="Sprite Name:", font_size=18, text_color=arcade.color.WHITE)) + self.sprite_name_input = self.sprite_add_ui.add(arcade.gui.UIInputText(width=self.window.width * 0.4, height=self.window.height * 0.05).with_border(color=arcade.color.WHITE)) + + self.sprite_add_ui.add(arcade.gui.UILabel(text="Select a texture for the sprite:", font_size=18, text_color=arcade.color.WHITE)) + self.sprite_add_ui.add(self.sprite_add_filemanager, anchor_x="center", anchor_y="bottom", align_y=25) + + self.sprites_ui = arcade.gui.UIAnchorLayout(size_hint=(0.95, 0.9)) + self.sprite_types = SPRITES self.shapes = [] self.shape_batch = pyglet.graphics.Batch() @@ -52,6 +62,7 @@ class Game(arcade.gui.UIView): button.on_click = on_click def move_x(self, a, shape): + a = float(a) if isinstance(shape, Triangle): shape.x += a shape.x2 += a @@ -60,6 +71,7 @@ class Game(arcade.gui.UIView): shape.x += a def move_y(self, a, shape): + a = float(a) if isinstance(shape, Triangle): shape.y += a shape.y2 += a @@ -68,6 +80,7 @@ class Game(arcade.gui.UIView): shape.y += a def change_x(self, a, shape): + a = float(a) if isinstance(shape, Triangle): offset_x2 = shape.x2 - shape.x offset_x3 = shape.x3 - shape.x @@ -79,6 +92,7 @@ class Game(arcade.gui.UIView): shape.x = a def change_y(self, a, shape): + a = float(a) if isinstance(shape, Triangle): offset_y2 = shape.y2 - shape.y offset_y3 = shape.y3 - shape.y @@ -90,18 +104,22 @@ class Game(arcade.gui.UIView): shape.y = a def change_x_velocity(self, a, shape): + a = float(a) shape.x_velocity = a self.triggered_events.append(["x_velocity_change", {"event_shape_type": shape.shape_type, "shape_size": shape.shape_size, "shape_x": shape.x, "shape_y": shape.y, "shape": shape, "shape_color": shape.shape_color}]) def change_y_velocity(self, a, shape): + a = float(a) shape.y_velocity = a self.triggered_events.append(["y_velocity_change", {"event_shape_type": shape.shape_type, "shape_size": shape.shape_size, "shape_x": shape.x, "shape_y": shape.y, "shape": shape, "shape_color": shape.shape_color}]) def change_x_gravity(self, a): + a = float(a) self.x_gravity = a self.triggered_events.append(["x_gravity_change", {}]) def change_y_gravity(self, a): + a = float(a) self.y_gravity = a self.triggered_events.append(["y_gravity_change", {}]) @@ -116,6 +134,7 @@ class Game(arcade.gui.UIView): shape.delete() def change_size(self, a, shape): + a = float(a) if isinstance(shape, Circle): shape.radius = a elif isinstance(shape, Rectangle): @@ -146,38 +165,56 @@ class Game(arcade.gui.UIView): elif shape_type == "triangle": self.shapes.append(Triangle(x, y, x + 10, y, x + 5, y + 10, color=arcade.color.WHITE, batch=self.shape_batch)) + + else: + self.shapes.append(TexturedRectangle(shape_type, img=SPRITE_TEXTURES.get(shape_type, SPRITE_TEXTURES["rectangle"]), x=x, y=y, batch=self.shape_batch)) shape = self.shapes[-1] self.triggered_events.append(["spawn", {"event_shape_type": shape.shape_type, "shape_size": shape.shape_size, "shape_x": shape.x, "shape_y": shape.y, "shape": shape, "shape_color": shape.shape_color}]) - def morph(self, a, shape): - old_shape_x, old_shape_y, old_shape_size, old_shape_color = shape.x, shape.y, shape.shape_size, shape.shape_color - self.destroy(shape) + def add_sprite(self): + self.disable_previous() - if a == "circle": - self.shapes.append(Circle(old_shape_x, old_shape_y, old_shape_size, color=getattr(arcade.color, old_shape_color), batch=self.shape_batch)) + self.mode = "sprite_add" - elif a == "rectangle": - self.shapes.append(Rectangle(old_shape_x, old_shape_y, width=old_shape_size, height=old_shape_size, color=getattr(arcade.color, old_shape_color), batch=self.shape_batch)) - - elif a == "triangle": - self.shapes.append(Triangle(old_shape_x, old_shape_y, old_shape_x + old_shape_size, old_shape_y, old_shape_x + int(old_shape_size / 2), old_shape_y + old_shape_size, color=getattr(arcade.color, old_shape_color), batch=self.shape_batch)) + self.anchor.add(self.sprite_add_ui, anchor_x="center", anchor_y="center") + + def check_selection(delta_time): + if self.sprite_add_filemanager.submitted_content: + texture = arcade.load_texture(self.sprite_add_filemanager.submitted_content) + + SPRITE_TEXTURES[self.sprite_name_input.text] = texture + SPRITES[self.sprite_name_input.text] = self.sprite_add_filemanager.submitted_content + + self.sprites_grid.clear() + + for n, shape in enumerate(SPRITES): + row, col = n % 8, n // 8 + box = self.sprites_grid.add(arcade.gui.UIBoxLayout(), row=row, column=col) + box.add(arcade.gui.UILabel(text=shape, font_size=16, text_color=arcade.color.WHITE)) + box.add(arcade.gui.UIImage(texture=SPRITE_TEXTURES[shape], width=self.window.width / 15, height=self.window.width / 15)) + + self.anchor.remove(self.sprite_add_ui) + arcade.unschedule(check_selection) + + arcade.schedule(check_selection, 0.1) def on_show_view(self): super().on_show_view() - self.sprites_box.add(arcade.gui.UILabel(text="Sprites", font_size=24, text_color=arcade.color.WHITE), anchor_x="center", anchor_y="top") + self.sprites_ui.add(arcade.gui.UILabel(text="Sprites", font_size=24, text_color=arcade.color.WHITE), anchor_x="center", anchor_y="top") - self.sprites_grid = self.sprites_box.add(arcade.gui.UIGridLayout(columns=8, row_count=8, align="left", vertical_spacing=10, horizontal_spacing=10, size_hint=(0.95, 0.85)), anchor_x="center", anchor_y="center").with_border() + self.sprites_grid = self.sprites_ui.add(arcade.gui.UIGridLayout(columns=8, row_count=8, align="left", vertical_spacing=10, horizontal_spacing=10, size_hint=(0.95, 0.85), width=self.window.width * 0.95, height=self.window.height * 0.85), anchor_x="center", anchor_y="center") - for n, shape in enumerate(SHAPES): + for n, shape in enumerate(SPRITES): row, col = n % 8, n // 8 box = self.sprites_grid.add(arcade.gui.UIBoxLayout(), row=row, column=col) box.add(arcade.gui.UILabel(text=shape, font_size=16, text_color=arcade.color.WHITE)) box.add(arcade.gui.UIImage(texture=SPRITE_TEXTURES[shape], width=self.window.width / 15, height=self.window.width / 15)) - self.sprites_box.add(arcade.gui.UITextureButton(text="Add Sprite", width=self.window.width / 2, height=self.window.height / 10, texture=button_texture, texture_hovered=button_hovered_texture, style=button_style)) + add_sprite_button = self.sprites_ui.add(arcade.gui.UITextureButton(text="Add Sprite", width=self.window.width / 2, height=self.window.height / 10, texture=button_texture, texture_hovered=button_hovered_texture, style=button_style), anchor_x="center", anchor_y="bottom", align_y=10) + add_sprite_button.on_click = lambda event: self.add_sprite() self.triggered_events.append(["start", {}]) @@ -205,8 +242,7 @@ class Game(arcade.gui.UIView): "change_y_velocity": self.change_y_velocity, "change_color": self.change_color, "change_size": self.change_size, - "destroy": self.destroy, - "morph": self.morph + "destroy": self.destroy } } @@ -254,17 +290,23 @@ class Game(arcade.gui.UIView): data = json.load(file) self.triggered_events = [] + self.rulesets = {} if not data: self.add_widget(arcade.gui.UIMessageBox(message_text="Invalid file. Could not import rules.", width=self.window.width * 0.5, height=self.window.height * 0.25)) return - for rule_num, ruleset in data.items(): + for rule_num, ruleset in data["rulesets"].items(): kwargs = ruleset kwargs["children"] = [Block(**child) for child in ruleset["children"]] kwargs["vars"] = [VarBlock(**var) for var in ruleset["vars"]] block = Block(**kwargs) self.rulesets[rule_num] = block + + self.sprite_types = data.get("sprites", SPRITES) + for sprite_name, sprite_path in self.sprite_types.items(): + if not sprite_name in SPRITE_TEXTURES: + SPRITE_TEXTURES[sprite_name] = arcade.load_texture(sprite_path) self.rules_box.rulesets = self.rulesets self.rules_box.current_rule_num = self.get_max_rule_num() + 1 @@ -272,9 +314,19 @@ class Game(arcade.gui.UIView): self.rules() - if self.mode == "export" and self.file_manager.submitted_content: + if self.mode == "export" and self.file_manager.submitted_content: with open(self.file_manager.submitted_content, "w") as file: - file.write(json.dumps({rule_num: asdict(block) for rule_num, block in self.rulesets.items()}, indent=4)) + file.write(json.dumps( + { + "rules": { + rule_num: asdict(block) for rule_num, block in self.rulesets.items() + }, + "sprites": self.sprite_types + + }, + indent=4)) + + self.add_widget(arcade.gui.UIMessageBox(message_text="Rules and Sprites exported successfully!", width=self.window.width * 0.5, height=self.window.height * 0.25)) if not self.mode == "simulation": return @@ -307,7 +359,7 @@ class Game(arcade.gui.UIView): def on_key_press(self, symbol, modifiers): if symbol == arcade.key.ESCAPE: self.main_exit() - elif self.mode == "simulation" and symbol in [ord(key) for key in ALLOWED_INPUT]: + elif self.mode == "simulation" and symbol in [ord(key) if len(key) == 1 else getattr(arcade.key, key.upper()) for key in ALLOWED_INPUT]: self.triggered_events.append(["on_input", {"event_key": chr(symbol)}]) def on_mouse_press(self, x, y, button, modifiers): @@ -339,7 +391,9 @@ class Game(arcade.gui.UIView): elif self.mode == "rules": self.anchor.remove(self.rules_box) elif self.mode == "sprites": - self.anchor.remove(self.sprites_box) + self.anchor.remove(self.sprites_ui) + elif self.mode == "sprite_add": + self.anchor.remove(self.sprite_add_ui) self.anchor.trigger_full_render() @@ -371,7 +425,7 @@ class Game(arcade.gui.UIView): self.mode = "sprites" - self.anchor.add(self.sprites_box, anchor_x="center", anchor_y="top") + self.anchor.add(self.sprites_ui, anchor_x="center", anchor_y="top") def simulation(self): self.disable_previous() diff --git a/game/rules.py b/game/rules.py index a4164f8..2b2bd23 100644 --- a/game/rules.py +++ b/game/rules.py @@ -124,10 +124,10 @@ class BlockRenderer: def _build_block_with_vars(self, b: Block, x: int, y: int) -> None: lx, ly = x, y - 42 - current_x = lx + 10 + current_x = lx + 14 current_y = ly + 28 - pattern = r' ([a-z]) ' + pattern = r'(?:^| )([a-z])(?= |$)' parts = re.split(pattern, b.label) var_index = 0 @@ -145,19 +145,19 @@ class BlockRenderer: self.text_objects.append(text_obj) self.text_by_rule_num[b.rule_num].append(text_obj) - current_x += len(part) * 10 + current_x += len(part) * 12 else: if var_index < len(b.vars): var = b.vars[var_index] var_width, var_height = self._build_var_ui( var, current_x, current_y, b.rule_num ) - current_x += var_width + 7 + current_x += var_width + 10 var_index += 1 def _build_block(self, b: Block, x: int, y: int) -> int: is_wrap = b.rule_type != "do" - h, w = 42, 280 + h, w = 42, 380 if b.rule_type == "if": color = IF_COLOR @@ -467,7 +467,7 @@ class RuleUI(arcade.gui.UIAnchorLayout): if block == self.dragged_rule_ui or (self.dragged_rule_ui.rule in NEEDS_SHAPE and block.rule not in PROVIDES_SHAPE): continue - if arcade.LBWH(block.x, block.y - 44, 280, 44).intersection(arcade.LBWH(self.dragged_rule_ui.x, self.dragged_rule_ui.y - 44, 280, 44)): + if arcade.LBWH(block.x, block.y - 44, 380, 44).intersection(arcade.LBWH(self.dragged_rule_ui.x, self.dragged_rule_ui.y - 44, 380, 44)): block.children.append(self.dragged_rule_ui) del self.rulesets[self.dragged_rule_ui.rule_num] self.block_renderer.refresh() @@ -491,7 +491,7 @@ class RuleUI(arcade.gui.UIAnchorLayout): continue projected_vec = self.camera.unproject((event.x, event.y)) - if arcade.LBWH(block.x, block.y - 44, 280, 44).point_in_rect((projected_vec.x, projected_vec.y)): + if arcade.LBWH(block.x, block.y - 44, 380, 44).point_in_rect((projected_vec.x, projected_vec.y)): if block not in list(self.rulesets.values()): # its children self.remove_from_parent(block, list(self.rulesets.values())) self.block_renderer.refresh() @@ -526,9 +526,22 @@ class RuleUI(arcade.gui.UIAnchorLayout): elif isinstance(event, arcade.gui.UIMouseReleaseEvent): if self.dragged_rule_ui: - block_vec = self.camera.unproject((self.dragged_rule_ui.x, self.dragged_rule_ui.y)) - if self.trash_sprite.rect.intersection(arcade.LBWH(block_vec.x, block_vec.y, 280, 44)) and not self.trash_sprite._current_keyframe_index == self.trash_sprite.animation.num_frames - 1: - del self.rulesets[self.dragged_rule_ui.rule_num] + block_screen_pos = self.camera.project((self.dragged_rule_ui.x, self.dragged_rule_ui.y)) + + block_rect = arcade.LBWH(block_screen_pos[0], block_screen_pos[1], 380, 44) + trash_rect = arcade.LBWH( + self.trash_sprite.center_x - self.trash_sprite.width / 2, + self.trash_sprite.center_y - self.trash_sprite.height / 2, + self.trash_sprite.width, + self.trash_sprite.height + ) + + if block_rect.intersection(trash_rect): + self.remove_from_parent(self.dragged_rule_ui, list(self.rulesets.values())) + + if self.dragged_rule_ui.rule_num in self.rulesets: + del self.rulesets[self.dragged_rule_ui.rule_num] + self.dragged_rule_ui = None self.block_renderer.refresh() return @@ -556,8 +569,8 @@ class RuleUI(arcade.gui.UIAnchorLayout): def on_update(self, dt): if self.dragged_rule_ui: - block_vec = self.camera.unproject((self.dragged_rule_ui.x, self.dragged_rule_ui.y)) - if self.trash_sprite.rect.intersection(arcade.LBWH(block_vec.x, block_vec.y, 280, 44)) and not self.trash_sprite._current_keyframe_index == self.trash_sprite.animation.num_frames - 1: + block_screen_pos = self.camera.project((self.dragged_rule_ui.x, self.dragged_rule_ui.y)) + if self.trash_sprite.rect.intersection(arcade.LBWH(block_screen_pos[0], block_screen_pos[1], 380, 44)) and not self.trash_sprite._current_keyframe_index == self.trash_sprite.animation.num_frames - 1: self.trash_sprite.update_animation() else: self.trash_sprite.time = 0 diff --git a/game/sprites.py b/game/sprites.py index b41ed3c..a8a4faa 100644 --- a/game/sprites.py +++ b/game/sprites.py @@ -106,12 +106,11 @@ class Circle(pyglet.shapes.Circle, BaseShape): return not (has_neg and has_pos) -class Rectangle(pyglet.shapes.Rectangle, BaseShape): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - BaseShape.__init__(self) - self.shape_type = "rectangle" - + +class BaseRectangle(BaseShape): + def __init__(self): + super().__init__() + @property def shape_size(self): return self.width @@ -181,6 +180,18 @@ class Rectangle(pyglet.shapes.Rectangle, BaseShape): return (ccw(x1, y1, x3, y3, x4, y4) != ccw(x2, y2, x3, y3, x4, y4) and ccw(x1, y1, x2, y2, x3, y3) != ccw(x1, y1, x2, y2, x4, y4)) +class Rectangle(pyglet.shapes.Rectangle, BaseRectangle): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + BaseRectangle.__init__(self) + self.shape_type = "rectangle" + +class TexturedRectangle(pyglet.sprite.Sprite, BaseRectangle): + def __init__(self, shape_type, *args, **kwargs): + super().__init__(*args, **kwargs) + BaseRectangle.__init__(self) + self.shape_type = shape_type + class Triangle(pyglet.shapes.Triangle, BaseShape): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/utils/constants.py b/utils/constants.py index 52f5561..130b1fe 100644 --- a/utils/constants.py +++ b/utils/constants.py @@ -1,12 +1,21 @@ +import os import arcade.color, operator from arcade.types import Color from arcade.gui.widgets.buttons import UITextureButtonStyle, UIFlatButtonStyle from arcade.gui.widgets.slider import UISliderStyle -SHAPES = ["rectangle", "circle", "triangle"] +# Get the directory where this module is located +_module_dir = os.path.dirname(os.path.abspath(__file__)) +_assets_dir = os.path.join(os.path.dirname(_module_dir), 'assets') + +SPRITES = { + os.path.splitext(file_name)[0]: os.path.join(_assets_dir, 'graphics', 'sprites', file_name) + for file_name in os.listdir(os.path.join(_assets_dir, 'graphics', 'sprites')) + } + VAR_NAMES = ["a", "b", "c", "d", "e", "f", "g"] -ALLOWED_INPUT = ["a", "b", "c", "d", "e", "q", "w", "s", "t"] +ALLOWED_INPUT = ["a", "b", "c", "d", "e", "q", "w", "s", "t", "space", "left", "right", "up", "down"] TRIGGER_COLOR = (255, 204, 102) DO_COLOR = (102, 178, 255) @@ -39,8 +48,8 @@ OPS = { } VAR_DEFAULT = { - "shape_type": SHAPES[0], - "target_type": SHAPES[1], + "shape_type": "rectangle", + "target_type": "circle", "variable": 0, "color": "WHITE", "size": 10, @@ -49,8 +58,8 @@ VAR_DEFAULT = { } VAR_OPTIONS = { - "shape_type": SHAPES, - "target_type": SHAPES, + "shape_type": SPRITES, + "target_type": SPRITES, "variable": (-700, 700), "color": COLORS, "size": (1, 200), @@ -118,13 +127,6 @@ TRIGGER_RULES = { "vars": ["shape_type", "event_shape_type"], "func": lambda *v: v[0] == v[1] }, - "morphs": { - "key": "morphs", - "description": "IF {a} shape morphs into {b}", - "user_vars": ["shape_type", "target_type"], - "vars": ["shape_type", "target_type", "event_a_type", "event_b_type"], - "func": lambda *v: (v[0] == v[2]) and (v[3] == v[1]) - }, "collides": { "key": "collides", "description": "IF {a} shape collides with {b}", @@ -289,14 +291,6 @@ DO_RULES = { "vars": ["shape"] }, - "morph_into": { - "key": "morph_into", - "description": "Morph this into {a}", - "action": {"type": "shape_action", "name": "morph"}, - "user_vars": ["shape_type"], - "vars": ["shape", "shape_type"] - }, - "change_x_gravity": { "key": "change_x_gravity", "description": "Change X gravity to {a}", @@ -327,7 +321,6 @@ PROVIDES_SHAPE = [ "spawns", "color_changes", "size_changes", - "morphs", "collides", # IFs, technically, these need and provide a shape to the next rule @@ -362,7 +355,6 @@ NEEDS_SHAPE = [ "change_y_velocity", "change_size", "destroy", - "morph_into" ] RULE_DEFAULTS = {