def ray_casting_npc_player(npc_x, npc_y, blocked_doors, world_map, player_pos): ox, oy = player_pos xm, ym = mapping(ox, oy) delta_x, delta_y = ox - npc_x, oy - npc_y angle = math.atan2(delta_y, delta_x) angle += math.pi # ray casting sin_a = math.sin(angle) cos_a = math.cos(angle) # verticals x, dx = (xm + TILE, 1) if cos_a >= 0 else (xm, -1) for i in range(int(abs(delta_x) // TILE)): depth_v = (x - ox) / cos_a yv = oy + depth_v * sin_a tile_v = mapping(x + dx, yv) if tile_v in world_map or tile_v in blocked_doors: return False x += dx * TILE # horizontals y, dy = (ym + TILE, 1) if sin_a >= 0 else (ym, -1) for i in range(int(abs(delta_y) // TILE)): depth_h = (y - oy) / sin_a xh = ox + depth_h * cos_a tile_h = mapping(xh, y + dy) if tile_h in world_map or tile_h in blocked_doors: return False y += dy * TILE return True
def ray_casting_npc_player(npc_x, npc_y, world_map, player_pos): ox, oy = player_pos xm, ym = mapping(ox, oy) delta_x, delta_y = ox - npc_x, oy - npc_y cur_angle = math.atan2(delta_y, delta_x) cur_angle += math.pi sin_a = math.sin(cur_angle) sin_a = sin_a if sin_a else 0.000001 cos_a = math.cos(cur_angle) cos_a = cos_a if cos_a else 0.000001 # verticals x, dx = (xm + TILE, 1) if cos_a >= 0 else (xm, -1) for i in range(0, int(abs(delta_x)) // TILE): depth_v = (x - ox) / cos_a yv = oy + depth_v * sin_a tile_v = mapping(x + dx, yv) if tile_v in world_map: return False x += dx * TILE # horizontals y, dy = (ym + TILE, 1) if sin_a >= 0 else (ym, -1) for i in range(0, int(abs(delta_y)) // TILE): depth_h = (y - oy) / sin_a xh = ox + depth_h * cos_a tile_h = mapping(xh, y + dy) if tile_h in world_map: return False y += dy * TILE return True
def blocked_doors(self): blocked_doors = Dict.empty(key_type=types.UniTuple(int32, 2), value_type=int32) for obj in self.list_of_objects: if obj.flag in {'door_h', 'door_v'} and obj.blocked: i, j = mapping(obj.x, obj.y) blocked_doors[(i, j)] = 0 return blocked_doors
def ray_casting_npc_player(npc_x, npc_y, blocked_doors, world_map, player_pos): """ Sent one ray and define if player is reachable by npc :param npc_x: :param npc_y: :param world_map: :param player_pos: :return: True/False """ ox, oy = player_pos xm, ym = mapping(ox, oy) delta_x, delta_y = ox - npc_x, oy - npc_y cur_angle = math.atan2(delta_y, delta_x) cur_angle += math.pi sin_a = math.sin(cur_angle) sin_a = sin_a if sin_a else 0.000001 cos_a = math.cos(cur_angle) cos_a = cos_a if cos_a else 0.000001 # verticals x, dx = (xm + TILE, 1) if cos_a >= 0 else (xm, -1) for i in range(0, int(abs(delta_x)) // TILE): depth_v = (x - ox) / cos_a yv = oy + depth_v * sin_a tile_v = mapping(x + dx, yv) # Check for blocked_doors. NPC doesn't see the player through the doors. if tile_v in world_map or tile_v in blocked_doors: return False x += dx * TILE # horizontals y, dy = (ym + TILE, 1) if sin_a >= 0 else (ym, -1) for i in range(0, int(abs(delta_y)) // TILE): depth_h = (y - oy) / sin_a xh = ox + depth_h * cos_a tile_h = mapping(xh, y + dy) # Check for blocked_doors. NPC doesn't see the player through the doors. if tile_h in world_map or tile_h in blocked_doors: return False y += dy * TILE return True
def blocked_doors(self): """ All closed doors on the map :return: """ blocked_doors = Dict.empty(key_type=types.UniTuple(int32, 2), value_type=int32) for obj in self.list_of_objects: if obj.flag in {"door_h", "door_v"} and obj.blocked: i, j = mapping(obj.x, obj.y) blocked_doors[(i, j)] = 0 return blocked_doors