Newer
Older
import argparse
import signal
import subprocess

Fabian Heinrich
committed
import sys
from subprocess import Popen
import requests
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.game_server import (
CreateEnvironmentConfig,
WebsocketMessage,
PlayerRequestType,
)
from cooperative_cuisine.pygame_2d_vis.drawing import Visualizer
from cooperative_cuisine.pygame_2d_vis.game_colors import colors
from cooperative_cuisine.state_representation import StateRepresentation
from cooperative_cuisine.utils import (
url_and_port_arguments,
disable_websocket_logging_arguments,
add_list_of_manager_ids_arguments,
class MenuStates(Enum):
Start = "Start"
ControllerTutorial = "ControllerTutorial"
PreGame = "PreGame"
"""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:

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:
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]
"""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
CONNECT_WITH_STUDY_SERVER: bool,
USE_AAAMBOS_AGENT: bool,

Fabian Heinrich
committed
):

Fabian Heinrich
committed
self.CONNECT_WITH_STUDY_SERVER = CONNECT_WITH_STUDY_SERVER
self.USE_AAAMBOS_AGENT = USE_AAAMBOS_AGENT
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.websocket_url = f"ws://{game_host}:{game_port}/ws/player/"
self.websockets = {}
if CONNECT_WITH_STUDY_SERVER:
self.request_url = f"http://{study_host}:{study_port}"
else:
self.request_url = f"http://{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.FPS = self.visualization_config["GameWindow"]["FPS"]
self.screen_margin = self.visualization_config["GameWindow"]["screen_margin"]
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.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)
self.menu_state = MenuStates.Start
self.manager: pygame_gui.UIManager
self.sub_processes = []
self.layout_file_paths = sorted(
(ROOT_DIR / "configs" / "layouts").rglob("*.layout")
self.last_state: StateRepresentation
self.player_info = {"0": {"name": "0"}}
self.level_info = {"name": "Level", "recipe_graphs": []}

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 disjunct:
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,
move_vec,
self.send_action(action)
def handle_joy_stick_input(self, joysticks):
"""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.2
# 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 (
abs(axis_left_right) > tolerance_threshold
or abs(axis_up_down) > tolerance_threshold
):
move_vec = np.zeros(2)
if abs(axis_left_right) > tolerance_threshold:
move_vec[0] += axis_left_right
# axis 1 = joy stick right --> up & down
if abs(axis_up_down) > tolerance_threshold:
move_vec[1] += axis_up_down
# if np.linalg.norm(move_vec) != 0:
# move_vec = move_vec / np.linalg.norm(move_vec)
action = Action(
current_player_name,
ActionType.MOVEMENT,
move_vec,
duration=self.time_delta,
)
self.send_action(action)
def handle_key_event(self, 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:

Fabian Heinrich
committed
action = Action(current_player_name, ActionType.PUT, "pickup")
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, joysticks):
"""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.PUT, "pickup")
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):
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
self.main_window = pygame.display.set_mode(

Fabian Heinrich
committed
(
self.window_width,
self.window_height,
flags=flags,
def reset_window_size(self):
self.game_width = 0
self.game_height = 0
self.set_window_size()
def set_game_size(self, max_width=None, max_height=None):
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)
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):
self.manager = pygame_gui.UIManager((self.window_width, self.window_height))
self.manager.get_theme().load_theme(
ROOT_DIR / "pygame_2d_vis" / "gui_theme.json"
)
########################################################################
# Start screen
########################################################################
self.start_button = pygame_gui.elements.UIButton(
relative_rect=pygame.Rect(

Fabian Heinrich
committed
(0, 0), (self.buttons_width, self.buttons_height)

Fabian Heinrich
committed
anchors={"center": "center"},
ROOT_DIR / "pygame_2d_vis" / "continue.drawio.png"
).convert_alpha()
image_rect = img.get_rect()
image_rect.centery += 80
self.press_a_image = pygame_gui.elements.UIImage(
image_rect,
img,
anchors={"centerx": "centerx", "centery": "centery"},
img_width = self.buttons_width * 1.5
img_height = img_width * (image_rect.height / image_rect.width)
new_dims = (img_width, img_height)
self.press_a_image.set_dimensions(new_dims)
rect = pygame.Rect((0, 0), (self.buttons_width, self.buttons_height))
rect.topright = (0, 0)

Fabian Heinrich
committed
self.quit_button = pygame_gui.elements.UIButton(
relative_rect=rect,
object_id="#quit_button",

Fabian Heinrich
committed
anchors={"right": "right", "top": "top"},

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

Fabian Heinrich
committed
),
)

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"},
)
multiple_keysets_button_rect = pygame.Rect((0, 0), (190, 50))

Fabian Heinrich
committed
self.multiple_keysets_button = pygame_gui.elements.UIButton(
relative_rect=multiple_keysets_button_rect,
manager=self.manager,
container=self.player_selection_container,
text="not set",
anchors={"left": "left", "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={"centerx": "centerx", "centery": "centery"},

Fabian Heinrich
committed
)

Fabian Heinrich
committed
players_container_rect = pygame.Rect(
(0, 0),
(
self.window_width * 0.6,
self.player_selection_container.get_abs_rect().height // 3,
),

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

Fabian Heinrich
committed
relative_rect=players_container_rect,
manager=self.manager,
object_id="#players_players",
container=self.player_selection_container,
anchors={"top": "top", "centerx": "centerx"},
)
bot_container_rect = pygame.Rect(
(0, 0),
(
self.window_width * 0.6,
self.player_selection_container.get_abs_rect().height // 3,
),

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

Fabian Heinrich
committed
relative_rect=bot_container_rect,
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
text=f"Humans to be added: -",

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
text=f"Bots to be added: -",

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

Fabian Heinrich
committed
add_player_button_rect = pygame.Rect((0, 0), (size, size))
add_player_button_rect.right = 0
self.add_human_player_button = pygame_gui.elements.UIButton(
relative_rect=add_player_button_rect,
text="+",
manager=self.manager,

Fabian Heinrich
committed
anchors={"right": "right", "centery": "centery"},
)
remove_player_button_rect = pygame.Rect((0, 0), (size, size))
remove_player_button_rect.left = 0
self.remove_human_button = pygame_gui.elements.UIButton(
relative_rect=remove_player_button_rect,
text="-",
manager=self.manager,

Fabian Heinrich
committed
anchors={"left": "left", "centery": "centery"},
)
add_bot_button_rect = pygame.Rect((0, 0), (size, size))
add_bot_button_rect.right = 0
self.add_bot_button = pygame_gui.elements.UIButton(
relative_rect=add_bot_button_rect,
text="+",
manager=self.manager,

Fabian Heinrich
committed
anchors={"right": "right", "centery": "centery"},
)
remove_bot_button_rect = pygame.Rect((0, 0), (size, size))
remove_bot_button_rect.left = 0
self.remove_bot_button = pygame_gui.elements.UIButton(
relative_rect=remove_bot_button_rect,
text="-",
manager=self.manager,

Fabian Heinrich
committed
anchors={"left": "left", "centery": "centery"},
)
########################################################################
# Tutorial screen
########################################################################
image = pygame.image.load(
ROOT_DIR / "pygame_2d_vis" / "tutorial_files" / "tutorial.drawio.png"
).convert_alpha()
image_rect = image.get_rect()

Fabian Heinrich
committed
image_rect.topleft = (20, self.buttons_height)
self.tutorial_image = pygame_gui.elements.UIImage(
image_rect,
image,
manager=self.manager,
anchors={"top": "top", "left": "left"},

Fabian Heinrich
committed
img_width = self.window_width * 0.8
img_height = img_width * (image_rect.height / image_rect.width)
new_dims = (img_width, img_height)
self.tutorial_image.set_dimensions(new_dims)
button_rect = pygame.Rect((0, 0), (220, 80))
button_rect.bottom = -20
self.continue_button = pygame_gui.elements.UIButton(
relative_rect=button_rect,
text="Continue",
manager=self.manager,
anchors={"centerx": "centerx", "bottom": "bottom"},
)
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,
text="Fullscreen",
manager=self.manager,
object_id="#fullscreen_button",
anchors={"right": "right", "top": "top"},
)
########################################################################
# 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(
text=f"Recipes in this level:",
relative_rect=pygame.Rect(
(0, 0),
),
manager=self.manager,
anchors={"centerx": "centerx", "top_target": self.level_name_label},
)
scroll_height = (
self.continue_button.get_abs_rect().top
- self.text_recipes_label.get_abs_rect().bottom
)
self.scroll_width = self.window_width
self.scroll_space = pygame_gui.elements.UIScrollingContainer(
relative_rect=pygame.Rect((0, 0), (self.scroll_width, scroll_height)),
manager=self.manager,
anchors={"centerx": "centerx", "top_target": self.text_recipes_label},
)
########################################################################
# Game screen
########################################################################
self.orders_label = pygame_gui.elements.UILabel(
text="Orders:",
relative_rect=pygame.Rect(0, 0, self.screen_margin, self.screen_margin),
manager=self.manager,
object_id="#orders_label",
)

Fabian Heinrich
committed
rect = pygame.Rect(
(0, 0),
(self.window_width * 0.2, self.buttons_height),
)
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(
text="WAITING FOR OTHER PLAYERS",
relative_rect=rect,
manager=self.manager,
object_id="#wait_players_label",
anchors={"centery": "centery", "right": "right"},
########################################################################
# PostGame screen
########################################################################
self.next_game_button = pygame_gui.elements.UIButton(
manager=self.manager,
text="Next game",
anchors={"centerx": "centerx", "bottom": "bottom"},
object_id="#split_players_button",
)
self.finish_study_button = pygame_gui.elements.UIButton(
manager=self.manager,
text="Finish study",
anchors={"centerx": "centerx", "bottom": "bottom"},
object_id="#split_players_button",
)
rect = pygame.Rect(
(0, 0),
(self.window_width, 50),
)
self.score_conclusion = pygame_gui.elements.UILabel(
text=f"not set",
relative_rect=rect,
manager=self.manager,
object_id="#level_name",
anchors={"centerx": "centerx", "top_target": self.level_name_label},
)
self.completed_meals_text_label = pygame_gui.elements.UILabel(
text=f"Completed meals:",
relative_rect=pygame.Rect(
(0, 0),
(self.window_width * 0.7, 50),
),
manager=self.manager,
object_id="#level_name",
anchors={"centerx": "centerx", "top_target": self.score_conclusion},
)
########################################################################
# End screen
########################################################################
conclusion_rect = pygame.Rect(
0, 0, self.window_width * 0.6, self.window_height * 0.4
)
self.thank_you_label = pygame_gui.elements.UILabel(
text="Thank you!",
relative_rect=conclusion_rect,
manager=self.manager,
object_id="#score_label",
anchors={"center": "center"},
)
########################################################################
self.start_screen_elements = [
self.start_button,
self.quit_button,
self.fullscreen_button,
self.player_selection_container,
]
self.tutorial_screen_elements = [
self.tutorial_image,
self.continue_button,
self.fullscreen_button,
]
self.pregame_screen_elements = [
self.continue_button,
self.quit_button,
self.fullscreen_button,
]
self.game_screen_elements = [
self.orders_label,
self.score_label,
self.timer_label,

Fabian Heinrich
committed
self.wait_players_label,
]

Fabian Heinrich
committed
self.postgame_screen_elements = [
self.scroll_space,
self.next_game_button,
self.finish_study_button,
]

Fabian Heinrich
committed
self.end_screen_elements = [
self.fullscreen_button,
self.quit_button,
self.thank_you_label,
]

Fabian Heinrich
committed
self.rest = [
self.fullscreen_button,
self.quit_button,
]
def show_screen_elements(self, elements: list):
for element in (
self.start_screen_elements
+ self.tutorial_screen_elements
+ self.pregame_screen_elements
+ self.game_screen_elements
+ self.postgame_screen_elements
+ self.end_screen_elements

Fabian Heinrich
committed
+ self.rest
):
element.hide()
for element in elements:
element.show()
def update_screen_elements(self):
match self.menu_state:
case MenuStates.Start:
self.show_screen_elements(self.start_screen_elements)

Fabian Heinrich
committed
if self.CONNECT_WITH_STUDY_SERVER:
self.bot_number_container.hide()
self.update_selection_elements()
case MenuStates.ControllerTutorial:
self.show_screen_elements(self.tutorial_screen_elements)
if self.CONNECT_WITH_STUDY_SERVER:
self.get_game_connection(tutorial=True)
else:
self.create_env_on_game_server(tutorial=True)
self.setup_game(tutorial=True)
self.set_game_size(

Fabian Heinrich
committed
max_height=self.window_height * 0.3,
max_width=self.window_width * 0.3,
)
self.game_center = (

Fabian Heinrich
committed
self.window_width - self.game_width / 2 - 20,
self.window_height - self.game_height / 2 - 20,
)
self.show_screen_elements(self.pregame_screen_elements)
self.show_screen_elements(self.game_screen_elements)
self.show_screen_elements(self.postgame_screen_elements)

Fabian Heinrich
committed
if self.last_level:

Fabian Heinrich
committed
self.next_game_button.hide()
self.finish_study_button.show()
else:
self.next_game_button.show()
self.finish_study_button.hide()
self.show_screen_elements(self.end_screen_elements)
def draw_main_window(self):
self.main_window.fill(
colors[self.visualization_config["GameWindow"]["background_color"]]
)
match self.menu_state:
case MenuStates.ControllerTutorial:

Fabian Heinrich
committed
self.draw_tutorial_screen_frame()
case MenuStates.Game:
self.draw_game_screen_frame()

Fabian Heinrich
committed
self.manager.draw_ui(self.main_window)
self.manager.update(self.time_delta)
pygame.display.flip()
def draw_tutorial_screen_frame(self):
self.handle_keys()
state = self.request_state()
self.vis.draw_gamescreen(
self.game_screen,
state,
self.grid_size,
[int(k.current_player) for k in self.key_sets],
)
game_screen_rect = self.game_screen.get_rect()
game_screen_rect.center = self.game_center
self.main_window.blit(self.game_screen, game_screen_rect)
self.score_conclusion.set_text(f"Your final score is {score}. Hurray!")
self.level_name_label.set_text(f"Completed: {self.level_info['name']}!")
# icon_size = 50
container_width = self.scroll_width * 0.9
container_height = len(served_meals) * row_height
main_container = pygame_gui.elements.UIPanel(
relative_rect=pygame.Rect(
(
container_width,
container_height,
),
),
object_id="#graph_container",
manager=self.manager,
container=self.scroll_space,
)
for idx, (player, meal) in enumerate(served_meals):
anchors = {"centerx": "centerx", "top": "top"}
anchors = {
"centerx": "centerx",
container = pygame_gui.elements.UIPanel(
relative_rect=pygame.Rect(
(0, 0),
(
container_width,
row_height,
),
),
object_id="#graph_container",
manager=self.manager,
container=main_container,