implementar modelo de Frames, para simplificar interface gráfica

cada area do ecra ira ter uma Frame, que tem informação sobre tamanho e
posicao dessa area relativamente à janela principal.
This commit is contained in:
2026-03-30 17:47:37 +01:00
parent 590ddab9ac
commit 7dca69aba4

View File

@ -2,6 +2,7 @@ import sys
import random import random
from types import NoneType from types import NoneType
import pygame as pg import pygame as pg
from modules import mapa
from modules.agente import Agente from modules.agente import Agente
from modules.mapa import Mapa from modules.mapa import Mapa
import modules.estrategia as ModEstrategia import modules.estrategia as ModEstrategia
@ -11,6 +12,73 @@ import modules.interaccoes as ModInteraccoes
# 0 para desactivar flags # 0 para desactivar flags
# pg.FULLSCREEN para fullscreen mode # pg.FULLSCREEN para fullscreen mode
flags = pg.FULLSCREEN flags = pg.FULLSCREEN
sep_janelas: int = 10
class Frame:
def __init__(
self,
tamanho_janela: tuple[int, int],
coord_posicao: tuple[int, int],
cor_fundo: pg.Color = pg.Color(0, 0, 0, 0),
):
self.tamanho = tamanho_janela
self.posicao = coord_posicao
self.surface = pg.Surface(self.tamanho)
self.cor = cor_fundo
def rect(self) -> pg.Rect:
return pg.Rect(self.posicao, self.tamanho)
def desenhar(self, dest: pg.Surface) -> None:
pg.draw.rect(dest, pg.Color(0, 0, 0, 0), self.rect())
pg.draw.rect(dest, self.cor, self.rect(), 5, border_radius=20)
def criarFrames(janela_app: pg.Surface) -> tuple[Frame, Frame, Frame, Frame]:
frame_mapa = Frame(
(
janela_app.get_size()[1] - (sep_janelas) * 2,
janela_app.get_size()[1] - (sep_janelas * 2),
),
(sep_janelas, sep_janelas),
pg.Color(255, 255, 0, 0),
)
frame_info_mapa = Frame(
(
janela_app.get_size()[0] - frame_mapa.tamanho[0] - (sep_janelas * 3),
(janela_app.get_size()[1] - (sep_janelas * 2)) // 2,
),
(frame_mapa.tamanho[0] + (sep_janelas * 2), sep_janelas),
pg.Color(0, 0, 255, 0),
)
frame_info_pos = Frame(
(
janela_app.get_size()[0] - frame_mapa.tamanho[0] - (sep_janelas * 3),
((frame_info_mapa.tamanho[1] * 2) // 3) - sep_janelas,
),
(
frame_mapa.tamanho[0] + (sep_janelas * 2),
frame_info_mapa.tamanho[1] + (sep_janelas * 2),
),
pg.Color(0, 255, 0, 0),
)
frame_accoes = Frame(
(
janela_app.get_size()[0] - frame_mapa.tamanho[0] - (sep_janelas * 3),
janela_app.get_size()[1]
- frame_info_mapa.tamanho[1]
- frame_info_pos.tamanho[1]
- (sep_janelas * 4),
),
(
frame_mapa.tamanho[0] + 20,
frame_info_mapa.tamanho[1] + frame_info_pos.tamanho[1] + 30,
),
pg.Color(255, 0, 0, 0),
)
return (frame_mapa, frame_info_mapa, frame_info_pos, frame_accoes)
def devolveCor(agente: Agente) -> tuple[int, int, int, int]: def devolveCor(agente: Agente) -> tuple[int, int, int, int]:
@ -30,10 +98,6 @@ def devolveCor(agente: Agente) -> tuple[int, int, int, int]:
return (0, 0, 0, 0) return (0, 0, 0, 0)
def criarJanelaInfo(surface: pg.Surface) -> None:
pass
def criarTabuleiro( def criarTabuleiro(
surface: pg.Surface, surface: pg.Surface,
mapa: Mapa, mapa: Mapa,
@ -109,6 +173,50 @@ def mostrarMapa(mapa: Mapa | None) -> None:
print("") print("")
def actualizarEstatisticas(
janela: pg.Surface, frame_info_mapa: Frame, mapa: Mapa
) -> None:
frame_info_mapa.desenhar(janela)
font = pg.font.Font(None, 20)
dict_estrat = prepararEstatistica(mapa)
n_linhas = 0
for strat in dict_estrat:
strat_label = font.render(
f"{strat}: {(dict_estrat[strat] / mapa.dimensao[0] ** 2) * 100:3.2f}",
False,
pg.Color(255, 255, 255, 0),
)
janela.blit(
strat_label,
(
frame_info_mapa.posicao[0] + (sep_janelas * 2),
frame_info_mapa.posicao[1] + (sep_janelas * 2) + (30 * n_linhas),
),
)
n_linhas += 1
def actualizarInfoPos(
janela: pg.Surface, frame: Frame, mapa: Mapa, pos: tuple[int, int]
) -> None:
# limpar frame_info_mapa
frame.desenhar(janela)
# mostrar informação sobre posicao seleccionada
font = pg.font.Font(None, 20)
info_posicao = font.render(
f"{mapa.posicao(pos).estrategia}@{pos}",
False,
pg.Color(255, 255, 255, 0),
)
janela.blit(
info_posicao,
(
frame.posicao[0] + (sep_janelas * 2),
frame.posicao[1] + (sep_janelas * 2),
),
)
def main(mapa: Mapa | None, tamanho_mapa: tuple[int, int]): def main(mapa: Mapa | None, tamanho_mapa: tuple[int, int]):
if isinstance(mapa, NoneType): if isinstance(mapa, NoneType):
raise TypeError("não foi passado mapa (tipo None)") raise TypeError("não foi passado mapa (tipo None)")
@ -118,10 +226,9 @@ def main(mapa: Mapa | None, tamanho_mapa: tuple[int, int]):
clock = pg.time.Clock() clock = pg.time.Clock()
running: bool = True running: bool = True
# cor1: tuple[int, int, int, int] = (255, 0, 0, 0)
# cor2: tuple[int, int, int, int] = (0, 255, 0, 0)
# mostrarMapa(mapa)
quadrado_seleccionado: pg.Rect | None = None quadrado_seleccionado: pg.Rect | None = None
# criar frames
frame_mapa, frame_info_mapa, frame_info_pos, frame_accoes = criarFrames(janela)
while running: while running:
if quadrado_seleccionado: if quadrado_seleccionado:
@ -172,22 +279,23 @@ def main(mapa: Mapa | None, tamanho_mapa: tuple[int, int]):
tamanho_quadrado, tamanho_quadrado,
tamanho_quadrado, tamanho_quadrado,
) )
# limpar janela de info
janela_info = pg.Surface((200, 200))
janela_info.fill(pg.Color(0, 0, 0, 0))
janela.blit(janela_info, (janela.get_size()[0] - 200, 500))
if quadrado_novo == quadrado_seleccionado: if quadrado_novo == quadrado_seleccionado:
quadrado_seleccionado = None quadrado_seleccionado = None
frame_info_pos.desenhar(janela)
else: else:
quadrado_seleccionado = quadrado_novo quadrado_seleccionado = quadrado_novo
agente = mapa.posicao((pos_x, pos_y)) agente = mapa.posicao((pos_x, pos_y))
print(f"{agente.posicao} com {agente.estrategia}") print(f"{agente.posicao} com {agente.estrategia}")
# desenhar mapa
frame_mapa.desenhar(janela)
criarTabuleiro(janela, mapa) criarTabuleiro(janela, mapa)
# criar surface para apresentar info # mostrar numero de iteração actual
criarJanelaInfo(janela)
# mostrar dimensão do mapa # mostrar dimensão do mapa
# mostrar estatisticas
actualizarEstatisticas(janela, frame_info_mapa, mapa)
# mostrar borda da posicao seleccionado com o rato # mostrar borda da posicao seleccionado com o rato
frame_info_pos.desenhar(janela)
if quadrado_seleccionado: if quadrado_seleccionado:
pg.draw.rect( pg.draw.rect(
janela, janela,
@ -196,34 +304,10 @@ def main(mapa: Mapa | None, tamanho_mapa: tuple[int, int]):
2, 2,
border_radius=20, border_radius=20,
) )
# limpar janela de info # actualizar info na frame_info_pos
info_janela = pg.Surface((200, 200)) actualizarInfoPos(janela, frame_info_pos, mapa, (pos_x, pos_y))
info_janela.fill(pg.Color(0, 0, 0, 0)) # mostrar frame accoes
janela.blit(info_janela, (janela.get_size()[0] - 200, 500)) frame_accoes.desenhar(janela)
# mostrar informação sobre posicao seleccionada
font = pg.font.Font(None, 20)
info_posicao = font.render(
f"{mapa.posicao((pos_x, pos_y)).estrategia}@{(pos_x, pos_y)}",
False,
pg.Color(255, 255, 255, 0),
)
janela.blit(info_posicao, (janela.get_size()[0] - 200, 500))
# mostrar numero de iteração actual
# mostrar estatisticas
janela_stats = pg.Surface((200, 200))
janela_stats.fill(pg.Color(0, 0, 0, 0))
janela.blit(janela_stats, (janela.get_size()[0] - 200, 10))
font = pg.font.Font(None, 20)
dict_estrat = prepararEstatistica(mapa)
n_linhas = 0
for strat in dict_estrat:
strat_label = font.render(
f"{strat}: {(dict_estrat[strat] / mapa.dimensao[0] ** 2) * 100:3.2f}",
False,
pg.Color(255, 255, 255, 0),
)
janela.blit(strat_label, (janela.get_size()[0] - 200, 10 + (30 * n_linhas)))
n_linhas += 1
pg.display.flip() pg.display.flip()
clock.tick(60) clock.tick(60)