Untitled
unknown
plain_text
10 months ago
3.0 kB
5
Indexable
-- Calcula a nova posição e direção do inimigo
novaPosicaoEDirecao :: Float -> (Int, Int) -> Mapa -> (Float, Float) -> Float -> ((Float, Float), (Float, Float))
novaPosicaoEDirecao dt destino mapa (xAtual, yAtual) velocidade =
let celulaAtual = (floor xAtual, floor yAtual) -- Célula onde o inimigo está
caminho = gerarCaminho celulaAtual destino mapa -- Calcula o caminho
in case caminho of
[] -> ((xAtual, yAtual), (0, 0)) -- Sem caminho, o inimigo não se move
(prox:_) -> -- Move em direção ao próximo quadrado no caminho
let (xProx, yProx) = centroCelula prox -- Centro da próxima célula
dx = xProx - xAtual
dy = yProx - yAtual
dist = sqrt (dx^2 + dy^2) -- Distância até o próximo ponto
vel = velocidade * dt -- Velocidade ajustada ao tempo
fator = min 1 (vel / dist) -- Garante que não ultrapassa
novaPos = if dist < 0.1
then centroCelula prox -- Chegou no centro da célula
else (xAtual + fator * dx, yAtual + fator * dy) -- Move em direção ao centro
direcao = if dist < 0.1
then (0, 0) -- Parado se já chegou no centro
else (dx / dist, dy / dist) -- Direção normalizada
in (novaPos, direcao)
-- Calcula o centro de uma célula do mapa
centroCelula :: (Int, Int) -> (Float, Float)
centroCelula (linha, coluna) =
(fromIntegral coluna + 0.5, fromIntegral linha + 0.5)
-- Gera o caminho usando BFS
gerarCaminho :: (Int, Int) -> (Int, Int) -> Mapa -> [(Int, Int)]
gerarCaminho inicio destino mapa =
bfs inicio destino mapa
-- BFS para calcular o caminho no mapa
bfs :: (Int, Int) -> (Int, Int) -> Mapa -> [(Int, Int)]
bfs inicio destino mapa = bfsAux [(inicio, [inicio])] [] destino mapa
where
bfsAux [] _ _ _ = [] -- Sem caminho possível
bfsAux ((atual, caminho):fila) visitados destino mapa
| atual == destino = reverse caminho -- Chegou ao destino
| atual `elem` visitados = bfsAux fila visitados destino mapa -- Ignorar visitados
| otherwise =
let vizinhosValidos = filter (ehCelulaValida mapa) (vizinhos atual)
novos = [(viz, viz:caminho) | viz <- vizinhosValidos, viz `notElem` visitados]
in bfsAux (fila ++ novos) (atual:visitados) destino mapa
-- Retorna os vizinhos de uma célula
vizinhos :: (Int, Int) -> [(Int, Int)]
vizinhos (linha, coluna) =
[(linha-1, coluna), (linha+1, coluna), (linha, coluna-1), (linha, coluna+1)] -- Norte, Sul, Oeste, Este
-- Verifica se uma célula é válida
ehCelulaValida :: Mapa -> (Int, Int) -> Bool
ehCelulaValida mapa (linha, coluna) =
linha >= 0 && linha < length mapa &&
coluna >= 0 && coluna < length (head mapa) &&
(mapa !! linha !! coluna == Relva) -- Apenas células de Relva são válidas
Editor is loading...
Leave a Comment