From 3f3344c3d52598fdd57d5ee6018b066383427aa9 Mon Sep 17 00:00:00 2001 From: fheinrich <fheinrich@techfak.uni-bielefeld.de> Date: Mon, 4 Dec 2023 15:18:00 +0100 Subject: [PATCH] Added collision detectio for player with players and player with counters --- .../overcooked_environment.py | 51 ++++++++++++++++++- overcooked_simulator/player.py | 1 + 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py index c6e4970e..16986f61 100644 --- a/overcooked_simulator/overcooked_environment.py +++ b/overcooked_simulator/overcooked_environment.py @@ -143,9 +143,58 @@ class Environment: player: The player for which to check collisions. Returns: True if the player is intersecting with any object in the environment. + """ + return self.detect_player_collision(player) or self.detect_collision_counters(player) + + def detect_player_collision(self, player: Player): + """Detects collisions between the queried player and other players. + A player is modelled as a circle. Collision is detected if the distance between the players is smaller + than the sum of the radius's. + + Args: + player: The player to check collisions with other players for. + + Returns: True if the player collides with other players, False if not. """ - pass + other_players = filter(lambda p: p.name != player.name, self.players.values()) + + def collide(p): + return np.linalg.norm(player.pos - p.pos) <= (player.radius + p.radius) + + return any(map(collide, other_players)) + + def detect_collision_counters(self, player: Player): + """Checks for collisions of the queried player with each counter. + + Args: + player: The player to check collisions with counters for. + + Returns: True if the player collides with any counter, False if not. + + """ + return any(map(lambda counter: self.detect_collision_player_counter(player, counter), self.counters)) + + def detect_collision_player_counter(self, player: Player, counter: Counter): + """Checks if the player and counter collide (overlap). + A counter is modelled as a rectangle (square actually), a player is modelled as a circle. + The distance of the player position (circle center) and the counter rectangle is calculated, if it is + smaller than the player radius, a collision is detected. + TODO: Efficiency improvement by checking only nearest counters? Quadtree...? + + Args: + player: The player to check the collision for. + counter: The counter to check the collision for. + + Returns: True if player and counter overlap, False if not. + + """ + size = self.counter_side_length + cx, cy = player.pos + dx = max(np.abs(cx - counter.pos[0]) - size / 2, 0) + dy = max(np.abs(cy - counter.pos[1]) - size / 2, 0) + distance = np.linalg.norm([dx, dy]) + return distance < player.radius def step(self): """Performs a step of the environment. Affects time based events such as cooking or cutting things, orders diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py index b98df2d6..bea1771a 100644 --- a/overcooked_simulator/player.py +++ b/overcooked_simulator/player.py @@ -13,6 +13,7 @@ class Player: self.pos = np.array(pos, dtype=float) self.holding = None + self.radius = 18 self.move_dist = 5 self.interaction_range = 50 self.facing_direction = np.array([0, 1]) -- GitLab