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

This commit is contained in:
csd4ni3l
2025-12-07 22:43:07 +01:00
parent b74115b489
commit 3a7e40d833
5 changed files with 146 additions and 80 deletions

View File

@@ -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:]

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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 = {