Сделал ещё одну очевидную оптимизацию - кэширование матриц препятствий, результат превзошёл всё ожидания. 300 объектов - плавные 60 фпс, 500 объектов - 60 фпс с микрофризами. Для масштабов игры этого уже более чем достаточно. Теперь следует добиться такого же для более слабых машин, надо выбрать минимальные системные требования.
This commit is contained in:
224
common.py
224
common.py
@@ -26,6 +26,12 @@ def path_exists(data, path):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def find_way(cells, start, goal, walkable, rocks_only):
|
||||||
|
result = bfs_quick(cells, start, goal, walkable, rocks_only)
|
||||||
|
return result
|
||||||
|
|
||||||
|
'''
|
||||||
#def find_way(cells, start, goal):
|
#def find_way(cells, start, goal):
|
||||||
# """Находит путь от start=(row, col) к goal=(row, col). row=y (строка), col=x (столбец)"""
|
# """Находит путь от start=(row, col) к goal=(row, col). row=y (строка), col=x (столбец)"""
|
||||||
# rows = len(cells)
|
# rows = len(cells)
|
||||||
@@ -289,8 +295,9 @@ def path_exists(data, path):
|
|||||||
#
|
#
|
||||||
# return path
|
# return path
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
def find_way(cells, start, goal):
|
def bfs_quick(cells, start, goal, walkable, rocks_only):
|
||||||
"""★СУПЕРБЫСТРЫЙ BFS: массивы вместо set/deque★"""
|
"""★СУПЕРБЫСТРЫЙ BFS: массивы вместо set/deque★"""
|
||||||
rows = len(cells)
|
rows = len(cells)
|
||||||
if rows == 0:
|
if rows == 0:
|
||||||
@@ -303,22 +310,22 @@ def find_way(cells, start, goal):
|
|||||||
|
|
||||||
if (s_row >= rows or s_col >= cols or
|
if (s_row >= rows or s_col >= cols or
|
||||||
g_row >= rows or g_col >= cols):
|
g_row >= rows or g_col >= cols):
|
||||||
print(f"Путь не найден: выход за границы {start} -> {goal}")
|
#print(f"Путь не найден: выход за границы {start} -> {goal}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# ★ МАТРИЦЫ вместо set (10x быстрее хэширования) ★
|
## ★ МАТРИЦЫ вместо set (10x быстрее хэширования) ★
|
||||||
walkable = [[True] * cols for _ in range(rows)]
|
#walkable = [[True] * cols for _ in range(rows)]
|
||||||
rocks_only = [[False] * cols for _ in range(rows)]
|
#rocks_only = [[False] * cols for _ in range(rows)]
|
||||||
start_creature = cells[s_row][s_col].creature_obj
|
#start_creature = cells[s_row][s_col].creature_obj
|
||||||
|
#
|
||||||
for r in range(rows):
|
#for r in range(rows):
|
||||||
for c in range(cols):
|
# for c in range(cols):
|
||||||
cell = cells[r][c]
|
# cell = cells[r][c]
|
||||||
if (cell.creature_obj and cell.creature_obj != start_creature) or \
|
# if (cell.creature_obj and cell.creature_obj != start_creature) or \
|
||||||
(cell.terrain_obj and cell.terrain_obj.sprite_name == "rock_small"):
|
# (cell.terrain_obj and cell.terrain_obj.sprite_name == "rock_small"):
|
||||||
walkable[r][c] = False
|
# walkable[r][c] = False
|
||||||
if cell.terrain_obj and cell.terrain_obj.sprite_name == "rock_small":
|
# if cell.terrain_obj and cell.terrain_obj.sprite_name == "rock_small":
|
||||||
rocks_only[r][c] = True
|
# rocks_only[r][c] = True
|
||||||
|
|
||||||
# ★ ВЫЧИСЛЯЕМЫЕ МАССИВЫ ★
|
# ★ ВЫЧИСЛЯЕМЫЕ МАССИВЫ ★
|
||||||
visited = [[False] * cols for _ in range(rows)]
|
visited = [[False] * cols for _ in range(rows)]
|
||||||
@@ -381,3 +388,190 @@ def can_move_diagonal(r, c, nr, nc, rocks_only, rows, cols):
|
|||||||
check2_ok = (0 <= r2 < rows and 0 <= c2 < cols and not rocks_only[r2][c2])
|
check2_ok = (0 <= r2 < rows and 0 <= c2 < cols and not rocks_only[r2][c2])
|
||||||
|
|
||||||
return check1_ok and check2_ok
|
return check1_ok and check2_ok
|
||||||
|
|
||||||
|
'''
|
||||||
|
#def bfs_quick_d(obstacle_matrix, start, goal):
|
||||||
|
# rows = len(obstacle_matrix)
|
||||||
|
# if rows == 0:
|
||||||
|
# print("❌ DEBUG: ПУСТАЯ МАТРИЦА")
|
||||||
|
# return None
|
||||||
|
#
|
||||||
|
# cols = len(obstacle_matrix[0])
|
||||||
|
# s_row, s_col = start
|
||||||
|
# g_row, g_col = goal
|
||||||
|
#
|
||||||
|
# print(f"🔍 DEBUG: start={start}, goal={goal}, размер={rows}x{cols}")
|
||||||
|
#
|
||||||
|
# if (s_row >= rows or s_col >= cols or
|
||||||
|
# g_row >= rows or g_col >= cols):
|
||||||
|
# print(f"❌ DEBUG: ВЫХОД ЗА ГРАНИЦЫ: start({s_row},{s_col}) goal({g_row},{g_col})")
|
||||||
|
# return None
|
||||||
|
#
|
||||||
|
# print(f"✅ DEBUG: Границы OK. obstacle[start]={obstacle_matrix[s_row][s_col]}, obstacle[goal]={obstacle_matrix[g_row][g_col]}")
|
||||||
|
#
|
||||||
|
# visited = [[False] * cols for _ in range(rows)]
|
||||||
|
# parent = [[None] * cols for _ in range(rows)]
|
||||||
|
#
|
||||||
|
# queue_size = 0
|
||||||
|
# queue = [[0, 0] for _ in range(rows * cols)]
|
||||||
|
# queue[0] = [s_row, s_col]
|
||||||
|
# queue_size = 1
|
||||||
|
# front = 0
|
||||||
|
#
|
||||||
|
# visited[s_row][s_col] = True
|
||||||
|
# print(f"✅ DEBUG: Старт добавлен в очередь. queue_size={queue_size}")
|
||||||
|
#
|
||||||
|
# directions = [(-1,0), (1,0), (0,-1), (0,1), (-1,-1), (-1,1), (1,-1), (1,1)]
|
||||||
|
#
|
||||||
|
# DEBUG_COUNTER = 0
|
||||||
|
#
|
||||||
|
# while front < queue_size:
|
||||||
|
# r, c = queue[front]
|
||||||
|
# front += 1
|
||||||
|
# DEBUG_COUNTER += 1
|
||||||
|
#
|
||||||
|
# print(f"🔄 DEBUG[{DEBUG_COUNTER}]: обрабатываем ({r},{c}), очередь={front}/{queue_size}")
|
||||||
|
#
|
||||||
|
# if r == g_row and c == g_col:
|
||||||
|
# print(f"✅ DEBUG: НАЙДЕН ЦЕЛЬ! Путь: ({r},{c})")
|
||||||
|
# path = []
|
||||||
|
# cr, cc = g_row, g_col
|
||||||
|
# while True:
|
||||||
|
# path.append((cr, cc))
|
||||||
|
# if parent[cr][cc] is None:
|
||||||
|
# break
|
||||||
|
# pr, pc = parent[cr][cc]
|
||||||
|
# cr, cc = pr, pc
|
||||||
|
# return path[::-1]
|
||||||
|
#
|
||||||
|
# for dr, dc in directions:
|
||||||
|
# nr, nc = r + dr, c + dc
|
||||||
|
#
|
||||||
|
# print(f" 📍 Проверяем соседа ({nr},{nc}): граница={0<=nr<rows and 0<=nc<cols}, "
|
||||||
|
# f"visited={visited[nr][nc]}, obstacle={obstacle_matrix[nr][nc]}")
|
||||||
|
#
|
||||||
|
# if (0 <= nr < rows and 0 <= nc < cols and
|
||||||
|
# not visited[nr][nc] and
|
||||||
|
# not obstacle_matrix[nr][nc]):
|
||||||
|
#
|
||||||
|
# diagonal_ok = True
|
||||||
|
# if dr * dc != 0:
|
||||||
|
# diagonal_ok = can_move_diagonal(r, c, nr, nc, obstacle_matrix)
|
||||||
|
# print(f" ↘️ Диагональ: {diagonal_ok}")
|
||||||
|
#
|
||||||
|
# if diagonal_ok:
|
||||||
|
# visited[nr][nc] = True
|
||||||
|
# parent[nr][nc] = (r, c)
|
||||||
|
# queue[queue_size] = [nr, nc]
|
||||||
|
# queue_size += 1
|
||||||
|
# print(f" ✅ Добавили ({nr},{nc}) в очередь. queue_size={queue_size}")
|
||||||
|
# else:
|
||||||
|
# print(f" ❌ Диагональ заблокирована!")
|
||||||
|
# else:
|
||||||
|
# print(f" ❌ Сосед отклонен!")
|
||||||
|
#
|
||||||
|
# print(f"❌ DEBUG: ОЧЕРЕДЬ ОПУСТЕЛА! Обработано {DEBUG_COUNTER} узлов")
|
||||||
|
# print(f" Последняя клетка в очереди: {queue[front-1] if front > 0 else 'ПУСТО'}")
|
||||||
|
# print(f" Цель ({g_row},{g_col}) помечена как visited? {visited[g_row][g_col]}")
|
||||||
|
# return None
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#def bfs_quick(obstacle_matrix, start, goal):
|
||||||
|
# """★СУПЕРБЫСТРЫЙ BFS 8-направлений★
|
||||||
|
# obstacle_matrix - ТОЛЬКО камни
|
||||||
|
# """
|
||||||
|
# rows = len(obstacle_matrix)
|
||||||
|
# if rows == 0:
|
||||||
|
# return None
|
||||||
|
#
|
||||||
|
# cols = len(obstacle_matrix[0])
|
||||||
|
# s_row, s_col = start
|
||||||
|
# g_row, g_col = goal
|
||||||
|
#
|
||||||
|
# if (s_row >= rows or s_col >= cols or
|
||||||
|
# g_row >= rows or g_col >= cols):
|
||||||
|
# return None
|
||||||
|
#
|
||||||
|
# # ★ МАТРИЦЫ состояния ★
|
||||||
|
# visited = [[False] * cols for _ in range(rows)]
|
||||||
|
# parent = [[None] * cols for _ in range(rows)]
|
||||||
|
#
|
||||||
|
# # ★ БЫСТРАЯ ОЧЕРЕДЬ ★
|
||||||
|
# queue_size = 0
|
||||||
|
# queue = [[0, 0] for _ in range(rows * cols)]
|
||||||
|
# queue[0] = [s_row, s_col]
|
||||||
|
# queue_size = 1
|
||||||
|
# front = 0
|
||||||
|
#
|
||||||
|
# visited[s_row][s_col] = True
|
||||||
|
#
|
||||||
|
# # ★ 8 НАПРАВЛЕНИЙ ★
|
||||||
|
# directions = [(-1,0), (1,0), (0,-1), (0,1), # Кардинальные (всегда)
|
||||||
|
# (-1,-1), (-1,1), (1,-1), (1,1)] # Диагональные
|
||||||
|
#
|
||||||
|
# while front < queue_size:
|
||||||
|
# r, c = queue[front]
|
||||||
|
# front += 1
|
||||||
|
#
|
||||||
|
# if r == g_row and c == g_col:
|
||||||
|
# # ★ Реконструкция пути ★
|
||||||
|
# path = []
|
||||||
|
# cr, cc = g_row, g_col
|
||||||
|
# while True:
|
||||||
|
# path.append((cr, cc))
|
||||||
|
# if parent[cr][cc] is None:
|
||||||
|
# break
|
||||||
|
# pr, pc = parent[cr][cc]
|
||||||
|
# cr, cc = pr, pc
|
||||||
|
# return path[::-1]
|
||||||
|
#
|
||||||
|
# for dr, dc in directions:
|
||||||
|
# nr, nc = r + dr, c + dc
|
||||||
|
#
|
||||||
|
# if not (0 <= nr < rows and 0 <= nc < cols):
|
||||||
|
# continue
|
||||||
|
# if visited[nr][nc] or obstacle_matrix[nr][nc]:
|
||||||
|
# continue
|
||||||
|
#
|
||||||
|
# diagonal_ok = True
|
||||||
|
# if dr * dc != 0:
|
||||||
|
# diagonal_ok = can_move_diagonal(r, c, nr, nc, obstacle_matrix)
|
||||||
|
# if diagonal_ok:
|
||||||
|
# visited[nr][nc] = True
|
||||||
|
# parent[nr][nc] = (r, c)
|
||||||
|
# queue[queue_size] = [nr, nc]
|
||||||
|
# queue_size += 1
|
||||||
|
#
|
||||||
|
# return None
|
||||||
|
'''
|
||||||
|
#def can_move_diagonal(r, c, nr, nc, obstacle_matrix):
|
||||||
|
# """Диагональ БЛОКИРУЕТСЯ только камнями по углам"""
|
||||||
|
# rows, cols = len(obstacle_matrix), len(obstacle_matrix[0])
|
||||||
|
# dr = nr - r
|
||||||
|
# dc = nc - c
|
||||||
|
#
|
||||||
|
# r1, c1 = r + dr, c # Вертикальная соседка
|
||||||
|
# r2, c2 = r, c + dc # Горизонтальная соседка
|
||||||
|
#
|
||||||
|
# check1_ok = (0 <= r1 < rows and 0 <= c1 < cols and not obstacle_matrix[r1][c1])
|
||||||
|
# check2_ok = (0 <= r2 < rows and 0 <= c2 < cols and not obstacle_matrix[r2][c2])
|
||||||
|
#
|
||||||
|
# return check1_ok and check2_ok
|
||||||
|
|
||||||
|
#def can_move_diagonal(r, c, nr, nc, obstacle_matrix):
|
||||||
|
# """Проверка диагонали с границами"""
|
||||||
|
# rows, cols = len(obstacle_matrix), len(obstacle_matrix[0])
|
||||||
|
# dr = nr - r
|
||||||
|
# dc = nc - c
|
||||||
|
#
|
||||||
|
# # ★ ПРОВЕРКА ГРАНИЦ ПОПЕРЕДУ ★
|
||||||
|
# r1, c1 = r + dr, c # вертикальная
|
||||||
|
# r2, c2 = r, c + dc # горизонтальная
|
||||||
|
#
|
||||||
|
# # Если УЖЕ за границей - False
|
||||||
|
# if not (0 <= r1 < rows and 0 <= c1 < cols):
|
||||||
|
# return False
|
||||||
|
# if not (0 <= r2 < rows and 0 <= c2 < cols):
|
||||||
|
# return False
|
||||||
|
#
|
||||||
|
# return not obstacle_matrix[r1][c1] and not obstacle_matrix[r2][c2]
|
||||||
@@ -11,7 +11,9 @@
|
|||||||
"name": "2",
|
"name": "2",
|
||||||
"sprite_name": "sword_default"
|
"sprite_name": "sword_default"
|
||||||
},
|
},
|
||||||
"creature_obj": {}
|
"creature_obj": {"id": "1",
|
||||||
|
"name": "2",
|
||||||
|
"sprite_name": "elf_watching"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"terrain_obj": {
|
"terrain_obj": {
|
||||||
@@ -20,7 +22,9 @@
|
|||||||
"sprite_name": "grass_small"
|
"sprite_name": "grass_small"
|
||||||
},
|
},
|
||||||
"item_obj": {},
|
"item_obj": {},
|
||||||
"creature_obj": {}
|
"creature_obj": {"id": "1",
|
||||||
|
"name": "2",
|
||||||
|
"sprite_name": "elf_watching"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"terrain_obj": {
|
"terrain_obj": {
|
||||||
|
|||||||
61
eb_engine.py
61
eb_engine.py
@@ -38,6 +38,8 @@ class Map:
|
|||||||
sprites: dict
|
sprites: dict
|
||||||
sprites_refresh: int = 60
|
sprites_refresh: int = 60
|
||||||
cells: dict = field(default_factory = dict)
|
cells: dict = field(default_factory = dict)
|
||||||
|
walkable_matrix: list = field(default_factory = list)
|
||||||
|
rocks_matrix: list = field(default_factory = list)
|
||||||
color: str = "gray57"
|
color: str = "gray57"
|
||||||
target_color: str = "gold"
|
target_color: str = "gold"
|
||||||
cell_size: int = 150
|
cell_size: int = 150
|
||||||
@@ -68,6 +70,15 @@ class Map:
|
|||||||
|
|
||||||
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):
|
def move_obj(self, type, start, goal):
|
||||||
"""Перемещает объект типа 'terrain_obj', 'item_obj' или 'creature_obj'
|
"""Перемещает объект типа 'terrain_obj', 'item_obj' или 'creature_obj'
|
||||||
из клетки start=(row, col) в goal=(row, col)"""
|
из клетки start=(row, col) в goal=(row, col)"""
|
||||||
@@ -114,10 +125,36 @@ class Map:
|
|||||||
return (row, col)
|
return (row, col)
|
||||||
|
|
||||||
def update_map(self, time_delta):
|
def update_map(self, time_delta):
|
||||||
|
self.compute_walkable_rocks()
|
||||||
for j in range(len(self.cells)):
|
for j in range(len(self.cells)):
|
||||||
for cell in self.cells[j]:
|
for cell in self.cells[j]:
|
||||||
if cell.creature_obj:
|
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):
|
# def draw_map(self, screen, current_frame, grid=True):
|
||||||
# terrain_list = []
|
# terrain_list = []
|
||||||
@@ -168,7 +205,6 @@ class Map:
|
|||||||
# color = self.target_color if cell.is_target else self.color
|
# color = self.target_color if cell.is_target else self.color
|
||||||
# pygame.draw.rect(screen, color, grid_rect, self.bord)
|
# pygame.draw.rect(screen, color, grid_rect, self.bord)
|
||||||
|
|
||||||
|
|
||||||
def draw_map(self, screen, current_frame, grid=True):
|
def draw_map(self, screen, current_frame, grid=True):
|
||||||
screen_rect = screen.get_rect()
|
screen_rect = screen.get_rect()
|
||||||
terrain_list = []
|
terrain_list = []
|
||||||
@@ -238,9 +274,6 @@ class Map:
|
|||||||
pygame.draw.rect(screen, color, grid_rect, self.bord)
|
pygame.draw.rect(screen, color, grid_rect, self.bord)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Engine:
|
class Engine:
|
||||||
sprites: dict = field(default_factory = dict)
|
sprites: dict = field(default_factory = dict)
|
||||||
@@ -328,14 +361,6 @@ class Engine:
|
|||||||
|
|
||||||
def main_loop(self):
|
def main_loop(self):
|
||||||
easy_map = Map("def_map.json", self.cached_sprites)
|
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 = pygame.Surface((1600, 800))
|
||||||
background.fill("chartreuse4")
|
background.fill("chartreuse4")
|
||||||
|
|
||||||
@@ -380,7 +405,12 @@ class Engine:
|
|||||||
col < len(easy_map.cells[row]) and
|
col < len(easy_map.cells[row]) and
|
||||||
easy_map.cells[row][col].creature_obj is None):
|
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_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)
|
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])
|
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)
|
cell_coords = easy_map.get_cell_at_mouse(mouse_pos)
|
||||||
if cell_coords:
|
if cell_coords:
|
||||||
#print(f"Движение: {active_cell} -> {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[0]][active_cell[1]].creature_obj.move(easy_map.cells, cell_coords)
|
||||||
easy_map.cells, cell_coords)
|
|
||||||
|
|
||||||
if keys[pygame.K_ESCAPE]:
|
if keys[pygame.K_ESCAPE]:
|
||||||
running = False
|
running = False
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ class Creature(Object):
|
|||||||
replan_counter: int = 0
|
replan_counter: int = 0
|
||||||
REPLAN_INTERVAL: int = 30000
|
REPLAN_INTERVAL: int = 30000
|
||||||
waypoints: list = field(default_factory = list)
|
waypoints: list = field(default_factory = list)
|
||||||
|
walkable_matrix: list = field(default_factory = list)
|
||||||
|
rocks_matrix: list = field(default_factory = list)
|
||||||
|
|
||||||
inventory: dict = field(default_factory = dict)
|
inventory: dict = field(default_factory = dict)
|
||||||
quick_actions: list = field(default_factory = list)
|
quick_actions: list = field(default_factory = list)
|
||||||
@@ -76,7 +78,7 @@ class Creature(Object):
|
|||||||
|
|
||||||
def replan(self, cells, pos):
|
def replan(self, cells, pos):
|
||||||
from common import find_way
|
from common import find_way
|
||||||
path = find_way(cells, pos, self.final_goal)
|
path = find_way(cells, pos, self.final_goal, self.walkable_matrix, self.rocks_matrix)
|
||||||
if path and len(path) > 1:
|
if path and len(path) > 1:
|
||||||
self.waypoints = path[1:]
|
self.waypoints = path[1:]
|
||||||
self.current_target = self.waypoints[0]
|
self.current_target = self.waypoints[0]
|
||||||
@@ -97,25 +99,37 @@ class Creature(Object):
|
|||||||
|
|
||||||
|
|
||||||
if self.current_target is None: return
|
if self.current_target is None: return
|
||||||
target_row, target_col = self.current_target
|
|
||||||
if (target_row in map_obj.cells and
|
#target_row, target_col = self.current_target
|
||||||
target_col < len(map_obj.cells[target_row])):
|
#if (target_row in map_obj.cells and
|
||||||
target_cell = map_obj.cells[target_row][target_col]
|
# target_col < len(map_obj.cells[target_row])):
|
||||||
if target_cell.creature_obj is not None:
|
# target_cell = map_obj.cells[target_row][target_col]
|
||||||
self.current_target = None
|
#if target_cell.creature_obj is not None:
|
||||||
self.waypoints.clear()
|
# self.current_target = None
|
||||||
self.render_offset = (0.0, 0.0)
|
# self.waypoints.clear()
|
||||||
self.replan(map_obj.cells, self.start_pos)
|
# self.render_offset = (0.0, 0.0)
|
||||||
return
|
# self.replan(map_obj.cells, self.start_pos)
|
||||||
|
# return
|
||||||
|
|
||||||
self.move_progress += self.move_speed * time_delta * 60
|
self.move_progress += self.move_speed * time_delta * 60
|
||||||
self.move_progress = min(self.move_progress, 1.0)
|
self.move_progress = min(self.move_progress, 1.0)
|
||||||
|
|
||||||
if self.move_progress >= 1.0:
|
if self.move_progress >= 1.0:
|
||||||
map_obj.move_obj('creature_obj', self.start_pos, self.current_target)
|
if (map_obj.move_obj('creature_obj', self.start_pos, self.current_target)):
|
||||||
self.grid_pos = self.current_target
|
self.grid_pos = self.current_target
|
||||||
|
else:
|
||||||
|
self.current_target = None
|
||||||
|
self.waypoints.clear()
|
||||||
|
self.render_offset = (0.0, 0.0)
|
||||||
|
#если в матрице не считаем объекты, то:
|
||||||
|
#добавляем клетку в матрицу, матрицу периодически чистим
|
||||||
|
#посчитать как дорого обходится просчёт матрицы
|
||||||
|
self.replan(map_obj.cells, self.start_pos)
|
||||||
|
#тут сделать красивый переход в одну из соседних клеток
|
||||||
|
return
|
||||||
|
|
||||||
if self.waypoints: self.waypoints.pop(0)
|
if self.waypoints: self.waypoints.pop(0)
|
||||||
|
|
||||||
if self.waypoints:
|
if self.waypoints:
|
||||||
self.start_pos = self.current_target
|
self.start_pos = self.current_target
|
||||||
self.current_target = self.waypoints[0]
|
self.current_target = self.waypoints[0]
|
||||||
@@ -141,7 +155,7 @@ class Creature(Object):
|
|||||||
def move(self, cells, goal):
|
def move(self, cells, goal):
|
||||||
from common import find_way
|
from common import find_way
|
||||||
self.final_goal = goal
|
self.final_goal = goal
|
||||||
path = find_way(cells, self.grid_pos, goal)
|
path = find_way(cells, self.grid_pos, self.final_goal, self.walkable_matrix, self.rocks_matrix)
|
||||||
if path and len(path) > 1:
|
if path and len(path) > 1:
|
||||||
self.waypoints = path[1:]
|
self.waypoints = path[1:]
|
||||||
self.current_target = self.waypoints[0]
|
self.current_target = self.waypoints[0]
|
||||||
@@ -171,6 +185,9 @@ class Creature(Object):
|
|||||||
#clear goal/wp
|
#clear goal/wp
|
||||||
|
|
||||||
def update(self, time_delta, cell_size, map_obj):
|
def update(self, time_delta, cell_size, map_obj):
|
||||||
|
self.walkable_matrix = map_obj.walkable_matrix
|
||||||
|
self.rocks_matrix = map_obj.rocks_matrix
|
||||||
|
|
||||||
#quick_actions? here?
|
#quick_actions? here?
|
||||||
#print(self.waypoints, self.final_goal, self.action_counter, self.task_counter)
|
#print(self.waypoints, self.final_goal, self.action_counter, self.task_counter)
|
||||||
if self.final_goal is not None:
|
if self.final_goal is not None:
|
||||||
|
|||||||
231
f.txt
Normal file
231
f.txt
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 54.35
|
||||||
|
Elves count: 500 - Current FPS: 57.14
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 58.14
|
||||||
|
Elves count: 500 - Current FPS: 54.95
|
||||||
|
Elves count: 500 - Current FPS: 61.35
|
||||||
|
Elves count: 500 - Current FPS: 58.14
|
||||||
|
Elves count: 500 - Current FPS: 61.73
|
||||||
|
Elves count: 500 - Current FPS: 45.87
|
||||||
|
Elves count: 500 - Current FPS: 54.35
|
||||||
|
Elves count: 500 - Current FPS: 58.48
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 58.48
|
||||||
|
Elves count: 500 - Current FPS: 50.51
|
||||||
|
Elves count: 500 - Current FPS: 55.25
|
||||||
|
Elves count: 500 - Current FPS: 52.36
|
||||||
|
Elves count: 500 - Current FPS: 53.76
|
||||||
|
Elves count: 500 - Current FPS: 52.36
|
||||||
|
Elves count: 500 - Current FPS: 49.02
|
||||||
|
Elves count: 500 - Current FPS: 61.73
|
||||||
|
Elves count: 500 - Current FPS: 57.80
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 54.95
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 60.24
|
||||||
|
Elves count: 500 - Current FPS: 61.73
|
||||||
|
Elves count: 500 - Current FPS: 44.05
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 54.05
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 49.50
|
||||||
|
Elves count: 500 - Current FPS: 56.18
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 57.47
|
||||||
|
Elves count: 500 - Current FPS: 34.13
|
||||||
|
Elves count: 500 - Current FPS: 48.54
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 60.24
|
||||||
|
Elves count: 500 - Current FPS: 57.14
|
||||||
|
Elves count: 500 - Current FPS: 56.50
|
||||||
|
Elves count: 500 - Current FPS: 50.00
|
||||||
|
Elves count: 500 - Current FPS: 60.98
|
||||||
|
Elves count: 500 - Current FPS: 59.88
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 43.10
|
||||||
|
Leak: 2232.0 KB per 1000 frames
|
||||||
|
Elves count: 500 - Current FPS: 50.25
|
||||||
|
Elves count: 500 - Current FPS: 41.67
|
||||||
|
Elves count: 500 - Current FPS: 57.80
|
||||||
|
Elves count: 500 - Current FPS: 45.25
|
||||||
|
Elves count: 500 - Current FPS: 49.50
|
||||||
|
Elves count: 500 - Current FPS: 58.48
|
||||||
|
Elves count: 500 - Current FPS: 56.18
|
||||||
|
Elves count: 500 - Current FPS: 52.63
|
||||||
|
Elves count: 500 - Current FPS: 49.02
|
||||||
|
Elves count: 500 - Current FPS: 57.47
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 56.18
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 60.24
|
||||||
|
Elves count: 500 - Current FPS: 57.47
|
||||||
|
Elves count: 500 - Current FPS: 60.61
|
||||||
|
Elves count: 500 - Current FPS: 60.61
|
||||||
|
Elves count: 500 - Current FPS: 46.30
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 54.35
|
||||||
|
Elves count: 500 - Current FPS: 59.17
|
||||||
|
Elves count: 500 - Current FPS: 54.95
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 48.08
|
||||||
|
Elves count: 500 - Current FPS: 41.49
|
||||||
|
Elves count: 500 - Current FPS: 54.35
|
||||||
|
Elves count: 500 - Current FPS: 56.50
|
||||||
|
Elves count: 500 - Current FPS: 60.24
|
||||||
|
Elves count: 500 - Current FPS: 61.35
|
||||||
|
Elves count: 500 - Current FPS: 59.17
|
||||||
|
Elves count: 500 - Current FPS: 50.25
|
||||||
|
Elves count: 500 - Current FPS: 60.98
|
||||||
|
Elves count: 500 - Current FPS: 52.63
|
||||||
|
Elves count: 500 - Current FPS: 57.80
|
||||||
|
Elves count: 500 - Current FPS: 54.05
|
||||||
|
Elves count: 500 - Current FPS: 51.28
|
||||||
|
Elves count: 500 - Current FPS: 52.08
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 61.73
|
||||||
|
Elves count: 500 - Current FPS: 54.05
|
||||||
|
Elves count: 500 - Current FPS: 59.17
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 50.51
|
||||||
|
Elves count: 500 - Current FPS: 51.28
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 60.61
|
||||||
|
Elves count: 500 - Current FPS: 51.28
|
||||||
|
Elves count: 500 - Current FPS: 60.98
|
||||||
|
Elves count: 500 - Current FPS: 57.47
|
||||||
|
Elves count: 500 - Current FPS: 52.63
|
||||||
|
Elves count: 500 - Current FPS: 50.00
|
||||||
|
Elves count: 500 - Current FPS: 59.88
|
||||||
|
Elves count: 500 - Current FPS: 54.95
|
||||||
|
Elves count: 500 - Current FPS: 58.14
|
||||||
|
Elves count: 500 - Current FPS: 45.45
|
||||||
|
Elves count: 500 - Current FPS: 52.91
|
||||||
|
Elves count: 500 - Current FPS: 32.57
|
||||||
|
Elves count: 500 - Current FPS: 29.07
|
||||||
|
Elves count: 500 - Current FPS: 45.25
|
||||||
|
Elves count: 500 - Current FPS: 30.03
|
||||||
|
Elves count: 500 - Current FPS: 45.66
|
||||||
|
Elves count: 500 - Current FPS: 43.86
|
||||||
|
Elves count: 500 - Current FPS: 38.91
|
||||||
|
Elves count: 500 - Current FPS: 35.97
|
||||||
|
Elves count: 500 - Current FPS: 34.01
|
||||||
|
Elves count: 500 - Current FPS: 44.84
|
||||||
|
Elves count: 500 - Current FPS: 36.63
|
||||||
|
Elves count: 500 - Current FPS: 39.84
|
||||||
|
Elves count: 500 - Current FPS: 42.55
|
||||||
|
Elves count: 500 - Current FPS: 31.65
|
||||||
|
Elves count: 500 - Current FPS: 30.96
|
||||||
|
Elves count: 500 - Current FPS: 37.59
|
||||||
|
Elves count: 500 - Current FPS: 39.53
|
||||||
|
Elves count: 500 - Current FPS: 45.87
|
||||||
|
Elves count: 500 - Current FPS: 37.31
|
||||||
|
Elves count: 500 - Current FPS: 35.34
|
||||||
|
Elves count: 500 - Current FPS: 39.22
|
||||||
|
Elves count: 500 - Current FPS: 47.17
|
||||||
|
Elves count: 500 - Current FPS: 39.37
|
||||||
|
Elves count: 500 - Current FPS: 25.25
|
||||||
|
Elves count: 500 - Current FPS: 35.97
|
||||||
|
Elves count: 500 - Current FPS: 48.54
|
||||||
|
Elves count: 500 - Current FPS: 44.64
|
||||||
|
Elves count: 500 - Current FPS: 43.67
|
||||||
|
Elves count: 500 - Current FPS: 28.17
|
||||||
|
Elves count: 500 - Current FPS: 35.97
|
||||||
|
Elves count: 500 - Current FPS: 31.06
|
||||||
|
Elves count: 500 - Current FPS: 47.62
|
||||||
|
Elves count: 500 - Current FPS: 37.59
|
||||||
|
Elves count: 500 - Current FPS: 42.19
|
||||||
|
Elves count: 500 - Current FPS: 50.25
|
||||||
|
Elves count: 500 - Current FPS: 35.59
|
||||||
|
Elves count: 500 - Current FPS: 45.45
|
||||||
|
Elves count: 500 - Current FPS: 45.45
|
||||||
|
Elves count: 500 - Current FPS: 28.65
|
||||||
|
Elves count: 500 - Current FPS: 24.15
|
||||||
|
Elves count: 500 - Current FPS: 42.55
|
||||||
|
Leak: 3284.0 KB per 1000 frames
|
||||||
|
Elves count: 500 - Current FPS: 42.19
|
||||||
|
Elves count: 500 - Current FPS: 35.09
|
||||||
|
Elves count: 500 - Current FPS: 42.19
|
||||||
|
Elves count: 500 - Current FPS: 51.55
|
||||||
|
Elves count: 500 - Current FPS: 32.36
|
||||||
|
Elves count: 500 - Current FPS: 39.22
|
||||||
|
Elves count: 500 - Current FPS: 35.59
|
||||||
|
Elves count: 500 - Current FPS: 28.57
|
||||||
|
Elves count: 500 - Current FPS: 22.73
|
||||||
|
Elves count: 500 - Current FPS: 31.85
|
||||||
|
Elves count: 500 - Current FPS: 26.74
|
||||||
|
Elves count: 500 - Current FPS: 24.94
|
||||||
|
Elves count: 500 - Current FPS: 22.08
|
||||||
|
Elves count: 500 - Current FPS: 24.51
|
||||||
|
Elves count: 500 - Current FPS: 34.97
|
||||||
|
Elves count: 500 - Current FPS: 30.40
|
||||||
|
Elves count: 500 - Current FPS: 47.62
|
||||||
|
Elves count: 500 - Current FPS: 40.16
|
||||||
|
Elves count: 500 - Current FPS: 55.87
|
||||||
|
Elves count: 500 - Current FPS: 33.78
|
||||||
|
Elves count: 500 - Current FPS: 50.00
|
||||||
|
Elves count: 500 - Current FPS: 50.51
|
||||||
|
Elves count: 500 - Current FPS: 33.00
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 61.35
|
||||||
|
Elves count: 500 - Current FPS: 51.02
|
||||||
|
Elves count: 500 - Current FPS: 54.35
|
||||||
|
Elves count: 500 - Current FPS: 50.51
|
||||||
|
Elves count: 500 - Current FPS: 53.19
|
||||||
|
Elves count: 500 - Current FPS: 53.76
|
||||||
|
Elves count: 500 - Current FPS: 39.37
|
||||||
|
Elves count: 500 - Current FPS: 49.50
|
||||||
|
Elves count: 500 - Current FPS: 60.24
|
||||||
|
Elves count: 500 - Current FPS: 47.17
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 60.61
|
||||||
|
Elves count: 500 - Current FPS: 56.50
|
||||||
|
Elves count: 500 - Current FPS: 58.48
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 52.36
|
||||||
|
Elves count: 500 - Current FPS: 57.47
|
||||||
|
Elves count: 500 - Current FPS: 61.73
|
||||||
|
Elves count: 500 - Current FPS: 60.61
|
||||||
|
Elves count: 500 - Current FPS: 39.06
|
||||||
|
Elves count: 500 - Current FPS: 51.55
|
||||||
|
Elves count: 500 - Current FPS: 56.82
|
||||||
|
Elves count: 500 - Current FPS: 59.52
|
||||||
|
Elves count: 500 - Current FPS: 54.64
|
||||||
|
Elves count: 500 - Current FPS: 54.95
|
||||||
|
Elves count: 500 - Current FPS: 56.50
|
||||||
|
Elves count: 500 - Current FPS: 52.63
|
||||||
|
Elves count: 500 - Current FPS: 59.17
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 58.82
|
||||||
|
Elves count: 500 - Current FPS: 55.87
|
||||||
|
Elves count: 500 - Current FPS: 48.08
|
||||||
|
Elves count: 500 - Current FPS: 60.24
|
||||||
|
Elves count: 500 - Current FPS: 51.55
|
||||||
|
Elves count: 500 - Current FPS: 58.14
|
||||||
|
Elves count: 500 - Current FPS: 57.14
|
||||||
|
Elves count: 500 - Current FPS: 47.85
|
||||||
|
Elves count: 500 - Current FPS: 50.00
|
||||||
|
Elves count: 500 - Current FPS: 47.62
|
||||||
|
Elves count: 500 - Current FPS: 56.18
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 53.48
|
||||||
|
Elves count: 500 - Current FPS: 52.91
|
||||||
|
Elves count: 500 - Current FPS: 60.98
|
||||||
|
Elves count: 500 - Current FPS: 57.14
|
||||||
|
Elves count: 500 - Current FPS: 34.60
|
||||||
|
Elves count: 500 - Current FPS: 41.84
|
||||||
|
Elves count: 500 - Current FPS: 59.88
|
||||||
|
Elves count: 500 - Current FPS: 49.75
|
||||||
|
Elves count: 500 - Current FPS: 47.62
|
||||||
|
Elves count: 500 - Current FPS: 50.51
|
||||||
|
Elves count: 500 - Current FPS: 35.97
|
||||||
|
Elves count: 500 - Current FPS: 57.47
|
||||||
|
Elves count: 500 - Current FPS: 55.56
|
||||||
|
Elves count: 500 - Current FPS: 45.25
|
||||||
|
Elves count: 500 - Current FPS: 35.59
|
||||||
4
plan.txt
4
plan.txt
@@ -20,3 +20,7 @@
|
|||||||
что одновременно может рендериться несколько карт;
|
что одновременно может рендериться несколько карт;
|
||||||
|
|
||||||
3. Оптимизация.
|
3. Оптимизация.
|
||||||
|
- проверяем, есть ли объект в клетке только перед непосредственным перемещением в ячейку
|
||||||
|
Cells, а не каждый calc_step; + (исправить визуальный баг, см комменты calc_step)
|
||||||
|
- перестаём учитывать объекты в алгоритме поиска пути; - (попробовать ещё раз, подумать)
|
||||||
|
- заранее передаем в алгоритм карту препятствий; +
|
||||||
Reference in New Issue
Block a user