Add sprites sidebar, x and y gravity instead of gravity, fix a bunch of bugs, so now rules work, add input, mouse move and mouse click events, fix color changes, fix very slow loading times, go from is rules to greater, less and between rules

This commit is contained in:
csd4ni3l
2025-11-23 22:40:17 +01:00
parent daa13e5814
commit d5de17f8e0
9 changed files with 420 additions and 199 deletions

View File

@@ -1,2 +1,4 @@
Chaos Protocol is a simulation game where you have a rule engine and objects, which you can apply rules to! By default, the game launches with random rules.
Basically a framework of sorts, which can even be random!
The project is a huge WIP! You can't do much yet, but you have basic rules and simulation.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 B

View File

@@ -1,11 +1,12 @@
import arcade, arcade.gui, pyglet, random
from utils.constants import slider_style, dropdown_style, VAR_NAMES, VAR_DEFAULT, DEFAULT_GRAVITY, VAR_OPTIONS, DO_RULES, IF_RULES
from utils.preload import SPRITE_TEXTURES
from utils.constants import slider_style, dropdown_style, VAR_NAMES, VAR_DEFAULT, DEFAULT_X_GRAVITY, DEFAULT_Y_GRAVITY, VAR_OPTIONS, DO_RULES, IF_RULES, SHAPES, ALLOWED_INPUT
from arcade.gui.experimental.scroll_area import UIScrollArea, UIScrollBar
from game.rules import generate_rule
from game.sprites import *
from game.sprites import BaseShape, Rectangle, Circle, Triangle
class Game(arcade.gui.UIView):
def __init__(self, pypresence_client):
@@ -18,16 +19,19 @@ class Game(arcade.gui.UIView):
self.scroll_area = UIScrollArea(size_hint=(0.25, 1)) # center on screen
self.scroll_area.scroll_speed = -75
self.anchor.add(self.scroll_area, anchor_x="right", anchor_y="center", align_x=-self.window.width * 0.02)
self.anchor.add(self.scroll_area, anchor_x="right", anchor_y="bottom", align_x=-self.window.width * 0.02)
self.scrollbar = UIScrollBar(self.scroll_area)
self.scrollbar.size_hint = (0.02, 1)
self.anchor.add(self.scrollbar, anchor_x="right", anchor_y="center")
self.rules_box = arcade.gui.UIBoxLayout(align="left", size_hint=(0.25, 1)).with_background(color=arcade.color.DARK_GRAY)
self.rules_box = arcade.gui.UIBoxLayout(align="center", size_hint=(0.25, 1)).with_background(color=arcade.color.DARK_GRAY)
self.scroll_area.add(self.rules_box)
self.gravity = DEFAULT_GRAVITY
self.sprites_box = self.anchor.add(arcade.gui.UIBoxLayout(size_hint=(0.15, 1), align="center", space_between=10).with_background(color=arcade.color.DARK_GRAY), anchor_x="left", anchor_y="bottom")
self.x_gravity = DEFAULT_X_GRAVITY
self.y_gravity = DEFAULT_Y_GRAVITY
self.current_ruleset_num = 0
self.rulesets = {}
@@ -40,39 +44,119 @@ class Game(arcade.gui.UIView):
self.shapes = []
self.shape_batch = pyglet.graphics.Batch()
def move_x(self, shape, a):
def move_x(self, a, shape):
if isinstance(shape, Triangle):
shape.x += a
shape.x2 += a
shape.x3 += a
else:
shape.x += a
def move_y(self, shape, a):
def move_y(self, a, shape):
if isinstance(shape, Triangle):
shape.y += a
shape.y2 += a
shape.y3 += a
else:
shape.y += a
def change_x(self, shape, a):
def change_x(self, a, shape):
if isinstance(shape, Triangle):
offset_x2 = shape.x2 - shape.x
offset_x3 = shape.x3 - shape.x
shape.x = a
shape.x2 = a + offset_x2
shape.x3 = a + offset_x3
else:
shape.x = a
def change_y(self, shape, a):
def change_y(self, a, shape):
if isinstance(shape, Triangle):
offset_y2 = shape.y2 - shape.y
offset_y3 = shape.y3 - shape.y
shape.y = a
shape.y2 = a + offset_y2
shape.y3 = a + offset_y3
else:
shape.y = a
def change_x_velocity(self, shape, a):
def change_x_velocity(self, a, shape):
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.color}])
def change_y_velocity(self, shape, a):
def change_y_velocity(self, a, shape):
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.color}])
def change_gravity(self, a):
self.gravity = a
def change_x_gravity(self, a):
self.x_gravity = a
self.triggered_events.append(["x_gravity_change", {}])
def spawn(self, shape):
x, y = random.randint(100, self.window.width - 100), random.randint(100, self.window.height - 100)
def change_y_gravity(self, a):
self.y_gravity = a
self.triggered_events.append(["y_gravity_change", {}])
if shape == "circle":
def change_color(self, a, shape):
shape.color = getattr(arcade.color, a)
self.triggered_events.append(["color_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.color}])
def destroy(self, shape: BaseShape):
self.triggered_events.append(["destroyed", {"event_shape_type": shape.shape_type}])
if shape in self.shapes:
self.shapes.remove(shape)
shape.delete()
def change_size(self, a, shape):
if isinstance(shape, Circle):
shape.radius = a
elif isinstance(shape, Rectangle):
shape.width = a
shape.height = a
elif isinstance(shape, Triangle):
size = a - shape.shape_size
shape.x += size
shape.y += size
shape.x2 += size
shape.y2 += size
shape.x3 += size
shape.y3 += size
self.triggered_events.append(["size_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.color}])
def spawn(self, shape_type):
x, y = random.randint(self.window.width * 0.15 + 50, self.window.width * 0.75 - 50), random.randint(100, self.window.height - 100)
if shape_type == "circle":
self.shapes.append(Circle(x, y, 10, color=arcade.color.WHITE, batch=self.shape_batch))
elif shape == "rectangle":
elif shape_type == "rectangle":
self.shapes.append(Rectangle(x, y, width=10, height=10, color=arcade.color.WHITE, batch=self.shape_batch))
elif shape == "triangle":
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))
shape = self.shapes[-1]
self.triggered_events.append(["spawns", {"event_shape_type": shape.shape_type, "shape_size": shape.shape_size, "shape_x": shape.x, "shape_y": shape.y, "shape": shape, "shape_color": 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)
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))
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))
def create_rule_ui(self, rule_box: arcade.gui.UIBoxLayout, rule, rule_type, rule_num=1):
rule_dict = IF_RULES[rule] if rule_type == "if" else DO_RULES[rule]
@@ -81,7 +165,7 @@ class Game(arcade.gui.UIView):
default_values = {VAR_NAMES[n]: VAR_DEFAULT[variable] for n, variable in enumerate(rule_dict["user_vars"])}
description = rule_dict["description"].format_map(default_values)
desc_label = rule_box.add(arcade.gui.UILabel(description if rule_type == "if" else f"THEN {description}", font_size=13, width=self.window.width * 0.25))
desc_label = rule_box.add(arcade.gui.UILabel(description, font_size=13, width=self.window.width * 0.225))
self.rule_labels[f"{self.current_ruleset_num}_{rule_num}_desc"] = desc_label
for n, variable_type in enumerate(rule_dict["user_vars"]):
@@ -89,16 +173,17 @@ class Game(arcade.gui.UIView):
self.rule_values[key] = default_values[VAR_NAMES[n]]
label = rule_box.add(arcade.gui.UILabel(f'{VAR_NAMES[n]}: {default_values[VAR_NAMES[n]]}', font_size=11, width=self.window.width * 0.25, height=self.window.height / 25))
label = rule_box.add(arcade.gui.UILabel(f'{VAR_NAMES[n]}: {default_values[VAR_NAMES[n]]}', font_size=11, width=self.window.width * 0.225, height=self.window.height / 25))
self.rule_labels[key] = label
if variable_type in ["variable", "size"]:
slider = rule_box.add(arcade.gui.UISlider(value=default_values[VAR_NAMES[n]], min_value=VAR_OPTIONS[variable_type][0], max_value=VAR_OPTIONS[variable_type][1], step=1, style=slider_style, width=self.window.width * 0.25, height=self.window.height / 25))
slider = rule_box.add(arcade.gui.UISlider(value=default_values[VAR_NAMES[n]], min_value=VAR_OPTIONS[variable_type][0], max_value=VAR_OPTIONS[variable_type][1], step=1, style=slider_style, width=self.window.width * 0.225, height=self.window.height / 25))
slider._render_steps = lambda surface: None
slider.on_change = lambda event, variable_type=variable_type, rule=rule, rule_type=rule_type, ruleset_num=ruleset_num, rule_num=rule_num, n=n: self.change_rule_value(ruleset_num, rule_num, rule, rule_type, variable_type, n, event.new_value)
self.rule_var_changers[key] = slider
elif variable_type in ["shape_type", "target_type", "color"]:
dropdown = rule_box.add(arcade.gui.UIDropdown(default=default_values[VAR_NAMES[n]], options=VAR_OPTIONS[variable_type], active_style=dropdown_style, primary_style=dropdown_style, dropdown_style=dropdown_style, width=self.window.width * 0.25, height=self.window.height / 25))
dropdown = rule_box.add(arcade.gui.UIDropdown(default=default_values[VAR_NAMES[n]], options=VAR_OPTIONS[variable_type], active_style=dropdown_style, primary_style=dropdown_style, dropdown_style=dropdown_style, width=self.window.width * 0.225, height=self.window.height / 25))
dropdown.on_change = lambda event, variable_type=variable_type, rule=rule, rule_type=rule_type, ruleset_num=ruleset_num, rule_num=rule_num, n=n: self.change_rule_value(ruleset_num, rule_num, rule, rule_type, variable_type, n, event.new_value)
self.rule_var_changers[key] = dropdown
@@ -109,7 +194,7 @@ class Game(arcade.gui.UIView):
self.rulesets[self.current_ruleset_num] = ruleset
self.create_rule_ui(rule_box, ruleset[0], "if")
self.create_rule_ui(rule_box, ruleset[1], "do")
self.create_rule_ui(rule_box, ruleset[1], "do", 2)
else:
self.rulesets[self.current_ruleset_num] = ruleset
@@ -124,25 +209,35 @@ class Game(arcade.gui.UIView):
def on_show_view(self):
super().on_show_view()
add_rule_button = self.rules_box.add(arcade.gui.UIFlatButton(text="Add rule", width=self.window.width * 0.25, height=self.window.height / 15, style=dropdown_style))
self.rules_box.add(arcade.gui.UILabel(text="Rules", font_size=24, text_color=arcade.color.BLACK))
self.rules_box.add(arcade.gui.UISpace(height=self.window.height / 50, width=self.window.width * 0.25)) # have to add a width of 0.25 so it doesnt resize to 0.225
add_rule_button = self.rules_box.add(arcade.gui.UIFlatButton(text="Add rule", width=self.window.width * 0.225, height=self.window.height / 15, style=dropdown_style))
add_rule_button.on_click = lambda event: self.add_rule()
self.rules_box.add(arcade.gui.UISpace(height=self.window.height / 50))
for _ in range(8):
self.add_rule()
self.add_rule(["on_left_click", "spawn"])
self.add_rule(["size_greater", "morph_into"])
self.sprites_box.add(arcade.gui.UILabel(text="Sprites", font_size=24, text_color=arcade.color.BLACK))
self.sprites_box.add(arcade.gui.UISpace(height=self.window.height / 50))
for shape in SHAPES:
self.sprites_box.add(arcade.gui.UILabel(text=shape, font_size=16))
self.sprites_box.add(arcade.gui.UIImage(texture=SPRITE_TEXTURES[shape], width=self.window.width / 15, height=self.window.width / 15))
self.triggered_events.append(["game_launch", {}])
def add_rule(self):
self.rulesets[self.current_ruleset_num] = generate_rule()
def add_rule(self, force=None):
self.rulesets[self.current_ruleset_num] = generate_rule() if not force else force
self.add_ruleset(self.rulesets[self.current_ruleset_num])
self.current_ruleset_num += 1
def get_rule_values(self, ruleset_num, rule_num, rule_dict, event_args):
args = [self.rule_values[f"{ruleset_num}_{rule_num}_{user_var}_{n}"] for n, user_var in enumerate(rule_dict["user_vars"])]
return args + [event_args[var] for var in rule_dict.get("vars", []) if var in rule_dict["user_vars"]]
return args + [event_args[var] for var in rule_dict.get("vars", []) if not var in rule_dict["user_vars"]]
def check_rule(self, ruleset_num, rule_num, rule_dict, event_args):
return rule_dict["func"](*self.get_rule_values(ruleset_num, rule_num, rule_dict, event_args))
@@ -151,7 +246,8 @@ class Game(arcade.gui.UIView):
ACTION_FUNCTION_DICT = {
"global_action": {
"spawn": self.spawn,
"change_gravity": self.change_gravity
"change_x_gravity": self.change_x_gravity,
"change_y_gravity": self.change_y_gravity
},
"shape_action": {
"move_x": self.move_x,
@@ -159,7 +255,11 @@ class Game(arcade.gui.UIView):
"change_x": self.change_x,
"change_y": self.change_y,
"change_x_velocity": self.change_x_velocity,
"change_y_velocity": self.change_y_velocity
"change_y_velocity": self.change_y_velocity,
"change_color": self.change_color,
"change_size": self.change_size,
"destroy": self.destroy,
"morph": self.morph
}
}
@@ -173,7 +273,6 @@ class Game(arcade.gui.UIView):
while len(self.triggered_events) > 0:
trigger, trigger_args = self.triggered_events.pop(0)
for key, ruleset in self.rulesets.items():
if len(ruleset) == 2:
if_rule_dict = IF_RULES[ruleset[0]]
@@ -182,19 +281,18 @@ class Game(arcade.gui.UIView):
if not if_rule_dict["trigger"] == trigger:
continue
if if_rule_dict["trigger"] in ["every_update"]:
if do_rule_dict["action"]["type"] == "shape_action":
for shape in self.shapes:
event_args = trigger_args
event_args = trigger_args.copy()
if not "event_shape_type" in trigger_args:
event_args.update({"event_shape_type": shape.shape_type, "shape_size": shape.size})
event_args.update({"event_shape_type": shape.shape_type, "shape_size": shape.shape_size, "shape_x": shape.x, "shape_y": shape.y, "shape": shape, "shape_color": shape.color})
if self.check_rule(key, 0, if_rule_dict, event_args):
self.run_do_rule(key, 1, do_rule_dict, event_args)
if self.check_rule(key, 1, if_rule_dict, event_args):
self.run_do_rule(key, 2, do_rule_dict, event_args)
else:
event_args = trigger_args
if self.check_rule(key, 0, if_rule_dict, event_args):
self.run_do_rule(key, 1, do_rule_dict, event_args)
event_args = trigger_args.copy()
if self.check_rule(key, 1, if_rule_dict, event_args):
self.run_do_rule(key, 2, do_rule_dict, event_args)
else:
if_rule_dicts = IF_RULES[ruleset[0]], IF_RULES[ruleset[2]]
@@ -203,21 +301,35 @@ class Game(arcade.gui.UIView):
if not (if_rule_dicts[0]["trigger"] == trigger and if_rule_dicts[0]["trigger"] == trigger):
continue
for shape in self.shapes if not "event_shape_type" in trigger_args else [shape]:
if do_rule_dict["action"]["type"] == "shape_action":
for shape in self.shapes:
event_args = trigger_args
if not "event_shape_type" in trigger_args:
event_args.update({"event_shape_type": shape.shape_type, "shape_size": shape.size})
event_args.update({"event_shape_type": shape.shape_type, "shape_size": shape.shape_size, "shape_x": shape.x, "shape_y": shape.y, "shape": shape, "shape_color": shape.color})
if ruleset[1] == "and":
if self.check_rule(key, 0, if_rule_dicts[0], event_args) and self.check_rule(key, 2, if_rule_dicts[1], event_args):
if self.check_rule(key, 1, if_rule_dicts[0], event_args) and self.check_rule(key, 2, if_rule_dicts[1], event_args):
self.run_do_rule(key, 3, do_rule_dict, event_args)
elif ruleset[1] == "or":
if self.check_rule(key, 0, if_rule_dicts[0], event_args) or self.check_rule(key, 2, if_rule_dicts[1], event_args):
if self.check_rule(key, 1, if_rule_dicts[0], event_args) or self.check_rule(key, 2, if_rule_dicts[1], event_args):
self.run_do_rule(key, 3, do_rule_dict, event_args)
else:
event_args = trigger_args
if ruleset[1] == "and":
if self.check_rule(key, 1, if_rule_dicts[0], event_args) and self.check_rule(key, 2, if_rule_dicts[1], event_args):
self.run_do_rule(key, 3, do_rule_dict, event_args)
elif ruleset[1] == "or":
if self.check_rule(key, 1, if_rule_dicts[0], event_args) or self.check_rule(key, 2, if_rule_dicts[1], event_args):
self.run_do_rule(key, 3, do_rule_dict, event_args)
for shape in self.shapes:
shape.update(self.gravity)
shape.update(self.x_gravity, self.y_gravity)
if shape.x < 0 or shape.x > self.window.width or shape.y < 0 or shape.y > self.window.height:
self.destroy(shape)
def change_rule_value(self, ruleset_num, rule_num, rule, rule_type, variable_type, n, value):
rule_dict = IF_RULES[rule] if rule_type == "if" else DO_RULES[rule]
@@ -232,10 +344,29 @@ class Game(arcade.gui.UIView):
description = rule_dict["description"].format_map(values)
self.rule_labels[f"{ruleset_num}_{rule_num}_desc"].text = description if rule_type == "if" else f"THEN {description}"
self.rule_labels[f"{ruleset_num}_{rule_num}_desc"].text = description
self.rule_labels[key].text = f'{VAR_NAMES[n]}: {value}'
def on_draw(self):
super().on_draw()
def on_key_press(self, symbol, modifiers):
if symbol == arcade.key.ESCAPE:
self.main_exit()
elif symbol in ALLOWED_INPUT:
self.triggered_events.append(["on_input", {"event_key": chr(symbol)}])
def on_mouse_press(self, x, y, button, modifiers):
if button == arcade.MOUSE_BUTTON_LEFT:
self.triggered_events.append(["on_left_click", {}])
elif button == arcade.MOUSE_BUTTON_RIGHT:
self.triggered_events.append(["on_right_click", {}])
def on_mouse_move(self, x, y, button, modifiers):
self.triggered_events.append(["on_mouse_move", {}])
def main_exit(self):
from menus.main import Main
self.window.show_view(Main(self.pypresence_client))
def on_draw(self):
self.window.clear()
self.shape_batch.draw()
self.ui.draw()

View File

@@ -1,4 +1,4 @@
import pyglet
import pyglet, arcade.color
from utils.constants import DEFAULT_X_VELOCITY, DEFAULT_Y_VELOCITY
@@ -7,11 +7,22 @@ class BaseShape():
self.shape_type = ""
self.x_velocity = DEFAULT_X_VELOCITY
self.y_velocity = DEFAULT_Y_VELOCITY
self._shape_color = "WHITE"
def update(self, gravity):
def update(self, x_gravity, y_gravity):
self.x += self.x_velocity
self.y += self.y_velocity
self.y -= gravity
self.x -= x_gravity
self.y -= y_gravity
@property
def shape_color(self):
return self._shape_color
@shape_color.setter
def shape_color(self, color):
self._shape_color = color
self.color = getattr(arcade.color, color)
class Circle(pyglet.shapes.Circle, BaseShape):
def __init__(self, *args, **kwargs):
@@ -41,4 +52,4 @@ class Triangle(pyglet.shapes.Triangle, BaseShape):
@property
def shape_size(self):
return self.x2 - self.x
return max(self.x, self.x2, self.x3) - min(self.x, self.x2, self.x3)

View File

@@ -7,11 +7,27 @@ LOGICAL_OPERATORS = ["and", "or"]
SHAPES = ["rectangle", "circle", "triangle"]
VAR_NAMES = ["a", "b", "c", "d", "e", "f", "g"]
DEFAULT_GRAVITY = 2
DEFAULT_X_GRAVITY = 0
DEFAULT_Y_GRAVITY = 2
DEFAULT_X_VELOCITY = 0
DEFAULT_Y_VELOCITY = 0
COLORS = [key for key, value in arcade.color.__dict__.items() if isinstance(value, Color)]
ALLOWED_INPUT = [ord(key) for key in ["a", "b", "c", "d", "e", "q", "w", "s", "t"]]
COLORS = [
"BLACK", "WHITE", "GRAY", "DARK_GRAY", "CYAN",
"AMBER", "AQUA", "GREEN", "LIGHT_GREEN",
"RED", "LIGHT_RED", "DARK_RED",
"BLUE", "LIGHT_BLUE", "DARK_BLUE",
"YELLOW", "LIGHT_YELLOW", "DARK_YELLOW",
"MAGENTA", "PURPLE", "VIOLET", "INDIGO",
"ORANGE", "BROWN",
"GOLD", "SILVER", "BRONZE",
"TEAL", "AZURE",
"PINK", "HOT_PINK",
"MINT_GREEN", "CHARTREUSE"
]
VAR_DEFAULT = {
"shape_type": SHAPES[0],
@@ -19,49 +35,94 @@ VAR_DEFAULT = {
"variable": 0,
"color": "WHITE",
"size": 10,
"key_input": ALLOWED_INPUT[0]
}
VAR_OPTIONS = {
"shape_type": SHAPES,
"target_type": SHAPES,
"variable": (0, 2500),
"variable": (-700, 700),
"color": COLORS,
"size": (1, 200),
"key_input": ALLOWED_INPUT
}
IF_RULES = {
"x_position": {
"key": "x_position",
"description": "IF X for {a} shape is {b}",
"x_position_greater": {
"key": "x_position_greater",
"description": "IF X for {a} shape is greater than {b}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable"],
"vars": ["shape_type", "variable", "event_shape_type", "shape_x"],
"func": lambda *v: (v[0] == v[2]) and (v[3] == v[1])
"func": lambda *v: (v[0] == v[2]) and (v[3] > v[1])
},
"y_position": {
"key": "y_position",
"description": "IF Y for {a} shape is {b}",
"x_position_less": {
"key": "x_position_less",
"description": "IF X for {a} shape is less than {b}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable"],
"vars": ["shape_type", "variable", "event_shape_type", "shape_x"],
"func": lambda *v: (v[0] == v[2]) and (v[3] < v[1])
},
"x_position_between": {
"key": "x_position_between",
"description": "IF X for {a} shape is between {b} and {c}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable", "variable"],
"vars": ["shape_type", "variable", "variable", "event_shape_type", "shape_x"],
"func": lambda *v: (v[0] == v[3]) and (min(v[1], v[2]) <= v[4] <= max(v[1], v[2]))
},
"y_position_greater": {
"key": "y_position_greater",
"description": "IF Y for {a} shape is greater than {b}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable"],
"vars": ["shape_type", "variable", "event_shape_type", "shape_y"],
"func": lambda *v: (v[0] == v[2]) and (v[3] == v[1])
"func": lambda *v: (v[0] == v[2]) and (v[3] > v[1])
},
"color_is": {
"key": "color_is",
"description": "IF {a} shape color is {b}",
"y_position_less": {
"key": "y_position_less",
"description": "IF Y for {a} shape is less than {b}",
"trigger": "every_update",
"user_vars": ["shape_type", "color"],
"vars": ["shape_type", "color", "event_shape_type", "shape_color"],
"func": lambda *v: (v[0] == v[2]) and (v[3] == v[1])
"user_vars": ["shape_type", "variable"],
"vars": ["shape_type", "variable", "event_shape_type", "shape_y"],
"func": lambda *v: (v[0] == v[2]) and (v[3] < v[1])
},
"size_is": {
"key": "size_is",
"description": "IF {a} shape size is {b}",
"y_position_between": {
"key": "y_position_between",
"description": "IF Y for {a} shape is between {b} and {c}",
"trigger": "every_update",
"user_vars": ["shape_type", "size"],
"vars": ["shape_type", "size", "event_shape_type", "shape_size"],
"func": lambda *v: (v[0] == v[2]) and (v[3] == v[1])
"user_vars": ["shape_type", "variable", "variable"],
"vars": ["shape_type", "variable", "variable", "event_shape_type", "shape_y"],
"func": lambda *v: (v[0] == v[3]) and (min(v[1], v[2]) <= v[4] <= max(v[1], v[2]))
},
"size_greater": {
"key": "size_greater",
"description": "IF {a} shape size is greater than {b}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable"],
"vars": ["shape_type", "variable", "event_shape_type", "shape_size"],
"func": lambda *v: (v[0] == v[2]) and (v[3] > v[1])
},
"size_less": {
"key": "size_less",
"description": "IF {a} shape size is less than {b}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable"],
"vars": ["shape_type", "variable", "event_shape_type", "shape_size"],
"func": lambda *v: (v[0] == v[2]) and (v[3] < v[1])
},
"size_between": {
"key": "size_between",
"description": "IF {a} shape size is between {b} and {c}",
"trigger": "every_update",
"user_vars": ["shape_type", "variable", "variable"],
"vars": ["shape_type", "variable", "variable", "event_shape_type", "shape_size"],
"func": lambda *v: (v[0] == v[3]) and (min(v[1], v[2]) <= v[4] <= max(v[1], v[2]))
},
"spawns": {
"key": "spawns",
"description": "IF {a} shape spawns",
@@ -81,7 +142,7 @@ IF_RULES = {
"x_velocity_changes": {
"key": "x_velocity_changes",
"description": "IF {a} shape X velocity changes",
"trigger": "x_change",
"trigger": "x_velocity_change",
"user_vars": ["shape_type"],
"vars": ["shape_type", "event_shape_type"],
"func": lambda *v: v[0] == v[1]
@@ -89,7 +150,7 @@ IF_RULES = {
"y_velocity_changes": {
"key": "y_velocity_changes",
"description": "IF {a} shape Y velocity changes",
"trigger": "y_change",
"trigger": "y_velocity_change",
"user_vars": ["shape_type"],
"vars": ["shape_type", "event_shape_type"],
"func": lambda *v: v[0] == v[1]
@@ -110,14 +171,6 @@ IF_RULES = {
"vars": ["shape_type", "event_shape_type"],
"func": lambda *v: v[0] == v[1]
},
"gravity_changes": {
"key": "gravity_changes",
"description": "IF gravity changes",
"user_vars": [],
"trigger": "gravity_change",
"vars": [],
"func": lambda *v: True
},
"color_changes": {
"key": "color_changes",
"description": "IF {a} shape color changes",
@@ -150,6 +203,38 @@ IF_RULES = {
"vars": ["shape_type", "target_type", "event_a_type", "event_b_type"],
"func": lambda *v: (v[0] == v[2]) and (v[3] == v[1])
},
"on_left_click": {
"key": "on_left_click",
"description": "IF you left click",
"trigger": "on_left_click",
"user_vars": [],
"vars": [],
"func": lambda *v: True
},
"on_right_click": {
"key": "on_right_click",
"description": "IF you right click",
"trigger": "on_right_click",
"user_vars": [],
"vars": [],
"func": lambda *v: True
},
"on_mouse_move": {
"key": "on_mouse_move",
"description": "IF mouse moves",
"trigger": "on_mouse_move",
"user_vars": [],
"vars": [],
"func": lambda *v: True
},
"on_input": {
"key": "on_input",
"description": "IF {a} key is pressed",
"trigger": "on_input",
"user_vars": ["key_input"],
"vars": ["key_input", "event_key"],
"func": lambda *v: v[0] == v[1]
},
"game_launch": {
"key": "game_launch",
"description": "IF game launches",
@@ -176,7 +261,6 @@ NON_COMPATIBLE_WHEN = [
("spawns", "y_velocity_changes"),
("spawns", "x_gravity_changes"),
("spawns", "y_gravity_changes"),
("spawns", "gravity_changes"),
("spawns", "color_changes"),
("spawns", "size_changes"),
@@ -186,7 +270,6 @@ NON_COMPATIBLE_WHEN = [
("destroyed", "y_velocity_changes"),
("destroyed", "x_gravity_changes"),
("destroyed", "y_gravity_changes"),
("destroyed", "gravity_changes"),
("destroyed", "color_changes"),
("destroyed", "size_changes"),
@@ -195,19 +278,11 @@ NON_COMPATIBLE_WHEN = [
("morphs", "y_velocity_changes"),
("morphs", "x_gravity_changes"),
("morphs", "y_gravity_changes"),
("morphs", "gravity_changes"),
("morphs", "color_changes"),
("morphs", "size_changes"),
("collides", "destroyed"),
("collides", "morphs"),
("collides", "gravity_changes"),
("x_gravity_changes", "gravity_changes"),
("y_gravity_changes", "gravity_changes"),
("color_changes", "gravity_changes"),
("size_changes", "gravity_changes"),
("every_update", "spawns"),
("every_update", "destroyed"),
@@ -217,22 +292,20 @@ NON_COMPATIBLE_WHEN = [
("every_update", "y_velocity_changes"),
("every_update", "x_gravity_changes"),
("every_update", "y_gravity_changes"),
("every_update", "gravity_changes"),
("every_update", "color_changes"),
("every_update", "size_changes"),
("every_update", "launch"),
("every_update", "game_launch"),
("launch", "spawns"),
("launch", "destroyed"),
("launch", "morphs"),
("launch", "collides"),
("launch", "x_velocity_changes"),
("launch", "y_velocity_changes"),
("launch", "x_gravity_changes"),
("launch", "y_gravity_changes"),
("launch", "gravity_changes"),
("launch", "color_changes"),
("launch", "size_changes"),
("game_launch", "spawns"),
("game_launch", "destroyed"),
("game_launch", "morphs"),
("game_launch", "collides"),
("game_launch", "x_velocity_changes"),
("game_launch", "y_velocity_changes"),
("game_launch", "x_gravity_changes"),
("game_launch", "y_gravity_changes"),
("game_launch", "color_changes"),
("game_launch", "size_changes"),
]
NON_COMPATIBLE_DO_WHEN = [
@@ -242,7 +315,8 @@ NON_COMPATIBLE_DO_WHEN = [
("destroyed", "move_y"),
("destroyed", "change_x_velocity"),
("destroyed", "change_y_velocity"),
("destroyed", "change_gravity"),
("destroyed", "change_x_gravity"),
("destroyed", "change_y_gravity"),
("destroyed", "change_color"),
("destroyed", "change_size"),
("destroyed", "morph_into"),
@@ -250,35 +324,36 @@ NON_COMPATIBLE_DO_WHEN = [
("morphs", "morph_into"),
("gravity_changes", "change_x"),
("gravity_changes", "change_y"),
("gravity_changes", "move_x"),
("gravity_changes", "move_y"),
("gravity_changes", "change_x_velocity"),
("gravity_changes", "change_y_velocity"),
("gravity_changes", "change_gravity"),
("gravity_changes", "change_color"),
("gravity_changes", "change_size"),
("gravity_changes", "morph_into"),
("gravity_changes", "destroy"),
("x_velocity_changes", "change_x_velocity"),
("y_velocity_changes", "change_y_velocity"),
("color_changes", "change_color"),
("size_changes", "change_size"),
("launch", "change_x"),
("launch", "change_y"),
("launch", "move_x"),
("launch", "move_y"),
("launch", "change_x_velocity"),
("launch", "change_y_velocity"),
("launch", "change_gravity"),
("launch", "change_color"),
("launch", "change_size"),
("launch", "destroy"),
("launch", "morph_into")
("every_update", "change_x"),
("every_update", "change_y"),
("every_update", "move_x"),
("every_update", "move_y"),
("every_update", "change_x_velocity"),
("every_update", "change_y_velocity"),
("every_update", "change_color"),
("every_update", "change_size"),
("every_update", "destroy"),
("every_update", "morph_into"),
("game_launch", "change_x"),
("game_launch", "change_y"),
("game_launch", "move_x"),
("game_launch", "move_y"),
("game_launch", "change_x_velocity"),
("game_launch", "change_y_velocity"),
("game_launch", "change_x_gravity"),
("game_launch", "change_y_gravity"),
("game_launch", "change_color"),
("game_launch", "change_size"),
("game_launch", "destroy"),
("game_launch", "morph_into")
]
DO_RULES = {
@@ -286,84 +361,104 @@ DO_RULES = {
"key": "change_x",
"description": "Change this shape's X to {a}",
"action": {"type": "shape_action", "name": "change_x"},
"user_vars": ["shape", "variable"]
"user_vars": ["variable"],
"vars": ["shape", "variable"]
},
"change_y": {
"key": "change_y",
"description": "Change this shape's Y to {a}",
"action": {"type": "shape_action", "name": "change_y"},
"user_vars": ["shape", "variable"]
"user_vars": ["variable"],
"vars": ["shape", "variable"]
},
"move_x": {
"key": "move_x",
"description": "Move this shape's X by {a}",
"action": {"type": "shape_action", "name": "move_x"},
"user_vars": ["shape", "variable"]
"user_vars": ["variable"],
"vars": ["shape", "variable"]
},
"move_y": {
"key": "move_y",
"description": "Move this shape's Y by {a}",
"action": {"type": "shape_action", "name": "move_y"},
"user_vars": ["shape", "variable"]
"user_vars": ["variable"],
"vars": ["shape", "variable"]
},
"change_x_velocity": {
"key": "change_x_velocity",
"description": "Change X velocity of this to {a}",
"action": {"type": "shape_action", "name": "change_x_vel"},
"user_vars": ["shape", "variable"]
"action": {"type": "shape_action", "name": "change_x_velocity"},
"user_vars": ["variable"],
"vars": ["shape", "variable"]
},
"change_y_velocity": {
"key": "change_y_velocity",
"description": "Change Y velocity of this to {a}",
"action": {"type": "shape_action", "name": "change_y_vel"},
"user_vars": ["shape", "variable"]
"action": {"type": "shape_action", "name": "change_y_velocity"},
"user_vars": ["variable"],
"vars": ["shape", "variable"]
},
"change_color": {
"key": "change_color",
"description": "Change this shape's color to {a}",
"action": {"type": "shape_action", "name": "change_color"},
"user_vars": ["shape", "color"]
"user_vars": ["color"],
"vars": ["shape", "color"]
},
"change_size": {
"key": "change_size",
"description": "Change this shape's size to {a}",
"action": {"type": "shape_action", "name": "change_size"},
"user_vars": ["shape", "size"]
"user_vars": ["size"],
"vars": ["shape", "size"]
},
"destroy": {
"key": "destroy",
"description": "Destroy this",
"action": {"type": "shape_action", "name": "destroy"},
"user_vars": ["shape"]
"user_vars": [],
"vars": ["shape"]
},
"morph_into": {
"key": "morph_into",
"description": "Morph this into {a}",
"action": {"type": "shape_action", "name": "morph"},
"user_vars": ["shape", "shape_type"]
"user_vars": ["shape_type"],
"vars": ["shape", "shape_type"]
},
"change_gravity": {
"key": "change_gravity",
"description": "Change gravity to {a}",
"action": {"type": "global_action", "name": "change_gravity"},
"user_vars": ["shape", "variable"]
"change_x_gravity": {
"key": "change_x_gravity",
"description": "Change X gravity to {a}",
"action": {"type": "global_action", "name": "change_x_gravity"},
"user_vars": ["variable"],
"vars": ["variable"]
},
"change_y_gravity": {
"key": "change_y_gravity",
"description": "Change Y gravity to {a}",
"action": {"type": "global_action", "name": "change_y_gravity"},
"user_vars": ["variable"],
"vars": ["variable"]
},
"spawn": {
"key": "spawn",
"description": "Spawn {a}",
"action": {"type": "global_action", "name": "spawn"},
"user_vars": ["shape_type"]
"user_vars": ["shape_type"],
"vars": ["shape_type"]
}
}

View File

@@ -6,3 +6,9 @@ _assets_dir = os.path.join(os.path.dirname(_module_dir), 'assets')
button_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'button.png')))
button_hovered_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'button_hovered.png')))
SPRITE_TEXTURES = {
"circle": arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'sprites', 'circle.png')),
"rectangle": arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'sprites', 'rectangle.png')),
"triangle": arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'sprites', 'triangle.png')),
}

View File

@@ -1,9 +1,7 @@
import logging, arcade, arcade.gui, sys, traceback
import logging, arcade, arcade.gui, sys, traceback, pyglet.display
from utils.constants import menu_background_color
import pyglet.info, pyglet.event
def dump_platform():
import platform
logging.debug(f'Platform: {platform.platform()}')
@@ -16,6 +14,7 @@ def dump_gl(context=None):
info = context.get_info()
else:
from pyglet.gl import gl_info as info
logging.debug(f'gl_info.get_version(): {info.get_version()}')
logging.debug(f'gl_info.get_vendor(): {info.get_vendor()}')
logging.debug(f'gl_info.get_renderer(): {info.get_renderer()}')
@@ -38,29 +37,6 @@ def print_debug_info():
logging.debug('########################## DEBUG INFO ##########################')
logging.debug('')
class ErrorView(arcade.gui.UIView):
def __init__(self, message, title):
super().__init__()
self.message = message
self.title = title
def exit(self):
logging.fatal('Exited with error code 1.')
sys.exit(1)
def on_show_view(self):
super().on_show_view()
self.window.set_caption('Chaos Protocol - Error')
self.window.set_mouse_visible(True)
self.window.set_exclusive_mouse(False)
arcade.set_background_color(menu_background_color)
msgbox = arcade.gui.UIMessageBox(width=self.window.width / 2, height=self.window.height / 2, message_text=self.message, title=self.title)
msgbox.on_action = lambda _: self.exit()
self.add_widget(msgbox)
def on_exception(*exc_info):
logging.error(f"Unhandled exception:\n{''.join(traceback.format_exception(exc_info[1], limit=None))}")