Game Maker: Python com Pgzero para Crianças
Colisões entre Múltiplos Objetos
Aprenda sobre colisões entre múltiplos objetos
Colisões entre Múltiplos Objetos
Olá, futuro Game Maker! 👋
Nesta aula, vamos dar um passo gigantesco na criação de jogos interativos: aprender a detectar colisões! Saber quando dois objetos se tocam é fundamental para qualquer jogo, seja para coletar itens, derrotar inimigos ou saber quando o jogador perdeu.
Vamos mergulhar de cabeça e fazer nossos jogos reagirem ao mundo! 🚀
1. Introdução: O Toque Mágico dos Jogos ✨
Até agora, aprendemos a criar objetos, movê-los e até controlá-los. Mas o que acontece quando seu personagem encontra um monstro? Ou quando ele pega uma moeda? Sem a detecção de colisões, nada! Os objetos simplesmente passariam um pelo outro.
A detecção de colisão é o que permite que seu jogo saiba quando dois objetos estão se sobrepondo, ou seja, "se tocando". O Pgzero torna isso super fácil com algumas funções mágicas que vamos explorar.
2. Entendendo e Lidando com Colisões 💥
Em Pgzero, cada Actor (ator) possui um "retângulo" invisível ao seu redor, que é usado para verificar se ele está tocando outro ator. Pense como uma "caixa de colisão".
Como o Pgzero Detecta Colisões?
-
actor.colliderect(outro_ator): Esta é a função mais comum e útil! Ela verifica se o retângulo doactorestá se sobrepondo ao retângulo dooutro_ator. Se estiverem se tocando, ela retornaTrue(Verdadeiro); caso contrário, retornaFalse(Falso).if meu_jogador.colliderect(meu_inimigo): print("Game Over!") -
actor.collidepoint(x, y): Esta função verifica se um ponto específico (com coordenadasxey) está dentro do retângulo doactor. É útil para detectar cliques do mouse em um ator, por exemplo.if botao.collidepoint(mouse_x, mouse_y): print("Botão clicado!")
Lidando com Múltiplos Objetos
Em um jogo real, você raramente terá apenas um inimigo ou uma moeda. Você terá listas de inimigos, listas de moedas, listas de tiros, etc. Para verificar colisões entre múltiplos objetos, usaremos laços for.
Exemplo: Se você tem uma lista de inimigos, você precisará verificar se o jogador colidiu com cada um deles.
for inimigo in lista_de_inimigos:
if jogador.colliderect(inimigo):
print("Você foi atingido por um inimigo!")
# Faça algo, como diminuir a vida do jogador ou reiniciar o jogoRemovendo Objetos Após Colisão:
Quando seu jogador coleta uma moeda, a moeda deve desaparecer. Quando um tiro atinge um inimigo, ambos devem desaparecer. Remover objetos de uma lista enquanto você a itera pode ser um pouco complicado. Uma maneira segura e fácil para começar é criar uma nova lista apenas com os objetos que não colidiram.
# Exemplo: Coletando moedas
novas_moedas = []
for moeda in lista_de_moedas:
if jogador.colliderect(moeda):
print("Moeda coletada!")
score += 1 # Aumenta a pontuação
# Não adicionamos a moeda coletada à novas_moedas, então ela "desaparece"
else:
novas_moedas.append(moeda) # A moeda não colidiu, então ela continua no jogo
lista_de_moedas = novas_moedas # A lista original agora é a nova lista (sem as moedas coletadas)3. Código de Exemplo Oficial (Pgzero) 🎮
Vamos criar um pequeno jogo onde um alienígena (jogador) pode se mover, coletar moedas e deve evitar insetos (inimigos).
import pgzrun
import random
# --- Configurações da Janela ---
WIDTH = 800
HEIGHT = 600
TITLE = "Colisões Malucas!"
# --- Variáveis do Jogo ---
player = Actor('alien', (WIDTH // 2, HEIGHT - 50)) # Nosso jogador alienígena
player_speed = 5
score = 0
game_over = False
# Lista de inimigos (insetos)
enemies = []
num_enemies = 5
for _ in range(num_enemies):
x = random.randint(50, WIDTH - 50)
y = random.randint(50, HEIGHT // 2)
enemies.append(Actor('bug', (x, y)))
# Lista de moedas
coins = []
num_coins = 3
for _ in range(num_coins):
x = random.randint(50, WIDTH - 50)
y = random.randint(50, HEIGHT - 100)
coins.append(Actor('coin', (x, y)))
# --- Funções do Jogo ---
def draw():
screen.clear()
screen.fill((0, 0, 50)) # Fundo azul escuro
if game_over:
screen.draw.text("GAME OVER!", center=(WIDTH // 2, HEIGHT // 2 - 50), color="red", fontsize=80)
screen.draw.text(f"Pontuação Final: {score}", center=(WIDTH // 2, HEIGHT // 2 + 20), color="white", fontsize=40)
screen.draw.text("Pressione R para Reiniciar", center=(WIDTH // 2, HEIGHT // 2 + 80), color="yellow", fontsize=30)
else:
player.draw()
for enemy in enemies:
enemy.draw()
for coin in coins:
coin.draw()
screen.draw.text(f"Pontuação: {score}", (10, 10), color="white", fontsize=30)
def update():
global score, game_over
if game_over:
return # Se o jogo acabou, não atualiza mais nada
# Movimento do jogador
if keyboard.left:
player.x -= player_speed
if keyboard.right:
player.x += player_speed
if keyboard.up:
player.y -= player_speed
if keyboard.down:
player.y += player_speed
# Limitar o jogador dentro da tela
player.left = max(0, player.left)
player.right = min(WIDTH, player.right)
player.top = max(0, player.top)
player.bottom = min(HEIGHT, player.bottom)
# Movimento dos inimigos (simples, descendo)
for enemy in enemies:
enemy.y += 1 # Inimigo desce lentamente
if enemy.y > HEIGHT: # Se o inimigo sair da tela, reposiciona ele em cima
enemy.y = 0
enemy.x = random.randint(50, WIDTH - 50)
# --- Detecção de Colisões ---
# Colisão: Jogador vs Inimigo
for enemy in enemies:
if player.colliderect(enemy):
game_over = True # O jogo acaba se o jogador colidir com um inimigo
# Colisão: Jogador vs Moeda
novas_moedas = []
for coin in coins:
if player.colliderect(coin):
score += 1 # Aumenta a pontuação
sounds.collect.play() # Toca um som (você precisaria de um arquivo collect.ogg ou .wav)
else:
novas_moedas.append(coin) # Mantém a moeda se não foi coletada
coins = novas_moedas # Atualiza a lista de moedas
# Se todas as moedas foram coletadas, adiciona novas
if not coins:
for _ in range(num_coins):
x = random.randint(50, WIDTH - 50)
y = random.randint(50, HEIGHT - 100)
coins.append(Actor('coin', (x, y)))
def on_key_down(key):
global game_over, score, player, enemies, coins
if game_over and key == keys.R:
# Reinicia o jogo
game_over = False
score = 0
player.pos = (WIDTH // 2, HEIGHT - 50)
enemies = []
for _ in range(num_enemies):
x = random.randint(50, WIDTH - 50)
y = random.randint(50, HEIGHT // 2)
enemies.append(Actor('bug', (x, y)))
coins = []
for _ in range(num_coins):
x = random.randint(50, WIDTH - 50)
y = random.randint(50, HEIGHT - 100)
coins.append(Actor('coin', (x, y)))
pgzrun.go()Para rodar este código:
- Salve-o como
jogo_colisoes.py. - Crie uma pasta chamada
imagesno mesmo diretório. - Baixe as imagens
alien.png,bug.pngecoin.png(ou crie as suas próprias com esses nomes) e coloque-as na pastaimages. Você pode usar imagens simples de 32x32 ou 64x64 pixels. - (Opcional) Crie uma pasta
soundse adicione um arquivocollect.oggoucollect.wavpara o som de coleta. - Execute no terminal:
pgzrun jogo_colisoes.py
4. Exercícios e Desafios (Prática!) 🧑💻
Agora é a sua vez de colocar a mão na massa! Use o código acima como base e modifique-o para adicionar novas funcionalidades.
Tarefas:
- Aumentar Dificuldade: Aumente o número inicial de inimigos (
num_enemies) para 10. - Velocidade dos Inimigos: Faça os inimigos descerem mais rápido. Altere a linha
enemy.y += 1paraenemy.y += random.randint(1, 3)para dar uma velocidade aleatória a cada um. - Contador de Vidas: Em vez de
game_over = Trueimediatamente, crie uma variávellives = 3. A cada colisão com um inimigo, diminualivesem 1. O jogo só termina quandoliveschegar a 0. Não se esqueça de mostrar as vidas na tela! - Efeito de Colisão: Quando o jogador colide com um inimigo, além de perder uma vida, faça o jogador piscar por um curto período (ex:
player.image = 'alien_hit'por 0.5 segundos e depois volta paraalien) ou o reposicione em um local seguro. - Desafio Extra: Tiros! 🔫
- Crie uma lista
bullets = []. - Quando a tecla
space(espaço) for pressionada (on_key_down), adicione um novoActor(um tiro, comobullet.png) à listabullets, começando na posição do jogador. - Na função
update(), faça os tiros se moverem para cima (bullet.y -= bullet_speed). - Implemente a colisão entre
bulletseenemies:- Se um
bullet.colliderect(enemy), ambos devem ser removidos de suas respectivas listas. (Lembre-se da técnica de criar novas listas para remover objetos de forma segura!) - Adicione um som de tiro e um som de explosão quando o inimigo for atingido.
- Se um
- Crie uma lista
5. Resumo e Próximos Passos 🏁
Parabéns! Você dominou a detecção de colisões, uma habilidade essencial para qualquer desenvolvedor de jogos.
Nesta aula, você aprendeu:
- A importância da detecção de colisões para a interatividade do jogo.
- Como usar
actor.colliderect()para verificar se dois atores se tocam. - Como usar
actor.collidepoint()para verificar se um ponto toca um ator. - A gerenciar colisões entre múltiplos objetos usando listas e laços
for. - Uma técnica segura para remover objetos de listas após uma colisão.
Continue experimentando com as colisões! Pense em como você pode usá-las para:
- Abrir portas quando o jogador toca em uma chave.
- Ativar power-ups quando o jogador os coleta.
- Criar áreas seguras ou perigosas.
Na próxima aula, vamos explorar como adicionar sons e músicas aos nossos jogos, tornando-os ainda mais imersivos! 🎶
Até lá, divirta-se criando suas próprias interações de colisão! ✨