Adicionando Obstáculo - Criando o Meteoro

30/04/2026
iniciante pygame python 2d guia série

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:

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 img do 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.

Primeiro 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 0 e 10 usamos:

random.randint(0, 10)

Definimos a direção da rotação com valor aleatório entre -1 e 1.

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 Rect como 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ê:

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.