Game Maker: Python com Pgzero para Crianças
Adicionando Múltiplos Atores e Inimigos
Aprenda sobre adicionando múltiplos atores e inimigos
🚀 Adicionando Múltiplos Atores e Inimigos
Olá, futuro Game Maker! 👋
Na aula anterior, aprendemos a criar um único ator e movê-lo pela tela. Mas e se quisermos ter vários inimigos? Ou muitos objetos coletáveis? Criar um por um seria muito trabalho e o código ficaria enorme! 🤯
Nesta aula prática, vamos aprender como gerenciar múltiplos atores de forma eficiente, usando uma das ferramentas mais poderosas do Python: as listas! Veremos como adicionar vários inimigos, fazê-los se mover e até reagir a colisões. Prepare-se para dar vida a um cenário de jogo mais dinâmico! ✨
1. 🎯 Introdução: O Poder das Listas para Atores
Imagine um jogo onde você precisa atirar em 100 alienígenas. Você não criaria 100 variáveis diferentes como alien1, alien2, ..., alien100, certo? Isso seria uma loucura! 🤪
É aí que as listas entram em cena. Uma lista é como uma caixa onde você pode guardar vários itens (neste caso, vários atores) e acessá-los facilmente. Com listas, podemos:
- Criar vários atores com poucas linhas de código.
- Desenhar todos eles na tela com um único loop.
- Mover todos eles ou fazer com que se comportem de forma independente.
- Verificar colisões entre o jogador e qualquer inimigo da lista.
Vamos começar a sujar as mãos! 💻
2. 🧑🏫 Explicação Detalhada com Exemplos
Para esta aula, vamos precisar de algumas imagens. Se você não as tem, pode criar arquivos simples com esses nomes ou usar imagens padrão do Pgzero se disponíveis na sua instalação. Por exemplo, você pode usar alien.png para os inimigos e player.png para o jogador. Certifique-se de que estão na pasta images do seu projeto.
2.1. Criando Múltiplos Inimigos com Listas
Primeiro, vamos criar uma lista vazia para guardar nossos inimigos. Depois, usaremos um loop para adicionar vários atores a essa lista.
# game.py
import pgzrun
import random
WIDTH = 800
HEIGHT = 600
# Nosso jogador
player = Actor('player', (WIDTH / 2, HEIGHT - 50))
# Lista para armazenar nossos inimigos
inimigos = []
# Função para criar um novo inimigo
def criar_inimigo():
x_pos = random.randint(50, WIDTH - 50) # Posição X aleatória
y_pos = random.randint(-200, -50) # Começa acima da tela
inimigo = Actor('alien', (x_pos, y_pos))
inimigo.velocidade = random.randint(1, 3) # Velocidade aleatória
return inimigo
# Vamos adicionar 5 inimigos à nossa lista
for _ in range(5): # O '_' é usado quando não precisamos da variável de iteração
inimigos.append(criar_inimigo())
# --- Funções de Jogo (draw e update) virão aqui ---
pgzrun.go()O que fizemos:
- Criamos uma lista vazia chamada
inimigos. - Criamos uma função
criar_inimigo()que retorna um novo ator 'alien' em uma posição e com uma velocidade aleatória. Isso torna fácil criar muitos inimigos com variações. - Usamos um loop
forpara chamarcriar_inimigo()5 vezes e adicionamos cada novo inimigo à nossa listainimigosusandoinimigos.append().
2.2. Desenhando Múltiplos Atores
Para desenhar todos os inimigos, precisamos percorrer a lista inimigos e chamar o método draw() para cada um deles.
# game.py (continuação)
# ... (código anterior) ...
def draw():
screen.clear() # Limpa a tela
player.draw() # Desenha o jogador
# Desenha todos os inimigos na lista
for inimigo in inimigos:
inimigo.draw()O que fizemos:
- Na função
draw(), depois de limpar a tela e desenhar o jogador, usamos um loopfor inimigo in inimigos: - Dentro do loop, chamamos
inimigo.draw()para cada inimigo na lista. Simples assim!
2.3. Movendo Múltiplos Atores e Reiniciando Posições
Agora, queremos que nossos inimigos se movam. Como cada inimigo tem sua própria velocidade (que definimos na função criar_inimigo), eles podem se mover de forma independente.
Também queremos que, quando um inimigo sair da tela por baixo, ele volte para cima para que o jogo continue.
# game.py (continuação)
# ... (código anterior) ...
def update():
# Movimento do jogador (exemplo, você pode ter o seu próprio)
if keyboard.left:
player.x -= 5
if keyboard.right:
player.x += 5
# Garante que o jogador não saia da tela
player.x = max(player.width / 2, min(WIDTH - player.width / 2, player.x))
# Move todos os inimigos
for inimigo in inimigos:
inimigo.y += inimigo.velocidade # Move o inimigo para baixo
# Se o inimigo sair da tela, reposiciona ele no topo
if inimigo.top > HEIGHT:
inimigo.bottom = 0 # Volta para o topo (ou um pouco acima)
inimigo.x = random.randint(50, WIDTH - 50) # Nova posição X aleatória
inimigo.velocidade = random.randint(1, 3) # Nova velocidade aleatóriaO que fizemos:
- Na função
update(), adicionamos um loopfor inimigo in inimigos:. - Dentro do loop, atualizamos a posição
yde cadainimigousando suainimigo.velocidade. - Verificamos se
inimigo.top > HEIGHT(se a parte de cima do inimigo passou da parte de baixo da tela). - Se sim, reposicionamos o inimigo no topo (
inimigo.bottom = 0), damos uma nova posiçãoxaleatória e uma nova velocidade.
2.4. Detecção de Colisão com Múltiplos Atores
A detecção de colisão é crucial para a interatividade do jogo. Queremos saber se o nosso player colidiu com qualquer um dos inimigos. O método colliderect() do Pgzero é perfeito para isso.
# game.py (continuação)
# ... (código anterior) ...
def update():
# ... (movimento do jogador e inimigos) ...
# Verifica colisão com cada inimigo
for inimigo in inimigos:
if player.colliderect(inimigo):
print("GAME OVER! Você colidiu com um inimigo!")
# Aqui você pode adicionar lógica de fim de jogo,
# como parar o jogo, exibir uma mensagem, etc.
# Por enquanto, vamos apenas reposicionar o inimigo que colidiu.
inimigo.bottom = 0
inimigo.x = random.randint(50, WIDTH - 50)
inimigo.velocidade = random.randint(1, 3)O que fizemos:
- Dentro do mesmo loop
for inimigo in inimigos:na funçãoupdate(), adicionamos uma verificaçãoif player.colliderect(inimigo):. - Se houver uma colisão, imprimimos uma mensagem e, para continuar o jogo, reposicionamos o inimigo que colidiu. Em um jogo real, isso poderia significar
game_over = Trueouplayer.lives -= 1.
3. 📄 Código de Exemplo Oficial (Adaptado)
O Pgzero não tem um exemplo "oficial" exato para múltiplos inimigos, mas a documentação enfatiza o uso de listas e loops, que é exatamente o que estamos fazendo. O código abaixo é uma compilação e adaptação dos conceitos da documentação para a nossa aula, usando as melhores práticas.
import pgzrun
import random
# --- Configurações do Jogo ---
WIDTH = 800
HEIGHT = 600
TITLE = "Ataque Alienígena!"
# --- Ator do Jogador ---
player = Actor('player', (WIDTH / 2, HEIGHT - 50)) # Certifique-se de ter 'player.png'
# --- Lista de Inimigos ---
inimigos = []
NUM_INIMIGOS = 7 # Quantos inimigos queremos
# --- Funções Auxiliares ---
def criar_inimigo():
"""Cria e retorna um novo ator inimigo com posição e velocidade aleatórias."""
x_pos = random.randint(50, WIDTH - 50)
y_pos = random.randint(-200, -50) # Começa acima da tela, invisível
inimigo = Actor('alien', (x_pos, y_pos)) # Certifique-se de ter 'alien.png'
inimigo.velocidade = random.randint(1, 4) # Velocidade entre 1 e 4
return inimigo
# --- Inicialização dos Inimigos ---
for _ in range(NUM_INIMIGOS):
inimigos.append(criar_inimigo())
# --- Funções de Jogo Principais ---
def draw():
"""Função de desenho: chamada a cada frame para desenhar tudo na tela."""
screen.clear() # Limpa a tela com preto
screen.fill((0, 0, 50)) # Ou preenche com uma cor azul escura para o espaço
player.draw() # Desenha o jogador
# Desenha todos os inimigos
for inimigo in inimigos:
inimigo.draw()
def update():
"""Função de atualização: chamada a cada frame para atualizar a lógica do jogo."""
# Movimento do jogador
if keyboard.left:
player.x -= 5
if keyboard.right:
player.x += 5
# Garante que o jogador não saia da tela
player.x = max(player.width / 2, min(WIDTH - player.width / 2, player.x))
# Atualiza e move todos os inimigos
for inimigo in inimigos:
inimigo.y += inimigo.velocidade # Move o inimigo para baixo
# Se o inimigo sair da tela, reposiciona-o no topo
if inimigo.top > HEIGHT:
inimigo.bottom = 0 # Volta para o topo
inimigo.x = random.randint(50, WIDTH - 50) # Nova posição X aleatória
inimigo.velocidade = random.randint(1, 4) # Nova velocidade aleatória
# Verifica colisão com o jogador
if player.colliderect(inimigo):
print("GAME OVER! Você colidiu com um inimigo!")
# Em um jogo real, você resetaria o jogo, diminuiria vidas, etc.
# Por enquanto, apenas reposicionamos o inimigo que colidiu.
inimigo.bottom = 0
inimigo.x = random.randint(50, WIDTH - 50)
inimigo.velocidade = random.randint(1, 4)
# --- Inicia o Jogo ---
pgzrun.go()Para executar este código:
- Salve-o como
game.pyem uma pasta. - Crie uma subpasta chamada
imagesdentro da mesma pasta. - Coloque duas imagens PNG lá:
player.pngealien.png. Podem ser imagens simples, como um quadrado para o player e um círculo para o alien, desde que tenham esses nomes. - Abra o terminal nessa pasta e execute
pgzrun game.py.
Você verá o jogador na parte inferior e vários alienígenas descendo do topo! Tente desviar deles. Se colidir, uma mensagem aparecerá no terminal, e o alienígena irá para o topo novamente.
4. 🧩 Exercícios/Desafios
Agora é a sua vez de praticar e expandir o jogo! Use o código acima como ponto de partida.
📝 Lista de Tarefas:
- Desafio 1: Aumentar a Dificuldade
- Aumente o número de inimigos (
NUM_INIMIGOS). - Faça os inimigos se moverem mais rápido (aumente o intervalo de
random.randintparainimigo.velocidade).
- Aumente o número de inimigos (
- Desafio 2: Inimigos que Disparam (Mais avançado)
- Crie uma nova lista chamada
balas_inimigas. - Em
update(), para cada inimigo, adicione uma chance aleatória (ex:if random.randint(0, 100) < 1:) de criar uma nova bala (um novoActorcom uma imagem de bala) e adicioná-la àbalas_inimigas. - Faça as balas se moverem para baixo.
- Em
draw(), desenhe todas asbalas_inimigas. - Verifique a colisão entre
playere cadabala_inimiga. Se houver colisão, remova a bala da lista e imprima "GAME OVER!". - Remova as balas da lista
balas_inimigasquando elas saírem da tela para não sobrecarregar o jogo.
- Crie uma nova lista chamada
- Desafio 3: Pontuação!
- Crie uma variável global
score = 0. - Quando o jogador desviar de um inimigo (ou seja, o inimigo sair da tela por baixo sem colidir), aumente o
scoreem 10 pontos. - Exiba a pontuação na tela usando
screen.draw.text(f"Pontuação: {score}", (10, 10), color="white")na funçãodraw().
- Crie uma variável global
- Desafio 4: Múltiplos Tipos de Inimigos
- Crie uma segunda imagem de inimigo (ex:
alien_red.png). - Na função
criar_inimigo(), userandom.choice(['alien', 'alien_red'])para escolher a imagem do inimigo aleatoriamente. - Dê velocidades diferentes para cada tipo de inimigo.
- Crie uma segunda imagem de inimigo (ex:
5. 📝 Resumo e Próximos Passos
Parabéns! 🎉 Você deu um grande passo para criar jogos mais complexos e dinâmicos.
Nesta aula, você aprendeu:
- Listas em Python: Como usar listas (
[]) para armazenar múltiplos objetos (atores). - Loops
for: Como iterar sobre listas para desenhar, mover e verificar colisões para cada ator. - Funções Auxiliares: Como criar funções como
criar_inimigo()para organizar seu código e facilitar a criação de novos elementos. - Detecção de Colisão: Como usar
colliderect()para verificar se o jogador colidiu com qualquer inimigo em uma lista.
Gerenciar múltiplos atores é uma habilidade fundamental em qualquer desenvolvimento de jogos. Com este conhecimento, suas possibilidades de criação são muito maiores!
No próximo módulo, vamos explorar como adicionar elementos de jogo mais interativos, como tiros do jogador, power-ups e talvez até um sistema de vidas! Prepare-se para mais ação! 🚀