Adicionando Obstáculo - Criando o Meteoro
No capítulo anterior, aprendemos a mover a nave usando o teclado e impedir que ela ultrapassasse os limites da janela.
A nave se move. Os limites estão definidos. Mas até agora o jogador não tem nenhuma ameaça para desviar. O espaço está vazio. É hora de povoá-lo
Neste capítulo vamos prepara o meteoro pára ser criado infinitamente durante o jogo.
Ao longo deste capítulo você aprenderá a:
- Rotacionar imagens
- Gerar números aleatórios
- Centralizar imagens
Vamos começar criando a estrutura do meteoro.
Criando o Meteoro
Utilizando as imagens baixadas no capítulo onde criamos a nave. Escolha 1 meteoro e salve na pasta
imgdo projeto.
Seguindo a mesma estrutura criada no capítulo de criação da nave, agora vamos criar o meteoro:
meteoro_img = pygame.image.load("img/meteoro.png") meteoro = { "imagem": meteoro_img, "x": 100, "y": 100, "velocidade": 2, "rotacao": 0 }
Adicionamos uma informação a mais para o meteoro que armazena sua rotação. Vamos usá-la para girar a imagem do meteoro.
Com a estrutura do meteoro pronta, vamos desenhá-lo da mesma forma que desenhamos a nave.
janela.blit(meteoro["imagem"], (meteoro["x"], meteoro["y"]))
Como resultado, ao executar o jogo você verá o meteoro na tela.

Agora que o meteoro é exibido na tela. Vamos fazer com que ele gire para uma direção aleatória.
Adicionando Rotação ao Meteoro
Para rotacionar o meteoro, precisamos definir para qual direção ele irá girar.
Para isso vamos usar a biblioteca Python chamada random. Então vamos importá-la no inicio do código.
import random
Com isso podemos definir a direção da rotação usando a função random.randint() na estrutura do meteoro.
meteoro = { "imagem": meteoro_img, "x": 100, "y": 100, "velocidade": 2, "rotacao": 0, "dir_rotacao": random.randint(-1, 1) }
A função
random.randint()gera um número aleatório entre uma faixa de valores.Por exemplo, se queremos gerar um número aleatório entre
0e10usamos:random.randint(0, 10)
Definimos a direção da rotação com valor aleatório entre -1 e 1.
- Se o valor gerado for
-1ele gira para a esquerda - Se o valor gerado for
1ele gira para a direita - Se o valor gerado for
0ele não gira
Com a direção definida. Vamos fazer com que a rotação do meteoro seja incrementada por ela em todo frame.
Como estabelecemos nos capítulos anteriores, qualquer coisa que precisa acontecer a cada frame vai dentro do game loop:
meteoro["rotacao"] += meteoro["dir_rotacao"]
Se você executar o jogo, verá que o meteoro ainda não gira. Isso ocorre porque não aplicamos a rotação para imagem ainda.
Para aplicar a rotação na imagem vamos usar a função pygame.transform.rotate(). Essa função gera uma nova imagem rotacionada que pode ser desenhada na tela.
A função
pygame.transform.rotate()espera que você informe a imagem que sofrerá a rotação e qual o angulo que será rotacionada.Por exemplo, para girar uma imagem 90 graus para a direita fazemos:
imagem_rotacionada = pygame.transform.rotate(imagem, 90)
Devemos rotacionar a imagem antes de desenhá-la:
imagem_rotacionada = pygame.transform.rotate(meteoro["imagem"], meteoro["rotacao"]) janela.blit(imagem_rotacionada, (meteoro["x"], meteoro["y"]))
Agora toda vez que o jogo for executado o meteoro estará girando para um lado diferente.
Você deve ter percebido que o meteoro está se movendo enquanto gira. Vamos resolver isso usando os retângulos do Pygame.
Centralizando a Imagem com Rect
Ao aplicar a rotação, o meteoro parece "escorregar" ou sair da posição original.
O problema está no tamanho. Cada vez que a imagem é rotacionada, o Pygame recalcula sua área. Esse tamanho muda a cada frame. Resultando no "escorregamento" no meteoro.
Para resolver esse problema, o Pygame oferece uma ferramenta chamada Rect.
Pense no
Rectcomo uma caixa invisível que guarda a posição e o centro do sprite, independente da imagem.
A solução é usar o Rect. Em vez de posicionar a imagem pelas coordenadas brutas, o Rect mantém o centro fixo. Independente de como o tamanho da imagem muda durante a rotação.
O Rect possui atributos de posicionamento. Como center, topleft e bottomright. Ao passá-lo como argumento para get_rect() você já posiciona a caixa naquele ponto desde a criação.
imagem_rotacionada = pygame.transform.rotate(meteoro["imagem"], meteoro["rotacao"]) retangulo_rotacionado = imagem_rotacionada.get_rect(center = (meteoro["x"], meteoro["y"])) janela.blit(imagem_rotacionada, retangulo_rotacionado)
Usamos get_rect para obter o Rect da imagem rotacionada.
Dentro dele, passamos center=(meteoro["x"], meteoro["y"]) para ancorar o centro do Rect na posição do meteoro.
Em seguida utilizamos esse Rect para posicionar a imagem. Com isso o meteoro continua girando e permanece no mesmo lugar.
O que Aprendemos até Agora?
Agora você tem a base necessária para um meteoro e adicionou uma rotação com direção aleatória.
Neste capítulo você:
- Criou a base necessária para os meteoros
- Gerou números aleatórios com a biblioteca
random - Rotacionou uma imagem na tela
Código Completo
import pygame import random pygame.init() janela = pygame.display.set_mode((800, 600)) clock = pygame.time.Clock() nave_img = pygame.image.load("img/nave.png") nave = { "imagem": nave_img, "x": janela.get_width() // 2 - nave_img.get_width() // 2, "y": janela.get_height() // 2 - nave_img.get_height() // 2, "velocidade": 5, } meteoro_img = pygame.image.load("img/meteoro.png") meteoro = { "imagem": meteoro_img, "x": 100, "y": 100, "velocidade": 2, "rotacao": 0, "dir_rotacao": random.randint(-1, 1), } rodando = True while rodando: for evento in pygame.event.get(): if evento.type == pygame.QUIT: rodando = False teclas = pygame.key.get_pressed() if teclas[pygame.K_w]: nave["y"] -= nave["velocidade"] if teclas[pygame.K_s]: nave["y"] += nave["velocidade"] if teclas[pygame.K_a]: nave["x"] -= nave["velocidade"] if teclas[pygame.K_d]: nave["x"] += nave["velocidade"] if nave["x"] <= 0: nave["x"] = 0 elif nave["x"] + nave["imagem"].get_width() >= janela.get_width(): nave["x"] = janela.get_width() - nave["imagem"].get_width() if nave["y"] <= 0: nave["y"] = 0 elif nave["y"] + nave["imagem"].get_height() >= janela.get_height(): nave["y"] = janela.get_height() - nave["imagem"].get_height() janela.fill("black") janela.blit(nave["imagem"], (nave["x"], nave["y"])) meteoro["rotacao"] += meteoro["dir_rotacao"] imagem_rotacionada = pygame.transform.rotate(meteoro["imagem"], meteoro["rotacao"]) retangulo_rotacionado = imagem_rotacionada.get_rect(center = (meteoro["x"], meteoro["y"])) janela.blit(imagem_rotacionada, retangulo_rotacionado) pygame.display.flip() clock.tick(60) pygame.quit()
Próximo Passo: Gerando Meteoros Automaticamente
Um meteoro girando na posição certa é só o começo. No próximo capítulo, vamos fazer o espaço ficar caótico: dezenas de meteoros surgindo em posições imprevisíveis.
No próximo capítulo você vai aprender por que criar cada meteoro manualmente seria impossível. Também verá como resolver isso com uma única estrutura.