def raycasting(self): current_angle = self.player.angle - (self.player.fov / 2) current_angle %= 360 inc_angle = self.player.fov / self.width player_rad = calc.dg_to_rad(self.player.angle) for x in range(self.width): rad = calc.dg_to_rad(current_angle) cos = math.cos(rad) / self.precision sin = math.sin(rad) / self.precision level_x = self.player.x level_y = self.player.y tile = None while tile is None or not tile.solid: identifier = self.level.wall_map[math.floor(level_y)][ math.floor(level_x)] tile = self.level.get_tile_by_id(identifier) level_x += cos level_y += sin if self.minimap and self.minimap.show_ray_cast: self.minimap.set_pixel(level_x, level_y, self.minimap.ray_cast_color) # Calculate distance (Pythagoras) distance = calc.pythagoras(level_x, level_y, self.player.x, self.player.y) * self.tile_size # Fisheye fix distance = abs(math.cos(rad - player_rad) * distance) # Calculate wall height wall_height = self._calculate_wall_height(distance) # Render wall if tile.texture is not None: self._draw_textured_wall(x, wall_height, tile, level_x, level_y) else: self._draw_wall(x, wall_height, tile) # Render ceil if self.level.cast_ceil_map: self._draw_textured_ceil(x, wall_height) else: self._draw_ceil(x, wall_height) # Render floor if self.level.cast_floor_map or self.level.cast_ceil_map: self._draw_textured_floor_ceil(x, wall_height, rad) else: self._draw_floor(x, wall_height) current_angle += inc_angle current_angle %= 360
def move_back(self): cos = math.cos(calc.dg_to_rad(self.angle)) sin = math.sin(calc.dg_to_rad(self.angle)) newx = self.x - (cos * self.move_speed) newy = self.y - (sin * self.move_speed) half_dist = self.level.tile_size / 2 colx = self.x - (cos * (half_dist / self.level.tile_size)) coly = self.y - (sin * (half_dist / self.level.tile_size)) if not self.will_collide(colx, coly): self.x = newx self.y = newy
def _draw_textured_floor_ceil(self, x, wall_height, ray_rad): pr = calc.dg_to_rad(self.player.angle) cos = math.cos(ray_rad) sin = math.sin(ray_rad) start = math.floor(self.half_height + wall_height / 2) end = self.height for y in range(start, end): dist = (self.height / (2 * y - self.height)) dist = dist / math.cos(pr - ray_rad) pos_x = dist * cos pos_y = dist * sin pos_x += self.player.x pos_y += self.player.y if self.minimap and self.minimap.show_floor_cast: self.minimap.set_pixel(pos_x, pos_y, self.minimap.floor_cast_color) if self.level.cast_floor_map: floor_tile_id = self.level.get_floor_map_tile_by_coords( math.floor(pos_x), math.floor(pos_y)) floor_tile = self.level.get_tile_by_id(floor_tile_id) tx = math.floor(pos_x * floor_tile.texture.width) ty = math.floor(pos_y * floor_tile.texture.height) tex_width = floor_tile.texture.width tex_height = floor_tile.texture.height pixels = floor_tile.texture.pixels pixel = pixels[tx % tex_width, ty % tex_height] self._set_pixel(x, y, pixel) if self.level.cast_ceil_map: ceil_tile_id = self.level.get_ceil_map_tile_by_coords( math.floor(pos_x), math.floor(pos_y)) ceil_tile = self.level.get_tile_by_id(ceil_tile_id) tx = math.floor(pos_x * ceil_tile.texture.width) ty = math.floor(pos_y * ceil_tile.texture.height) tex_width = ceil_tile.texture.width tex_height = ceil_tile.texture.height pixels = ceil_tile.texture.pixels pixel = pixels[tx % tex_width, ty % tex_height] mirrored = self.height - y - 1 self._set_pixel(x, mirrored, pixel)
def _calculate_distance_projection_plane(self, half_width): return half_width / math.tan(calc.dg_to_rad(Player.DEFAULT_FOV) / 2)