diff --git a/__pycache__/eb_engine.cpython-314.pyc b/__pycache__/eb_engine.cpython-314.pyc index 27c024e..4c908b3 100644 Binary files a/__pycache__/eb_engine.cpython-314.pyc and b/__pycache__/eb_engine.cpython-314.pyc differ diff --git a/__pycache__/eb_objects.cpython-314.pyc b/__pycache__/eb_objects.cpython-314.pyc index 32348cb..32beb50 100644 Binary files a/__pycache__/eb_objects.cpython-314.pyc and b/__pycache__/eb_objects.cpython-314.pyc differ diff --git a/eb_engine.py b/eb_engine.py index d5cd630..94499ac 100644 --- a/eb_engine.py +++ b/eb_engine.py @@ -27,6 +27,7 @@ class Cell: item_obj: None = None creature_obj: None = None is_target: bool = False + render_offset: tuple = (0.0, 0.0) @dataclass class Map: @@ -36,7 +37,7 @@ class Map: cells: dict = field(default_factory = dict) color: str = "gray57" target_color: str = "gold" - size: int = 150 + cell_size: int = 150 bord: int = 3 scale: float = 1 cam_x: int = 0 @@ -88,8 +89,8 @@ class Map: """Возвращает индексы клетки (row, col) по позиции мыши или None если вне карты""" mx, my = mouse_pos # Переводим экранные координаты в координаты карты с учетом камеры и масштаба - map_x = (mx - self.cam_x * self.scale) / self.scale / self.size - map_y = (my - self.cam_y * self.scale) / self.scale / self.size + map_x = (mx - self.cam_x * self.scale) / self.scale / self.cell_size + map_y = (my - self.cam_y * self.scale) / self.scale / self.cell_size # Получаем индексы ближайшей клетки col = int(map_x) @@ -102,38 +103,65 @@ class Map: return (row, col) - def draw_map(self, screen, current_frame, grid = True): + def update_map(self, time_delta): + for j in range(len(self.cells)): + for cell in self.cells[j]: + if cell.creature_obj and cell.creature_obj.current_target: + cell.creature_obj.update(time_delta, self.cell_size, self) # self! + + + + def draw_map(self, screen, current_frame, grid=True): + terrain_list = [] + creature_list = [] + + # ★ 1 ПАСС: собираем terrain и creatures ★ for j in range(len(self.cells)): for i, cell in enumerate(self.cells[j]): - dd = {"x": int((i * self.size + self.cam_x) * self.scale), - "y": int((j * self.size + self.cam_y) * self.scale), - "w": int(self.size * self.scale - self.cell_dist), - "h": int(self.size * self.scale - self.cell_dist), - "spr_up": current_frame % self.sprites_refresh, - "sprites": self.sprites, "scale": self.scale, - "screen": screen} - - cell.terrain_obj.draw(dd) - - if cell.item_obj: - cell.item_obj.draw(dd) + base_x = i * self.cell_size + self.cam_x + base_y = j * self.cell_size + self.cam_y + # Terrain данные + terrain_dd = { + "x": int(base_x * self.scale), "y": int(base_y * self.scale), + "w": int(self.cell_size * self.scale - self.cell_dist), + "h": int(self.cell_size * self.scale - self.cell_dist), + "spr_up": current_frame % self.sprites_refresh, + "sprites": self.sprites, "scale": self.scale, "screen": screen + } + terrain_list.append((cell.terrain_obj, terrain_dd)) + + # Creature данные (если есть) if cell.creature_obj: - cell.creature_obj.draw(dd) - - if grid: - if cell.is_target: - pygame.draw.rect(screen, self.target_color, pygame.Rect(dd["x"], dd["y"], dd["w"], dd["h"]), self.bord) - else: - pygame.draw.rect(screen, self.color, pygame.Rect(dd["x"], dd["y"], dd["w"], dd["h"]), self.bord) - - def update_map(self, current_frame): + offset_x, offset_y = cell.creature_obj.render_offset + creature_dd = terrain_dd.copy() + creature_dd["x"] = int((base_x + offset_x) * self.scale) + creature_dd["y"] = int((base_y + offset_y) * self.scale) + creature_list.append((cell.creature_obj, creature_dd)) + + # ★ 2 ПАСС: рисуем terrain ★ + for obj, dd in terrain_list: + obj.draw(dd) + + # ★ 3 ПАСС: рисуем ВСЕХ creatures ПОСЛЕ terrain ★ + for obj, dd in creature_list: + obj.draw(dd) + + # ★ 4 ПАСС: grid поверх всего ★ for j in range(len(self.cells)): for i, cell in enumerate(self.cells[j]): - if cell.creature_obj is not None and len(cell.creature_obj.waypoints) > 1 and current_frame % 57 == 0: - del cell.creature_obj.waypoints[0] - self.move_obj("creature_obj", (j, i), (cell.creature_obj.waypoints[0])) - + base_x = i * self.cell_size + self.cam_x + base_y = j * self.cell_size + self.cam_y + grid_rect = pygame.Rect( + int(base_x * self.scale), int(base_y * self.scale), + int(self.cell_size * self.scale - self.cell_dist), + int(self.cell_size * self.scale - self.cell_dist) + ) + color = self.target_color if cell.is_target else self.color + pygame.draw.rect(screen, color, grid_rect, self.bord) + + + @dataclass class Engine: @@ -251,7 +279,7 @@ class Engine: global_counter = 0 global_counter_cap = 100000 - active_cell = [] + active_cell = None # profiling @@ -305,7 +333,7 @@ class Engine: # fill the screen with a color to wipe away anything from last frame #self.screen.fill("chartreuse4") self.screen.blit(background, (0, 0)) - easy_map.update_map(global_counter) + easy_map.update_map(time_delta) easy_map.draw_map(self.screen, current_frame + 1) manager.draw_ui(self.screen) @@ -330,25 +358,34 @@ class Engine: self.spr_scale -= self.scale_step self.scale_sprites() - if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: # Левая кнопка + if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: mouse_pos = pygame.mouse.get_pos() console_rect = console_window.get_abs_rect() if not console_rect.collidepoint(mouse_pos): cell_coords = easy_map.get_cell_at_mouse(mouse_pos) if cell_coords: - if active_cell: - easy_map.cells[active_cell[0]][active_cell[1]].is_target = False - active_cell = cell_coords - easy_map.cells[active_cell[0]][active_cell[1]].is_target = True + # Сбрасываем предыдущую цель + if active_cell is not None: + row, col = active_cell + if row in easy_map.cells and col < len(easy_map.cells[row]): + easy_map.cells[row][col].is_target = False + + active_cell = cell_coords # Теперь кортеж (row, col) + row, col = active_cell + easy_map.cells[row][col].is_target = True if event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: mouse_pos = pygame.mouse.get_pos() - cell_coords = easy_map.get_cell_at_mouse(mouse_pos) console_rect = console_window.get_abs_rect() - if not console_rect.collidepoint(mouse_pos) and easy_map.cells[active_cell[0]][active_cell[1]].creature_obj is not None: - easy_map.cells[active_cell[0]][active_cell[1]].creature_obj.move(easy_map.cells, (active_cell[0], active_cell[1]), (cell_coords[0], cell_coords[1])) - + if (not console_rect.collidepoint(mouse_pos) and + active_cell is not None and + easy_map.cells[active_cell[0]][active_cell[1]].creature_obj is not None): + cell_coords = easy_map.get_cell_at_mouse(mouse_pos) + if cell_coords: + print(f"Движение: {active_cell} -> {cell_coords}") + easy_map.cells[active_cell[0]][active_cell[1]].creature_obj.move( + easy_map.cells, active_cell, cell_coords) if keys[pygame.K_ESCAPE]: running = False @@ -364,6 +401,6 @@ class Engine: if global_counter % 10 == 0: current_fps = clock.get_fps() - print(f"Current FPS: {current_fps:.2f}") + #print(f"Current FPS: {current_fps:.2f}") pygame.quit() \ No newline at end of file diff --git a/eb_objects.py b/eb_objects.py index eaf6527..ef54ad9 100644 --- a/eb_objects.py +++ b/eb_objects.py @@ -36,12 +36,55 @@ class Creature(Object): tasks: list = field(default_factory = list) inventory: dict = field(default_factory = dict) - def update(self): - pass + move_progress: float = 0.0 # 0.0 = старт клетки, 1.0 = конец клетки + current_target: tuple = None # (row, col) следующая клетка + move_speed: float = 0.02 # пикселей/кадр (настройте) + render_offset: tuple = (0.0, 0.0) + start_pos: tuple = None # (row, col) начальная позиция сегмента пути + def move(self, cells, start, goal): from common import find_way - self.waypoints = find_way(cells, start, goal) + self.start_pos = start + path = find_way(cells, start, goal) + if path and len(path) > 1: + self.waypoints = path[1:] # Убираем текущую позицию + self.current_target = self.waypoints[0] + self.move_progress = 0.0 + self.start_pos = start # ★ ТУТ - текущая позиция как стартовая для первого шага ★ + self.render_offset = (0.0, 0.0) + + + def update(self, time_delta, cell_size, map_obj): + if self.current_target is None or not self.waypoints: + self.render_offset = (0.0, 0.0) + return + + self.move_progress += self.move_speed * time_delta * 60 + self.move_progress = min(self.move_progress, 1.0) + + if self.move_progress >= 1.0: + map_obj.move_obj('creature_obj', self.start_pos, self.current_target) + + self.waypoints.pop(0) + if self.waypoints: + self.start_pos = self.current_target # Новая клетка как старт + self.current_target = self.waypoints[0] + self.move_progress = 0.0 + self.render_offset = (0.0, 0.0) # ← ДОБАВИТЬ! + else: + self.current_target = None + self.render_offset = (0.0, 0.0) + return + + # ★ ТОЛЬКО интерполяция offset ★ + start_row, start_col = self.start_pos or (0, 0) + target_row, target_col = self.current_target + offset_x = (target_col - start_col) * cell_size * self.move_progress + offset_y = (target_row - start_row) * cell_size * self.move_progress + self.render_offset = (offset_x, offset_y) + + @dataclass