Newer
Older
import argparse
import signal
import subprocess

Fabian Heinrich
committed
import sys
from subprocess import Popen
import requests
from minerl.env.test_fake_env import color
from pygame import mixer
from websockets.sync.client import connect
from cooperative_cuisine import ROOT_DIR
from cooperative_cuisine.action import ActionType, InterActionData, Action
from cooperative_cuisine.argument_parser import create_gui_parser
from cooperative_cuisine.environment import Environment
from cooperative_cuisine.game_server import (
CreateEnvironmentConfig,
WebsocketMessage,
PlayerRequestType,
)
from cooperative_cuisine.items import ItemInfo
from cooperative_cuisine.pygame_2d_vis.drawing import Visualizer, CacheFlags
from cooperative_cuisine.pygame_2d_vis.game_colors import colors
from cooperative_cuisine.server_results import PlayerInfo
from cooperative_cuisine.state_representation import StateRepresentation
from cooperative_cuisine.utils import (
setup_logging, load_config_files,
from cooperative_cuisine.pygame_2d_vis.grid import layout_thumbnail
"""Enumeration of "Page" types in the 2D pygame vis."""
Tutorial = "Tutorial"
"""The logger for this module."""
"""Set of keyboard keys for controlling a player.
First four keys are for movement. Order: Down, Up, Left, Right.
5th key is for interacting with counters.
6th key ist for picking up things or dropping them.

Fabian Heinrich
committed
def __init__(
self,
move_keys: list[pygame.key],
interact_key: pygame.key,
pickup_key: pygame.key,
switch_key: pygame.key,

Fabian Heinrich
committed
):
"""Creates a player key set which contains information about which keyboard keys control the player.

Fabian Heinrich
committed
Movement keys in the following order: Down, Up, Left, Right
Args:
move_keys: The keys which control this players movement in the following order: Down, Up, Left, Right.
interact_key: The key to interact with objects in the game.
pickup_key: The key to pick items up or put them down.
switch_key: The key for switching through controllable players.
players: The player indices which this keyset can control.
joystick: number of joystick (later check if available)

Fabian Heinrich
committed
"""

Fabian Heinrich
committed
self.move_vectors: list[list[int]] = [[-1, 0], [1, 0], [0, -1], [0, 1]]
self.key_to_movement: dict[pygame.key, list[int]] = {
key: vec for (key, vec) in zip(move_keys, self.move_vectors)

Fabian Heinrich
committed
self.move_keys: list[pygame.key] = move_keys
self.interact_key: pygame.key = interact_key
self.pickup_key: pygame.key = pickup_key
self.switch_key: pygame.key = switch_key
self.controlled_players: list[str] = players
self.current_player: str = players[0] if players else "0"
self.current_idx = 0
self.other_keyset: list[PlayerKeySet] = []
self.joystick = joystick

Fabian Heinrich
committed
def set_controlled_players(self, controlled_players: list[str]) -> None:
"""Sets the controlled players for this keyset.
Args:
controlled_players: The players controlled by this keyset.
"""

Fabian Heinrich
committed
self.controlled_players = controlled_players
self.current_player = self.controlled_players[0]
self.current_idx = 0

Fabian Heinrich
committed
def next_player(self) -> None:
"""Switches to the next player in the list of controlled players."""
self.current_idx = (self.current_idx + 1) % len(self.controlled_players)
if self.other_keyset:
for ok in self.other_keyset:
if ok.current_idx == self.current_idx:
self.next_player()
return
self.current_player = self.controlled_players[self.current_idx]
def __repr__(self) -> str:
return f"Keyset(current={self.current_player}, players={self.controlled_players}, joy={self.joystick})"
"""Visualisation of the overcooked environment and reading keyboard inputs using pygame."""

Fabian Heinrich
committed
def __init__(
study_host: str,
study_port: int,
game_host: str,
game_port: int,

Fabian Heinrich
committed
USE_AAAMBOS_AGENT: bool,

Fabian Heinrich
committed
debug: bool,
do_study: bool,
use_ssl: bool,

Fabian Heinrich
committed
):

Fabian Heinrich
committed
self.USE_AAAMBOS_AGENT = USE_AAAMBOS_AGENT
self.show_debug_elements = not do_study
self.CONNECT_WITH_STUDY_SERVER = not debug

Fabian Heinrich
committed
pygame.image.load(ROOT_DIR / "pygame_2d_vis" / "images" / "brain_icon.png")

Fabian Heinrich
committed
self.participant_id = uuid.uuid4().hex
self.game_screen: pygame.Surface | None = None
self.running = True
self.key_sets: list[PlayerKeySet] = []
self.websockets = {}
if self.CONNECT_WITH_STUDY_SERVER:
self.request_url = (
f"http{'s' if use_ssl else ''}://{study_host}:{study_port}"
)
self.request_url = f"http{'s' if use_ssl else ''}://{game_host}:{game_port}"
self.manager_id = random.choice(manager_ids)
with open(ROOT_DIR / "pygame_2d_vis" / "visualization.yaml", "r") as file:
self.visualization_config = yaml.safe_load(file)
self.language = self.visualization_config["Gui"]["language"]
# self.fluent_bundle: FluentBundle = create_bundle(
# self.visualization_config["Gui"]["language"],
# ROOT_DIR
# / "pygame_2d_vis"
# / "locales"
# / f"gui_messages_{self.language}.ftl",
# )
self.FPS = self.visualization_config["GameWindow"]["FPS"]
self.min_width = self.visualization_config["GameWindow"]["min_width"]
self.min_height = self.visualization_config["GameWindow"]["min_height"]
self.buttons_width = self.visualization_config["GameWindow"]["buttons_width"]
self.buttons_height = self.visualization_config["GameWindow"]["buttons_height"]

Fabian Heinrich
committed
self.order_bar_height = self.visualization_config["GameWindow"][
"order_bar_height"
]
(
self.window_width_fullscreen,
self.window_height_fullscreen,
) = pygame.display.get_desktop_sizes()[0]
# if (
# self.window_width_fullscreen >= 3840
# and self.window_height_fullscreen >= 2160
# ):
# self.window_width_fullscreen /= 2
# self.window_height_fullscreen /= 2
self.game_width = 0
self.game_height = 0
self.window_width_windowed = self.min_width
self.window_height_windowed = self.min_height
self.kitchen_width = 1
self.kitchen_height = 1
self.kitchen_aspect_ratio = 1
self.images_path = ROOT_DIR / "pygame_gui" / "images"
self.vis = Visualizer(self.visualization_config)

Fabian Heinrich
committed
self.last_score: float = 0
self.switch_score_color: bool = False
self.count_frames_score_label: int = 0
self.fullscreen = False
self.menu_state = MenuStates.Start
self.manager: pygame_gui.UIManager
self.sub_processes = []
self.layout_file_paths_dict = {
p.name: p for p in (ROOT_DIR / "configs" / "layouts").rglob("*.layout")
}
self.layout_file_paths = sorted(list(self.layout_file_paths_dict.keys()))
self.last_state: StateRepresentation
self.player_info = {"0": {"name": "0"}}
self.level_info = {
"name": "Level",
"recipe_graphs": [],
"number_players": -1,
"kitchen_size": (0, 0),
}

Fabian Heinrich
committed
self.beeped_once = False
self.all_completed_meals = []
self.last_completed_meals = []
self.all_recipes_labels = []
self.last_recipes_labels = []
def setup_player_keys(self, players: list[str], number_key_sets=1, disjunct=False):
# First four keys are for movement. Order: Down, Up, Left, Right.
# 5th key is for interacting with counters.
# 6th key ist for picking up things or dropping them.

Fabian Heinrich
committed
if number_key_sets:
key_set1 = PlayerKeySet(
move_keys=[pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s],
interact_key=pygame.K_f,
pickup_key=pygame.K_e,
switch_key=pygame.K_SPACE,
players=players,
)
key_set2 = PlayerKeySet(
move_keys=[pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN],
interact_key=pygame.K_i,
pickup_key=pygame.K_o,
switch_key=pygame.K_p,
players=players,

Fabian Heinrich
committed
)
key_sets = [key_set1, key_set2]
if self.joysticks:
for idx, key in enumerate(self.joysticks.keys()):
if idx >= len(key_sets):
break
key_sets[idx].joystick = key
key_set1.set_controlled_players(players[::2])
key_set2.set_controlled_players(players[1::2])

Fabian Heinrich
committed
elif number_key_sets > 1:
key_set1.set_controlled_players(players)
key_set2.set_controlled_players(players)
key_set1.other_keyset = [key_set2]
key_set2.other_keyset = [key_set1]
key_set2.next_player()

Fabian Heinrich
committed
return key_sets[:number_key_sets]
else:
return []

Fabian Heinrich
committed
def handle_keys(self):
"""Handles keyboard inputs. Sends action for the respective players. When a key is held down, every frame
an action is sent in this function.
"""

Fabian Heinrich
committed

Fabian Heinrich
committed
for key_set in self.key_sets:
current_player_name = str(key_set.current_player)
relevant_keys = [keys[k] for k in key_set.move_keys]
if any(relevant_keys):

Fabian Heinrich
committed
for idx, pressed in enumerate(relevant_keys):
move_vec += key_set.move_vectors[idx]
if np.linalg.norm(move_vec) != 0:
move_vec = move_vec / np.linalg.norm(move_vec)
action = Action(

Fabian Heinrich
committed
current_player_name,
ActionType.MOVEMENT.value,

Fabian Heinrich
committed
move_vec,
self.send_action(action)
def handle_joy_stick_input(self, joysticks: dict[int, pygame.joystick.Joystick]):
"""Handles joystick inputs for movement every frame
Args:
joysticks: list of joysticks
# Axis 0: joy stick left: -1 = left, ~0 = center, 1 = right
# Axis 1: joy stick left: -1 = up, ~0 = center, 1 = down
# see control stuff here (at the end of the page): https://www.pygame.org/docs/ref/joystick.html
current_player_name = str(key_set.current_player)
# if a joystick is connected for current player
if key_set.joystick in joysticks:
# Usually axis run in pairs, up/down for one, and left/right for the other. Triggers count as axes.
# You may want to take into account some tolerance to handle jitter, and
# joystick drift may keep the joystick from centering at 0 or using the full range of position values.
tolerance_threshold = 0.22
# axis 0 = joy stick left --> left & right
axis_left_right = joysticks[key_set.joystick].get_axis(0)
axis_up_down = joysticks[key_set.joystick].get_axis(1)
if np.linalg.norm([axis_left_right, axis_up_down]) > tolerance_threshold:
move_vec = np.array([axis_left_right, axis_up_down])
# if np.linalg.norm(move_vec) != 0:
# move_vec = move_vec / np.linalg.norm(move_vec)
action = Action(
ActionType.MOVEMENT.value,
)
self.send_action(action)
def handle_key_event(self, event: pygame.event.Event):

Fabian Heinrich
committed
"""Handles key events for the pickup and interaction keys. Pickup is a single action,
for interaction keydown and keyup is necessary, because the player has to be able to hold
the key down.

Fabian Heinrich
committed
event: Pygame event for extracting the key action.

Fabian Heinrich
committed
for key_set in self.key_sets:
current_player_name = str(key_set.current_player)
if event.key == key_set.pickup_key and event.type == pygame.KEYDOWN:
action = Action(current_player_name, ActionType.PICK_UP_DROP, None)
self.send_action(action)

Fabian Heinrich
committed
if event.key == key_set.interact_key:

Fabian Heinrich
committed
if event.type == pygame.KEYDOWN:

Florian Schröder
committed
action = Action(

Fabian Heinrich
committed
current_player_name, ActionType.INTERACT, InterActionData.START

Florian Schröder
committed
)
self.send_action(action)

Fabian Heinrich
committed
elif event.type == pygame.KEYUP:

Florian Schröder
committed
action = Action(

Fabian Heinrich
committed
current_player_name, ActionType.INTERACT, InterActionData.STOP

Florian Schröder
committed
)
self.send_action(action)
if event.key == key_set.switch_key:

Fabian Heinrich
committed
if event.type == pygame.KEYDOWN:
key_set.next_player()
def handle_joy_stick_event(
self, event: pygame.event.Event, joysticks: dict[int, pygame.joystick.Joystick]
):
"""Handles joy stick events for the pickup and interaction keys. Pickup is a single action,
for interaction buttondown and buttonup is necessary, because the player has to be able to hold
the button down.
Args:
event: Pygame event for extracting the button action.
joysticks: list of joysticks
current_player_name = str(key_set.current_player)
# if a joystick is connected for current player
if key_set.joystick in joysticks:
# pickup = Button A <-> 0
if (
joysticks[key_set.joystick].get_button(0)
and event.type == pygame.JOYBUTTONDOWN
):
action = Action(current_player_name, ActionType.PICK_UP_DROP, None)
self.send_action(action)
# interact = Button X <-> 2
if (
joysticks[key_set.joystick].get_button(2)
and event.type == pygame.JOYBUTTONDOWN
):
action = Action(
current_player_name, ActionType.INTERACT, InterActionData.START
)
self.send_action(action)
# stop interaction if last pressed button was X <-> 2
if event.button == 2 and event.type == pygame.JOYBUTTONUP:
action = Action(
current_player_name, ActionType.INTERACT, InterActionData.STOP
)
self.send_action(action)
if joysticks[key_set.joystick].get_button(3):
if event.type == pygame.JOYBUTTONDOWN:
key_set.next_player()
def set_window_size(self):
"""Sets the window size based on fullscreen or not."""
if self.fullscreen:
flags = pygame.FULLSCREEN
self.window_width = self.window_width_fullscreen
self.window_height = self.window_height_fullscreen
else:
flags = 0
self.window_width = self.window_width_windowed
self.window_height = self.window_height_windowed

Fabian Heinrich
committed
self.screen_margin = self.visualization_config["GameWindow"][
"screen_margin_proportion"
] * min(self.window_width, self.window_height)
self.main_window = pygame.display.set_mode(

Fabian Heinrich
committed
(
self.window_width,
self.window_height,
flags=flags,
def set_game_size(self, max_width: float = None, max_height: float = None):
"""Sets the game size based on the kitchen size and the current window size.
Args:
max_width: Maximum width of the game screen.
max_height: Maximum height of the game screen.
"""
if max_width is None:
max_width = self.window_width - (2 * self.screen_margin)
if max_height is None:
max_height = self.window_height - (2 * self.screen_margin)
self.kitchen_aspect_ratio = self.kitchen_height / self.kitchen_width
if self.kitchen_width > self.kitchen_height:
self.game_width = max_width
self.game_height = self.game_width * self.kitchen_aspect_ratio
if self.game_height > max_height:
self.game_height = max_height
self.game_width = self.game_height / self.kitchen_aspect_ratio
else:
self.game_height = max_height
self.game_width = self.game_height / self.kitchen_aspect_ratio
if self.game_width > max_width:
self.game_width = max_width
self.game_height = self.game_width * self.kitchen_aspect_ratio
self.grid_size = int(self.game_width / self.kitchen_width)
self.game_width = max(self.game_width, 100)
self.game_height = max(self.game_height, 100)
self.grid_size = max(self.grid_size, 1)
self.vis.set_grid_size(self.grid_size)
residual_x = self.game_width - (self.kitchen_width * self.grid_size)
residual_y = self.game_height - (self.kitchen_height * self.grid_size)
self.game_width -= residual_x
self.game_height -= residual_y
self.game_screen = pygame.Surface(
(
self.game_width,
self.game_height,
)
def init_ui_elements(self):
"""Creates all UI elements. Creates lists of which elements belong on which screen."""
self.manager = pygame_gui.UIManager(
(self.window_width, self.window_height),
starting_language=self.language,
translation_directory_paths=[ROOT_DIR / "pygame_2d_vis" / "locales"],
)
self.manager.get_theme().load_theme(
ROOT_DIR / "pygame_2d_vis" / "gui_theme.json"
)
self.elements_margin = self.window_height * 0.02

Fabian Heinrich
committed
########################################################################
# All screens
########################################################################
fullscreen_button_rect = pygame.Rect(
(0, 0), (self.buttons_width * 0.7, self.buttons_height)
)
fullscreen_button_rect.topright = (-self.buttons_width, 0)
self.fullscreen_button = pygame_gui.elements.UIButton(
relative_rect=fullscreen_button_rect,

Fabian Heinrich
committed
manager=self.manager,
object_id="#fullscreen_button",
anchors={"right": "right", "top": "top"},
)
rect = pygame.Rect((0, 0), (self.buttons_width, self.buttons_height))
rect.topright = (0, 0)
self.quit_button = pygame_gui.elements.UIButton(
relative_rect=rect,

Fabian Heinrich
committed
manager=self.manager,
object_id="#quit_button",
anchors={"right": "right", "top": "top"},
)
########################################################################
# Start screen
########################################################################
self.start_button = pygame_gui.elements.UIButton(
relative_rect=pygame.Rect(

Fabian Heinrich
committed
(0, 0), (self.buttons_width, self.buttons_height)
text="translations.start_game",
text_kwargs={},

Fabian Heinrich
committed
anchors={"center": "center"},

Fabian Heinrich
committed
if self.visualization_config["Gui"]["press_button_to_continue"]:
img = pygame.image.load(
ROOT_DIR
/ "pygame_2d_vis"
/ "gui_images"
/ f"continue_{self.language}.png"
).convert_alpha()
image_rect = img.get_rect()
img_width = self.buttons_width * 1.5
img_height = img_width * (image_rect.height / image_rect.width)
new_dims = (img_width, img_height)
img = pygame.transform.smoothscale(img, new_dims)
image_rect = img.get_rect()
image_rect.centery += 80
self.press_a_image = pygame_gui.elements.UIImage(
image_rect,
img,
manager=self.manager,
anchors={"centerx": "centerx", "centery": "centery"},
)
else:
self.press_a_image = None
# self.press_a_image.set_dimensions(new_dims)
if not self.CONNECT_WITH_STUDY_SERVER:
assert len(self.layout_file_paths) != 0, "No layout files."
dropdown_width, dropdown_height = 200, 40
self.layout_selection = pygame_gui.elements.UIDropDownMenu(
relative_rect=pygame.Rect(
(
0,
0,
),
(dropdown_width, dropdown_height),
),
manager=self.manager,
options_list=self.layout_file_paths,
starting_option="basic.layout"
if "basic.layout" in self.layout_file_paths
else random.choice(self.layout_file_paths),
)

Fabian Heinrich
committed
player_selection_rect = pygame.Rect(
(0, 0),
(
(self.window_height // 4),

Fabian Heinrich
committed
),
)
player_selection_rect.bottom = -self.elements_margin

Fabian Heinrich
committed
self.player_selection_container = pygame_gui.elements.UIPanel(
player_selection_rect,
manager=self.manager,
object_id="#players",
anchors={"bottom": "bottom", "centerx": "centerx"},
)

Fabian Heinrich
committed
self.multiple_keysets_button = pygame_gui.elements.UIButton(

Fabian Heinrich
committed
manager=self.manager,
container=self.player_selection_container,
text="not set",
anchors={"centerx": "centerx", "centery": "centery"},

Fabian Heinrich
committed
)
split_players_button_rect = pygame.Rect((0, 0), (190, 50))

Fabian Heinrich
committed
self.split_players_button = pygame_gui.elements.UIButton(
relative_rect=split_players_button_rect,
manager=self.manager,
container=self.player_selection_container,
text="not set",
anchors={"centery": "centery", "left_target": self.multiple_keysets_button},

Fabian Heinrich
committed
)

Fabian Heinrich
committed
(0, 0),
self.player_selection_container.get_abs_rect().height * 0.35,

Fabian Heinrich
committed
)
self.player_number_container = pygame_gui.elements.UIPanel(

Fabian Heinrich
committed
manager=self.manager,
object_id="#players_players",
container=self.player_selection_container,
anchors={"top": "top", "centerx": "centerx"},
)

Fabian Heinrich
committed
(0, 0),
self.player_selection_container.get_abs_rect().height * 0.35,

Fabian Heinrich
committed
)
self.bot_number_container = pygame_gui.elements.UIPanel(

Fabian Heinrich
committed
manager=self.manager,
object_id="#players_bots",
container=self.player_selection_container,
anchors={"bottom": "bottom", "centerx": "centerx"},
)
number_players_rect = pygame.Rect((0, 0), (200, 200))
self.added_players_label = pygame_gui.elements.UILabel(
number_players_rect,
manager=self.manager,
object_id="#number_players_label",
container=self.player_number_container,

Fabian Heinrich
committed
anchors={"center": "center"},
)
number_bots_rect = pygame.Rect((0, 0), (200, 200))
self.added_bots_label = pygame_gui.elements.UILabel(
number_bots_rect,
manager=self.manager,
object_id="#number_bots_label",
container=self.bot_number_container,

Fabian Heinrich
committed
anchors={"center": "center"},
)

Fabian Heinrich
committed
self.add_human_player_button = pygame_gui.elements.UIButton(
relative_rect=pygame.Rect((0, 0), (size, size)),

Fabian Heinrich
committed
text="+",
manager=self.manager,
anchors={"left_target": self.added_bots_label, "centery": "centery"},

Fabian Heinrich
committed
)
rect = pygame.Rect((0, 0), (size, size))
rect.right = 0

Fabian Heinrich
committed
self.remove_human_button = pygame_gui.elements.UIButton(
relative_rect=rect,

Fabian Heinrich
committed
text="-",
manager=self.manager,
anchors={
"right": "right",
"right_target": self.added_bots_label,
"centery": "centery",
},

Fabian Heinrich
committed
)
self.add_bot_button = pygame_gui.elements.UIButton(
relative_rect=pygame.Rect((0, 0), (size, size)),

Fabian Heinrich
committed
text="+",
manager=self.manager,
anchors={"left_target": self.added_bots_label, "centery": "centery"},

Fabian Heinrich
committed
)
rect = pygame.Rect((0, 0), (size, size))
rect.right = 0

Fabian Heinrich
committed
self.remove_bot_button = pygame_gui.elements.UIButton(
relative_rect=rect,

Fabian Heinrich
committed
text="-",
manager=self.manager,
anchors={
"right": "right",
"right_target": self.added_bots_label,
"centery": "centery",
},

Fabian Heinrich
committed
)
self.scroll_space_layouts = pygame_gui.elements.UIScrollingContainer(
relative_rect=pygame.Rect((0, 0), (self.buttons_width * 1.2, self.window_height)),
manager=self.manager,
anchors={"top": "top", "left": "left"},
)
self.setup_layout_selection()
rect = pygame.Rect(
(0, 0),
(
self.window_width * 0.5,
self.buttons_height,
),
)
self.selected_layout_label = pygame_gui.elements.UILabel(
text="translations.selected_layout",
text_kwargs={"layout": "basic.layout"},
relative_rect=rect,
manager=self.manager,
object_id="#selected_layout",
anchors={"centerx": "centerx", "bottom_target": self.start_button},
)
########################################################################
# Tutorial screen
########################################################################

Fabian Heinrich
committed
button_rect = pygame.Rect((0, 0), (220, 80))

Fabian Heinrich
committed
self.continue_button = pygame_gui.elements.UIButton(
relative_rect=button_rect,

Fabian Heinrich
committed
manager=self.manager,
anchors={"centerx": "centerx", "bottom": "bottom"},
)

Fabian Heinrich
committed
button_rect = pygame.Rect((0, 0), (220, 80))
button_rect.bottom = -self.elements_margin
button_rect.centerx += 250
self.continue_button_two = pygame_gui.elements.UIButton(
relative_rect=button_rect,
text="translations.continue",
manager=self.manager,
anchors={"centerx": "centerx", "bottom": "bottom"},
)
ROOT_DIR / "pygame_2d_vis" / "gui_images" / f"controls_{self.language}.png"
).convert_alpha()
image_rect = image.get_rect()
# img_width = self.window_width * 0.68
# img_height = img_width * (image_rect.height / image_rect.width)
img_height = self.window_height * 0.95
img_width = img_height * (image_rect.width / image_rect.height)

Fabian Heinrich
committed
new_dims = (img_width, img_height)
image = pygame.transform.smoothscale(image, new_dims)

Fabian Heinrich
committed
image_rect = image.get_rect()
self.tutorial_image = pygame_gui.elements.UIImage(
image_rect,
image,
manager=self.manager,
ROOT_DIR / "pygame_2d_vis" / "gui_images" / f"try_{self.language}.png"
).convert_alpha()
image_rect = arrow_img.get_rect()
img_width = self.window_width * 0.2
img_height = img_width * (image_rect.height / image_rect.width)
new_dims = (img_width, img_height)
arrow_img = pygame.transform.smoothscale(arrow_img, new_dims)
rect = arrow_img.get_rect()
rect.left = self.window_width * 0.55
rect.top = self.window_height * 0.7
self.arrow_img = pygame_gui.elements.UIImage(
relative_rect=rect,
image_surface=arrow_img,
manager=self.manager,
anchors={
"left": "left",
"top": "top",
},
)

Fabian Heinrich
committed
rect = pygame.Rect(
(0, 0),
(self.window_width * 0.25, self.window_height * 0.4),

Fabian Heinrich
committed
)

Fabian Heinrich
committed
self.tutorial_recipe_container = pygame_gui.elements.UIPanel(
relative_rect=rect,

Fabian Heinrich
committed
object_id="#graph_container",
anchors={"right": "right", "top": "top", "top_target": self.quit_button},

Fabian Heinrich
committed
self.tutorial_recipe_graph_rect = pygame.Rect(
(0, 0), (self.window_width * 0.25, self.window_height * 0.2)

Fabian Heinrich
committed
self.tutorial_graph_image = pygame_gui.elements.UIImage(
relative_rect=self.tutorial_recipe_graph_rect,
image_surface=pygame.Surface(self.tutorial_recipe_graph_rect.size),

Fabian Heinrich
committed
object_id="#recipe_graph",
container=self.tutorial_recipe_container,
anchors={"centerx": "centerx", "bottom": "bottom"},

Fabian Heinrich
committed
)
r = pygame.Rect((0, 0), (self.window_width * 0.25, self.window_height * 0.05))

Fabian Heinrich
committed
r.bottom = 0
text = pygame_gui.elements.UILabel(

Fabian Heinrich
committed
relative_rect=r,
manager=self.manager,
container=self.tutorial_recipe_container,

Fabian Heinrich
committed
anchors={
"centerx": "centerx",
"bottom": "bottom",
"bottom_target": self.tutorial_graph_image,

Fabian Heinrich
committed
},
########################################################################
# PreGame screen
########################################################################
rect = pygame.Rect(
(0, 0),
(self.window_width, 50),
)
rect.top = 20
self.level_name_label = pygame_gui.elements.UILabel(
text=f"not set",
self.text_recipes_label = pygame_gui.elements.UILabel(
relative_rect=pygame.Rect(
(0, 0),
),
manager=self.manager,
anchors={"centerx": "centerx", "top_target": self.level_name_label},
)
self.scroll_height = (
self.continue_button.get_abs_rect().top
- self.text_recipes_label.get_abs_rect().bottom
)
self.scroll_space_recipes = pygame_gui.elements.UIScrollingContainer(
relative_rect=pygame.Rect((0, 0), (self.window_width, self.scroll_height)),
manager=self.manager,
anchors={"centerx": "centerx", "top_target": self.text_recipes_label},
)
########################################################################
# Game screen
########################################################################
self.orders_label = pygame_gui.elements.UILabel(
relative_rect=pygame.Rect(0, 0, self.buttons_width, self.screen_margin),
manager=self.manager,
object_id="#orders_label",
)
self.orders_container_width = (
self.window_width - (2 * self.buttons_width) - (self.buttons_width * 0.7)
)
self.orders_image = pygame_gui.elements.UIImage(
relative_rect=pygame.Rect(
0, 0, self.orders_container_width, self.screen_margin
),
image_surface=pygame.Surface(
(self.orders_container_width, self.screen_margin)
),
manager=self.manager,
object_id="#recipe_graph",
anchors={"top": "top", "left_target": self.orders_label},
)

Fabian Heinrich
committed
rect = pygame.Rect(
(0, 0),
(self.window_width * 0.3, self.buttons_height),

Fabian Heinrich
committed
)
rect.bottomleft = (0, 0)
self.score_label = pygame_gui.elements.UILabel(

Fabian Heinrich
committed
text=f"Score not set",
relative_rect=rect,
manager=self.manager,
object_id="#score_label",

Fabian Heinrich
committed
anchors={"bottom": "bottom", "left": "left"},

Fabian Heinrich
committed
rect = pygame.Rect(
(0, 0),
(self.window_width * 0.4, self.buttons_height),
)
rect.bottom = 0
self.timer_label = pygame_gui.elements.UILabel(

Fabian Heinrich
committed
text="GAMETIME not set",
relative_rect=rect,
manager=self.manager,
object_id="#timer_label",

Fabian Heinrich
committed
anchors={"bottom": "bottom", "centerx": "centerx"},
)
rect = pygame.Rect(
(0, 0),
(self.window_width, self.screen_margin),
)
rect.right = 20
self.wait_players_label = pygame_gui.elements.UILabel(

Fabian Heinrich
committed
relative_rect=rect,
manager=self.manager,
object_id="#wait_players_label",
anchors={"centery": "centery", "right": "right"},
rect = pygame.Rect((0, 0), (self.buttons_width, self.buttons_height))
rect.bottomright = (0, 0)
self.return_to_main_button = pygame_gui.elements.UIButton(
relative_rect=rect,
text="translations.return_to_main_menu",
manager=self.manager,
object_id="#main_menu_button",
anchors={"right": "right", "bottom": "bottom"},
)
########################################################################
# PostGame screen
########################################################################
rect.bottom = -self.elements_margin
self.next_game_button = pygame_gui.elements.UIButton(
anchors={"centerx": "centerx", "bottom": "bottom"},
object_id="#split_players_button",
)
(self.window_width, self.window_height * 0.07),
)
self.score_conclusion = pygame_gui.elements.UILabel(
text=f"not set",
relative_rect=rect,
manager=self.manager,
object_id="#score_conclusion",
anchors={"centerx": "centerx", "top_target": self.level_name_label},
)
self.completed_meals_text_label = pygame_gui.elements.UILabel(
(self.window_width, self.window_height * 0.05),
object_id="#completed_meals_label",
anchors={"centerx": "centerx", "top_target": self.score_conclusion},
)
scroll_height = (
self.continue_button.get_abs_rect().top
- self.completed_meals_text_label.get_abs_rect().bottom
- 10