Сделал ещё одну очевидную оптимизацию - кэширование матриц препятствий, результат превзошёл всё ожидания. 300 объектов - плавные 60 фпс, 500 объектов - 60 фпс с микрофризами. Для масштабов игры этого уже более чем достаточно. Теперь следует добиться такого же для более слабых машин, надо выбрать минимальные системные требования.
This commit is contained in:
63
eb_engine.py
63
eb_engine.py
@@ -38,6 +38,8 @@ class Map:
|
||||
sprites: dict
|
||||
sprites_refresh: int = 60
|
||||
cells: dict = field(default_factory = dict)
|
||||
walkable_matrix: list = field(default_factory = list)
|
||||
rocks_matrix: list = field(default_factory = list)
|
||||
color: str = "gray57"
|
||||
target_color: str = "gold"
|
||||
cell_size: int = 150
|
||||
@@ -66,7 +68,16 @@ class Map:
|
||||
final_cell.creature_obj = cell_classes[cell["creature_obj"]["sprite_name"]](**cell["creature_obj"])
|
||||
final_cell.creature_obj.grid_pos = (line, col)
|
||||
|
||||
self.cells[line].append(final_cell)
|
||||
self.cells[line].append(final_cell)
|
||||
|
||||
self.compute_walkable_rocks()
|
||||
for j in range(len(self.cells)):
|
||||
for cell in self.cells[j]:
|
||||
if cell.creature_obj:
|
||||
cell.creature_obj.walkable_matrix = self.walkable_matrix
|
||||
cell.creature_obj.rocks_matrix = self.rocks_matrix
|
||||
|
||||
|
||||
|
||||
def move_obj(self, type, start, goal):
|
||||
"""Перемещает объект типа 'terrain_obj', 'item_obj' или 'creature_obj'
|
||||
@@ -114,10 +125,36 @@ class Map:
|
||||
return (row, col)
|
||||
|
||||
def update_map(self, time_delta):
|
||||
self.compute_walkable_rocks()
|
||||
for j in range(len(self.cells)):
|
||||
for cell in self.cells[j]:
|
||||
if cell.creature_obj:
|
||||
cell.creature_obj.update(time_delta, self.cell_size, self) # self!
|
||||
cell.creature_obj.update(time_delta, self.cell_size, self)
|
||||
|
||||
def compute_walkable_rocks(self):
|
||||
"""Вычисляет матрицы walkable и rocks_only БЕЗ учета стартовой позиции"""
|
||||
rows = len(self.cells)
|
||||
if rows == 0:
|
||||
return None, None
|
||||
|
||||
cols = len(self.cells[0])
|
||||
|
||||
# ★ ИНИЦИАЛИЗАЦИЯ ★
|
||||
self.walkable_matrix = [[True] * cols for _ in range(rows)]
|
||||
self.rocks_matrix = [[False] * cols for _ in range(rows)]
|
||||
|
||||
# ★ ПОЛНЫЙ ПРОХОД ПО КАРТЕ ★
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
cell = self.cells[r][c]
|
||||
# Запрещаем ВСЕ существа (включая стартовое!)
|
||||
if cell.creature_obj or \
|
||||
(cell.terrain_obj and cell.terrain_obj.sprite_name == "rock_small"):
|
||||
self.walkable_matrix[r][c] = False
|
||||
|
||||
# Отмечаем маленькие камни
|
||||
if cell.terrain_obj and cell.terrain_obj.sprite_name == "rock_small":
|
||||
self.rocks_matrix[r][c] = True
|
||||
|
||||
# def draw_map(self, screen, current_frame, grid=True):
|
||||
# terrain_list = []
|
||||
@@ -168,7 +205,6 @@ class Map:
|
||||
# color = self.target_color if cell.is_target else self.color
|
||||
# pygame.draw.rect(screen, color, grid_rect, self.bord)
|
||||
|
||||
|
||||
def draw_map(self, screen, current_frame, grid=True):
|
||||
screen_rect = screen.get_rect()
|
||||
terrain_list = []
|
||||
@@ -238,9 +274,6 @@ class Map:
|
||||
pygame.draw.rect(screen, color, grid_rect, self.bord)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Engine:
|
||||
sprites: dict = field(default_factory = dict)
|
||||
@@ -328,14 +361,6 @@ class Engine:
|
||||
|
||||
def main_loop(self):
|
||||
easy_map = Map("def_map.json", self.cached_sprites)
|
||||
#print(easy_map.find_way((1, 1), (5, 5)))
|
||||
#print(easy_map.find_way((0, 0), (1, 1)))
|
||||
#print(easy_map.find_way((0, 0), (0, 1)))
|
||||
#print(easy_map.find_way((0, 0), (0, 0)))
|
||||
|
||||
#sp = eb_objects.Sprite(self.sprites, "elf_watching")
|
||||
#gr = pygame.image.load(file_path).convert_alpha()
|
||||
|
||||
background = pygame.Surface((1600, 800))
|
||||
background.fill("chartreuse4")
|
||||
|
||||
@@ -380,7 +405,12 @@ class Engine:
|
||||
col < len(easy_map.cells[row]) and
|
||||
easy_map.cells[row][col].creature_obj is None):
|
||||
|
||||
elf = eb_objects.Creature(id=f"elf_{random.randint(1000,9999)}", name="Elf", sprite_name="elf_watching", grid_pos = pos)
|
||||
elf = eb_objects.Creature(id=f"elf_{random.randint(1000,9999)}",
|
||||
name="Elf", sprite_name="elf_watching",
|
||||
grid_pos = pos,
|
||||
walkable_matrix = easy_map.walkable_matrix,
|
||||
rocks_matrix = easy_map.rocks_matrix)
|
||||
|
||||
r_move_short = eb_objects.Action(sprite_name="elf_watching", func=partial(elf.patrol, easy_map.cells, 3), duration=0.01)
|
||||
r_move_long = eb_objects.Action(sprite_name="elf_watching", func=partial(elf.move_rand, easy_map.cells, 0, 99), duration=0.01)
|
||||
elf.tasks.append([r_move_short]*5 + [r_move_long])
|
||||
@@ -514,8 +544,7 @@ class Engine:
|
||||
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, cell_coords)
|
||||
easy_map.cells[active_cell[0]][active_cell[1]].creature_obj.move(easy_map.cells, cell_coords)
|
||||
|
||||
if keys[pygame.K_ESCAPE]:
|
||||
running = False
|
||||
|
||||
Reference in New Issue
Block a user