Pular para o conteúdo

Inteligência Artificial (A* e Visão)

Módulos: navigation, collision | Dificuldade: Avançado

Fazer um inimigo seguir o jogador é fácil (apenas subtrair X e Y). Mas fazer ele desviar de paredes num labirinto exige Algoritmos de Busca em Grafos. A Power PPlay 2.0 possui o algoritmo A* (A-Estrela) embutido no motor matemático, aliado ao Sensor de Raycasting.

1. Visão Computacional (Raycasting 2D)

O inimigo só deve te atacar se não houver um obstáculo entre vocês. O raycast lança uma linha imaginária entre dois pontos e retorna a primeira coisa que ele bater.

from PPlay.collision import Collision

# Origem, Destino e Lista de Obstáculos possíveis (paredes e player)
visto = Collision.raycast(
    inimigo.x, inimigo.y, 
    player.x, player.y, 
    mapa.get_solidos() + [player]
)

if visto == player:
    print("O inimigo te enxergou!")
elif visto in mapa.get_solidos():
    print("O inimigo está olhando para a parede.")

2. Navegação em Labirintos (A* Algorithm)

O método encontrar_caminho analisa o seu TileMap e retorna uma lista de coordenadas. O inimigo só precisa andar até o próximo ponto da lista.

from PPlay.navigation import Navigation
from PPlay.timer import Timer

caminho_ia =[]

def calcular_rota():
    global caminho_ia
    # A engine cuida da Heurística de Manhattan internamente
    caminho_ia = Navigation.encontrar_caminho(
        meu_mapa, 
        (inimigo.x, inimigo.y), 
        (player.x, player.y)
    )

# Agendamos o recálculo para 2 vezes por segundo (otimização de CPU)
Timer.every(0.5, calcular_rota)

while True:
    Timer.update()
    
    # Movimento Suave da IA (Steering)
    if len(caminho_ia) > 1:
        alvo = caminho_ia[1] # Próximo tile
        dx = alvo[0] - inimigo.x
        dy = alvo[1] - inimigo.y
        dist = math.hypot(dx, dy)
        
        # Se estiver perto do centro do bloco, pula pro próximo
        if dist > 2:
            inimigo.x += (dx/dist) * velocidade_ia * janela.delta_time()
            inimigo.y += (dy/dist) * velocidade_ia * janela.delta_time()
        else:
            caminho_ia.pop(0)
💡 Dica do Sênior: Tweens e Animações Matemáticas

Quer fazer um botão do menu deslizar suavemente para a tela com efeito “elástico”? Use o Tween! Ele muda um valor do ponto A ao ponto B em X segundos.

Tween.to(botao_jogar, "x", 400, duracao=1.0, tipo="bounce")
Lembre-se de colocar Tween.update() no seu loop principal!