Skip to content
Snippets Groups Projects
Commit b29e3a41 authored by Florian Schröder's avatar Florian Schröder
Browse files

Improve collision detection and player control handling

This update refines the collision detection mechanism in the 'overcooked_environment' module. The changes ensure that players can't move into positions where they would collide with other elements. Player control handling in the 'overcooked_gui' module is also tweaked to provide smoother switching between players. Remaining modifications in 'arch_config.yml' deactivate the GUI in status manager and change the preference for IPAACARInfo under communication.
parent 020cb4db
No related branches found
No related tags found
1 merge request!44Resolve "GUI Player Management"
Pipeline #45488 failed
...@@ -2,7 +2,7 @@ concurrency: MultiProcessing ...@@ -2,7 +2,7 @@ concurrency: MultiProcessing
communication: communication:
communication_prefs: communication_prefs:
- !name:ipaacar_com_service.communications.ipaacar_com.IPAACARInfo - !name:ipaacar_com_service.communications.ipaacar_com.IPAACARInfo
modules: modules:
connection: connection:
...@@ -15,9 +15,10 @@ modules: ...@@ -15,9 +15,10 @@ modules:
action_execution: action_execution:
module_info: !name:cocosy_agent.modules.action_execution_module.ActionExecutionModule module_info: !name:cocosy_agent.modules.action_execution_module.ActionExecutionModule
mean_frequency_step: 10 # 2: every 0.5 seconds mean_frequency_step: 10 # 2: every 0.5 seconds
gui: # gui:
module_info: !name:aaambos.std.guis.pysimplegui.pysimplegui_window.PySimpleGUIWindowModule # module_info: !name:aaambos.std.guis.pysimplegui.pysimplegui_window.PySimpleGUIWindowModule
window_title: Counting GUI # window_title: Counting GUI
topics_to_show: [["SubtaskDecision", "cocosy_agent.conventions.communication.SubtaskDecision", ["task_type"]], ["ActionControl", "cocosy_agent.conventions.communication.ActionControl", ["action_type"]]] # topics_to_show: [["SubtaskDecision", "cocosy_agent.conventions.communication.SubtaskDecision", ["task_type"]], ["ActionControl", "cocosy_agent.conventions.communication.ActionControl", ["action_type"]]]
status_manager: status_manager:
module_info: !name:aaambos.std.modules.module_status_manager.ModuleStatusManager module_info: !name:aaambos.std.modules.module_status_manager.ModuleStatusManager
\ No newline at end of file gui: false
\ No newline at end of file
...@@ -73,17 +73,23 @@ class PlayerKeySet: ...@@ -73,17 +73,23 @@ class PlayerKeySet:
self.pickup_key: pygame.key = pickup_key self.pickup_key: pygame.key = pickup_key
self.switch_key: pygame.key = switch_key self.switch_key: pygame.key = switch_key
self.controlled_players: list[int] = players self.controlled_players: list[int] = players
self.current_player: int = players[0] self.current_player: int = players[0] if players else 0
self.current_idx = 0
self.other_keyset: list[PlayerKeySet] = []
def set_controlled_players(self, controlled_players: list[int]) -> None: def set_controlled_players(self, controlled_players: list[int]) -> None:
self.controlled_players = controlled_players self.controlled_players = controlled_players
self.current_player = self.controlled_players[0] self.current_player = self.controlled_players[0]
self.current_idx = 0
def next_player(self) -> None: def next_player(self) -> None:
self.current_player += 1 self.current_idx = (self.current_idx + 1) % len(self.controlled_players)
if self.current_player > self.controlled_players[-1]: if self.other_keyset:
self.current_player = self.controlled_players[0] for ok in self.other_keyset:
print(self.current_player, self.controlled_players) if ok.current_idx == self.current_idx:
self.next_player()
return
self.current_player = self.controlled_players[self.current_idx]
class PyGameGUI: class PyGameGUI:
...@@ -183,28 +189,32 @@ class PyGameGUI: ...@@ -183,28 +189,32 @@ class PyGameGUI:
def setup_player_keys(self, n=1, disjunct=False): def setup_player_keys(self, n=1, disjunct=False):
if n: if n:
players = list(range(self.number_humans_to_be_added))
key_set1 = PlayerKeySet( key_set1 = PlayerKeySet(
move_keys=[pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s], move_keys=[pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s],
interact_key=pygame.K_f, interact_key=pygame.K_f,
pickup_key=pygame.K_e, pickup_key=pygame.K_e,
switch_key=pygame.K_SPACE, switch_key=pygame.K_SPACE,
players=list(range(self.number_humans_to_be_added)), players=players,
) )
key_set2 = PlayerKeySet( key_set2 = PlayerKeySet(
move_keys=[pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN], move_keys=[pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN],
interact_key=pygame.K_i, interact_key=pygame.K_i,
pickup_key=pygame.K_o, pickup_key=pygame.K_o,
switch_key=pygame.K_p, switch_key=pygame.K_p,
players=list(range(self.number_humans_to_be_added)), players=players,
) )
key_sets = [key_set1, key_set2] key_sets = [key_set1, key_set2]
if disjunct: if disjunct:
split_idx = int(np.ceil(self.number_humans_to_be_added / 2)) key_set1.set_controlled_players(players[::2])
key_set1.set_controlled_players(list(range(0, split_idx))) key_set2.set_controlled_players(players[1::2])
key_set2.set_controlled_players( elif n > 1:
list(range(split_idx, self.number_humans_to_be_added)) 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()
return key_sets[:n] return key_sets[:n]
else: else:
return [] return []
......
...@@ -402,7 +402,6 @@ class Environment: ...@@ -402,7 +402,6 @@ class Environment:
Detects collisions with other players and pushes them out of the way. Detects collisions with other players and pushes them out of the way.
Args: Args:
player: The player to move.
duration: The duration for how long the movement to perform. duration: The duration for how long the movement to perform.
""" """
d_time = duration.total_seconds() d_time = duration.total_seconds()
...@@ -415,13 +414,12 @@ class Environment: ...@@ -415,13 +414,12 @@ class Environment:
], ],
dtype=float, dtype=float,
) )
print(player_positions, ".")
targeted_positions = player_positions + ( targeted_positions = player_positions + (
player_movement_vectors * (self.player_movement_speed * d_time) player_movement_vectors * (self.player_movement_speed * d_time)
) )
# Collisions player player # Collisions player between player
distances_players_after_scipy = distance_matrix( distances_players_after_scipy = distance_matrix(
targeted_positions, targeted_positions targeted_positions, targeted_positions
) )
...@@ -457,52 +455,46 @@ class Environment: ...@@ -457,52 +455,46 @@ class Environment:
] ]
nearest_counter_to_player = closest_counter_positions - new_positions nearest_counter_to_player = closest_counter_positions - new_positions
# print(nearest_counter_to_player)
collided = np.min(counter_distances, axis=1) < self.player_radius + 0.5 collided = np.min(counter_distances, axis=1) < self.player_radius + 0.5
# print(" COLLIDED", collided)
# print("CLOSEST_COUNTER", closest_counter_positions)
relevant_axes = np.abs(nearest_counter_to_player).argmax(axis=1) relevant_axes = np.abs(nearest_counter_to_player).argmax(axis=1)
relevant_values = nearest_counter_to_player.max(axis=1)
for idx, player in enumerate(player_positions): for idx, player in enumerate(player_positions):
axis = relevant_axes[idx] axis = relevant_axes[idx]
if collided[idx]: if collided[idx]:
# print("before", updated_movement) # collide with counter left or top
if nearest_counter_to_player[idx][axis] < 0: if nearest_counter_to_player[idx][axis] < 0:
# print("settings more")
# new_positions[idx, axis] = np.min(
# [
# player_positions[idx, axis],
# closest_counter_positions[idx, axis],
# ]
# )
updated_movement[idx, axis] = max(updated_movement[idx, axis], 0) updated_movement[idx, axis] = max(updated_movement[idx, axis], 0)
# collide with counter right or bottom
if nearest_counter_to_player[idx][axis] > 0: if nearest_counter_to_player[idx][axis] > 0:
# print("settings less")
# new_positions[idx, axis] = np.max(
# [
# player_positions[idx, axis],
# closest_counter_positions[idx, axis],
# ]
# )
updated_movement[idx, axis] = min(updated_movement[idx, axis], 0) updated_movement[idx, axis] = min(updated_movement[idx, axis], 0)
# print("after", updated_movement)
# new_positions[collided] = player_positions[collided]
print(updated_movement, "-")
new_positions = player_positions + ( new_positions = player_positions + (
updated_movement * (self.player_movement_speed * d_time) updated_movement * (self.player_movement_speed * d_time)
) )
print(new_positions, "<")
# new_positions[min_counter_distances < self.player_radius] = player_positions[min_counter_distances < self.player_radius] # Check if pushed players collide with counters or second closest is to close
counter_diff_vecs = (
# counter_distances_axes = np.max((np.abs(counter_diff_vecs)), axis=1) new_positions[:, np.newaxis, :] - self.counter_positions[np.newaxis, :, :]
)
counter_distances = np.max((np.abs(counter_diff_vecs)), axis=2)
collided2 = np.min(counter_distances, axis=1) < self.player_radius + 0.5
# player do not move if they collide after pushing/sliding
new_positions[collided2] = player_positions[collided2]
# Players that pushed the player that can not be pushed do also no movement
# in the future these players could slide around the player?
for idx, collides in enumerate(collided2):
if collides:
new_positions[collision_idxs[idx]] = player_positions[
collision_idxs[idx]
]
# Check if two moving players collide into each other: No movement (Future: slide?)
distances_players_after_scipy = distance_matrix(new_positions, new_positions)
collision_idxs = distances_players_after_scipy < (2 * self.player_radius)
collision_idxs[eye_idxs] = False
collision_idxs = np.any(collision_idxs, axis=1)
new_positions[collision_idxs] = player_positions[collision_idxs]
# Collisions player world borders # Collisions player world borders
new_positions = np.max( new_positions = np.max(
...@@ -513,8 +505,9 @@ class Environment: ...@@ -513,8 +505,9 @@ class Environment:
) )
for idx, p in enumerate(self.players.values()): for idx, p in enumerate(self.players.values()):
p.turn(player_movement_vectors[idx]) if not (new_positions[idx] == player_positions[idx]).all():
p.move_abs(new_positions[idx]) p.turn(player_movement_vectors[idx])
p.move_abs(new_positions[idx])
def detect_collision(self, player: Player): def detect_collision(self, player: Player):
"""Detect collisions between the player and other players or counters. """Detect collisions between the player and other players or counters.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment