Добавил ускоренный A* из библиотеки pathfinding - произволительность выросла, но несильно. Пока этот вариант закомментил, сейчас реализация BFS + walkable матрица, работает гораздо лучше, с неоптимальным рендером 100 объектов держит, без рендера 300.

This commit is contained in:
shiva404
2026-02-24 02:03:22 +03:00
parent a707638e09
commit 6b6ca341dc
9 changed files with 337 additions and 81 deletions

View File

@@ -1,4 +1,5 @@
from common import os, json, uuid, deepcopy, dataclass, field
from common import os, json, uuid, deepcopy, random
from common import dataclass, field
from common import pygame, pygame_gui
import eb_objects
import eb_terrain_objects
@@ -68,6 +69,9 @@ class Map:
def move_obj(self, type, start, goal):
"""Перемещает объект типа 'terrain_obj', 'item_obj' или 'creature_obj'
из клетки start=(row, col) в goal=(row, col)"""
if goal is None:
return False
s_y, s_x = start
d_y, d_x = goal
@@ -79,8 +83,9 @@ class Map:
source_cell = self.cells[s_y][s_x]
dest_cell = self.cells[d_y][d_x]
obj = getattr(source_cell, type)
check = getattr(dest_cell, type)
if obj is None:
if obj is None or check is not None:
return False
setattr(source_cell, type, None)
@@ -287,6 +292,11 @@ class Engine:
gc.collect()
mem_before = process.memory_info().rss / 1024
NUM_ELVES = 1000
elf_count = 0
while running:
time_delta = clock.tick(60)/1000.0
#pygame.event.clear()
@@ -301,6 +311,19 @@ class Engine:
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEWHEEL:
scroll_y = event.y
if scroll_y > 0:
easy_map.scale += self.scale_step * 5
self.spr_scale += self.scale_step * 5
self.scale_sprites()
elif scroll_y < 0 and easy_map.scale >= self.scale_step:
easy_map.scale -= self.scale_step * 5
self.spr_scale -= self.scale_step * 5
self.scale_sprites()
if event.type == pygame_gui.UI_TEXT_ENTRY_FINISHED and event.ui_element == input_entry:
user_text = input_entry.get_text()
exec(user_text)
@@ -349,15 +372,44 @@ class Engine:
if keys[pygame.K_d]:
easy_map.cam_x -= self.camera_step
if keys[pygame.K_q]:
easy_map.scale += self.scale_step
self.spr_scale += self.scale_step
self.scale_sprites()
if keys[pygame.K_e] and easy_map.scale >= self.scale_step:
easy_map.scale -= self.scale_step
self.spr_scale -= self.scale_step
self.scale_sprites()
#if keys[pygame.K_q]:
# easy_map.scale += self.scale_step
# self.spr_scale += self.scale_step
# self.scale_sprites()
#if keys[pygame.K_e] and easy_map.scale >= self.scale_step:
# easy_map.scale -= self.scale_step
# self.spr_scale -= self.scale_step
# self.scale_sprites()
if keys[pygame.K_SPACE] and elf_count < NUM_ELVES:
# Находим свободные клетки
# ★ МАССОВЫЙ СПАВН 50 эльфов ★
free_cells = []
for j in range(len(easy_map.cells)): # ★ ЛИМИТ строк ★
for i in range(len(easy_map.cells[j])): # ★ ЛИМИТ колонок ★
cell = easy_map.cells[j][i]
if (cell.creature_obj is None and
cell.terrain_obj and
cell.terrain_obj.sprite_name == "grass_small"):
free_cells.append((j, i))
spawn_count = min(50, len(free_cells)) # ★ Не больше свободных клеток ★
for _ in range(spawn_count):
row, col = random.choice(free_cells)
elf = eb_objects.Creature(id=f"elf_{random.randint(1000,9999)}", name="Elf", sprite_name="elf_watching")
easy_map.cells[row][col].creature_obj = elf
# ★ БЕЗОПАСНЫЙ выбор цели ★
possible_targets = [c for c in free_cells if c != (row, col)]
if possible_targets:
target_cell = random.choice(possible_targets)
elf.move(easy_map.cells, (row, col), target_cell)
free_cells.remove((row, col)) # Убираем занятые клетки
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
mouse_pos = pygame.mouse.get_pos()
console_rect = console_window.get_abs_rect()