mirror of
https://github.com/csd4ni3l/chaos-protocol.git
synced 2026-01-01 04:23:43 +01:00
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:
@@ -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:]
|
||||
|
||||
108
game/play.py
108
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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user