, поэтому я работаю над небольшим roguelike-проектом и продолжаю сталкиваться с этой проблемой. Я попытался реализовать камеру с автопрокруткой, которая следит за игроком, когда он движется слишком далеко от середины экрана. Проблема в том, что в какой-то момент он становится глючным, и игрок обращается дважды. Ребята, можете ли вы помочь мне понять, в чем проблема? Я добавил его изображение и код, который (скорее всего) является корнем проблемы.
class Camera:
map_cell_width = constants.MAP_WIDTH / constants.CELL_WIDTH
map_cell_height = constants.MAP_HEIGHT / constants.CELL_HEIGHT
def __init__(self):
self._rect = pygame.Rect(0, 0, constants.CAMERA_WIDTH, constants.CAMERA_HEIGHT)
def update(self):
self.x = self.scrolling_map(config.PLAYER.x * constants.CELL_WIDTH, constants.CAMERA_WIDTH /2, constants.CAMERA_WIDTH , constants.MAP_WIDTH * constants.CELL_WIDTH)
self.y = self.scrolling_map(config.PLAYER.y * constants.CELL_HEIGHT, constants.CAMERA_HEIGHT /2, constants.CAMERA_HEIGHT, constants.MAP_HEIGHT * constants.CELL_HEIGHT)
@property
def x(self):
return self._rect.left
@property
def y(self):
return self._rect.top
@x.setter
def x(self, val):
self._rect.left = val
@y.setter
def y(self, val):
self._rect.top = val
@staticmethod
def scrolling_map(p, hs, s, m):
"""
Get the position of the camera in a scrolling map:
- p is the position of the player.
- hs is half of the screen size, and s is the full screen size.
- m is the size of the map.
"""
if p < hs:
return 0
elif p >= m - hs:
return m - s
else:
return p - hs
@property
def rect(self):
return self._rect
@property
def map_address(self):
x,y = self.rect.center
map_x = x / constants.CELL_WIDTH
map_y = y / constants.CELL_HEIGHT
return map_x, map_y
def win_to_map(self, coords):
tar_x, tar_y = coords
# convert window coords to distance from camera
cam_d_x, cam_d_y = self.cam_dist((tar_x, tar_y))
# distance from cam -> map cords
map_p_x = self.x + cam_d_x
map_p_y = self.y + cam_d_y
return map_p_x, map_p_y
def map_dist(self, coords):
new_x, new_y = coords
dist_x = new_x - self.x
dist_y = new_y - self.y
return dist_x, dist_y
def cam_dist(self, coords):
win_x, win_y = coords
dist_x = win_x - (self.rect.width / 2)
dist_y = win_y - (self.rect.height / 2)
return dist_x, dist_y
и
def draw_game():
# clear the surface
config.CAMERA.update()
#fill_surfaces()
config.GUI.update(None)
config.GUI.draw()
# draw the map
#######draw_map(config.GAME.current_map)
draw_mini_map(config.GAME.current_map)
for obj in sorted(config.GAME.current_objects, key=lambda x: x.depth, reverse=True):
obj.draw()
config.SURFACE_INFO.blit(config.SURFACE_MINI_MAP, (0,0))
config.SURFACE_MAIN.blit(config.SURFACE_INFO, (constants.CAMERA_WIDTH,0))
config.SURFACE_MAIN.blit(config.SURFACE_MAP, (0, 0), config.CAMERA.rect)
draw_map(config.GAME.current_map)
draw_debug()
draw_messages()
config.CONSOLE.draw()
def fill_surfaces():
config.SURFACE_MAIN.fill(constants.COLOR_DARK_GREY)
config.SURFACE_MAP.fill(constants.COLOR_DARK_GREY)
config.SURFACE_MINI_MAP.fill(constants.COLOR_BLACK)
config.SURFACE_INFO.fill(constants.COLOR_BLACK)
def draw_map(map_to_draw):
DISPLAY_MAP_W = constants.CAMERA_WIDTH / constants.CELL_WIDTH
DISPLAY_MAP_H = constants.CAMERA_HEIGHT / constants.CELL_HEIGHT
cam_x, cam_y = config.CAMERA.x / constants.CELL_WIDTH, config.CAMERA.y / constants.CELL_HEIGHT
render_w_min = int(cam_x - DISPLAY_MAP_W)
render_h_min = int(cam_y - DISPLAY_MAP_H)
render_w_max = int(cam_x + DISPLAY_MAP_W)
render_h_max = int(cam_y + DISPLAY_MAP_H)
render_w_min = max(0, render_w_min)
render_h_min = max(0, render_h_min)
render_w_max = min(constants.MAP_WIDTH, render_w_max)
render_h_max = min(constants.MAP_HEIGHT, render_h_max)
for x in range(render_w_min, render_w_max):
for y in range(render_h_min, render_h_max):
is_visible = config.FOV_MAP.fov[y, x]
if is_visible and not map_to_draw[x][y].explored:
map_to_draw[x][y].explored = True
if map_to_draw[x][y].explored:
if is_visible:
texture = map_to_draw[x][y].texture
else:
texture = map_to_draw[x][y].texture_explored
config.SURFACE_MAP.blit(config.ASSETS.tile_dict[texture],
(x * constants.CELL_WIDTH, y * constants.CELL_HEIGHT))