Pular para o conteúdo
Power PPlay 2.1 · Capítulo 3 do manual

Tutoriais

Este roteiro constrói, do zero e sem pular etapas, um jogo de plataforma completo: personagem animado que anda e pula com física de verdade, cenário desenhado em arquivo de texto, câmera que acompanha, fundo com profundidade, moedas colecionáveis, inimigo com inteligência, efeitos de impacto, interface e telas de menu e fim de jogo.

Ao terminar, você terá usado a maior parte da engine — e entendido o papel de cada peça. Reserve entre 60 e 90 minutos.

💡 Dica do Sênior: como acompanhar

Digite o código, não copie. Rode a cada passo. Quando algo não funcionar, compare a sua tela com a ilustração do passo: quase sempre a diferença aponta direto para a linha errada.

Antes de começar

Você precisa da engine instalada e de uma janela abrindo. Se ainda não chegou lá, passe primeiro pela página de download e instalação — são dois comandos e uma pasta.

A estrutura do projeto deste tutorial:

plataforma/ |– PPlay/ <- a engine |– assets/ <- imagens, sons e mapas (crie a pasta vazia) |– gerar_assets.py <- so para este tutorial +– main.py <- o jogo

O gerar_assets.py desenha sozinho todas as imagens necessárias — herói, tiles, moeda, zumbi e as camadas de fundo. Rode uma única vez e esqueça que existe: assim você não precisa saber desenhar para seguir o tutorial.

Os passos

PassoO que você constróiPeças da engine
0 A pasta e os desenhos — gera a arte e o arquivo do mapa fase1.txt
1 A janela: 640×360 lógicos, azul-noite, fecha no X e alterna tela cheia no F11 Window
2 O herói aparece e anda com as setas — mas ainda flutua Sprite
3 Gravidade, chão e pulo. Ele cai, colide, anda com inércia e pula com coyote time Physics
4 O cenário vem do arquivo de texto — mude o .txt e o mundo muda TileMap
5 A câmera acompanha o herói com suavização e para nas bordas do mapa Camera
6 Profundidade com parallax: três camadas em velocidades diferentes ParallaxSystem
7 Moedas: sua primeira classe própria, herdando de Sprite ObjectGroup
8 Suco: partículas, tremor de tela e som ao coletar ParticleEmitter · ScreenEffects
9 Um inimigo que enxerga o jogador e reage Navegação · A*
10 Interface: vidas, pontuação e HUD módulo ui
11 Menu e fim de jogo como cenas separadas Scene · SceneManager

Passo 1 — a janela

from PPlay.window import Window janela = Window(640, 360, “Plataforma”, pixel_art=True) while True: janela.set_background_color((22, 32, 58)) janela.update()

A resolução lógica 640×360 é 16:9 e escala para 1080p em múltiplo exato de 3, o que mantém a arte nítida. O pixel_art=True garante o escalonamento por vizinho mais próximo — sem borrar os pixels.

Passo 2 — o herói aparece e anda

from PPlay.window import Window from PPlay.sprite import Sprite janela = Window(640, 360, “Plataforma”, pixel_art=True) heroi = Sprite(“assets/heroi.png”, 4) # 4 quadros na tira heroi.set_total_duration(500) # meio segundo por ciclo heroi.set_position(80, 200) while True: janela.set_background_color((22, 32, 58)) heroi.move_key_x(220) # setas, ja com delta time heroi.draw() janela.update()
⚠️ Atenção: ele anda mas não anima?

O move_key_x() move, mas quem troca os quadros da animação é o update(). Neste passo ainda não o chamamos — no passo seguinte o update_physics() passa a fazer isso por nós.

Passo 3 — gravidade, chão e pulo

Aqui o movimento manual dá lugar a um corpo cinemático. A partir deste ponto o herói cai, colide, anda com inércia e pula com coyote time — e você não escreve nada disso.

from PPlay.physics import Physics fisica = Physics(gravidade=2500) heroi.setup_physics(fisica) # <- ganha corpo fisico chao = Sprite(“assets/pedra.png”) chao.set_position(0, 320) chao.width = 640 # estica o retangulo de colisao while True: janela.set_background_color((22, 32, 58)) heroi.update_physics([chao]) # gravidade + colisao + animacao chao.draw() heroi.draw() janela.update()
💡 Dica do Sênior: sinta a diferença

Segure o espaço por mais tempo: o pulo fica mais alto (pulo variável). Corra até a borda e pule depois de já ter saído dela: ainda funciona, graças aos 150 ms de coyote time. São detalhes que ninguém percebe — e que fazem o controle parecer bom.

Passo 4 — o cenário vem do arquivo de texto

O chão improvisado sai de cena. Agora o mundo inteiro vem do fase1.txt, onde cada caractere é um bloco de 32 pixels.

from PPlay.tilemap import TileMap mapa = TileMap(tamanho_tile=32) mapa.carregar_mapa(“assets/fase1.txt”, { ‘#’: “assets/pedra.png”, ‘X’: “assets/madeira.png”, ‘solido’: [‘#’, ‘X’] # quem tem colisao }) # no loop, no lugar do chao provisorio: heroi.update_physics(mapa.get_solidos()) mapa.draw() heroi.draw()
🐞 Armadilha: o herói cai pelo chão

Se ele atravessa tudo, o dicionário provavelmente não tem a chave 'solido', ou ela lista caracteres que não aparecem no arquivo. Confira imprimindo print(len(mapa.get_solidos())): se der zero, é isso.

Passo 5 — a câmera acompanha

from PPlay.camera import Camera # ATENCAO a ordem: a camera precisa existir ANTES do mapa, # para que carregar_mapa() ja configure os limites do mundo. camera = Camera(640, 360) mapa = TileMap(tamanho_tile=32) mapa.carregar_mapa(…) # no loop, depois da fisica: camera.follow(heroi, 0.1)

O 0.1 é a suavização: a câmera persegue o alvo em vez de grudar nele. Troque por 1.0 e sinta a diferença — fica seco e embrulha o estômago.

Passo 6 — profundidade com parallax

from PPlay.parallax import ParallaxSystem fundo = ParallaxSystem() fundo.add_layer(“assets/ceu.png”, 0.0) # estatico fundo.add_layer(“assets/montanhas.png”, 0.3) # longe fundo.add_layer(“assets/arvores.png”, 0.7) # perto # no loop, ANTES de tudo (fica atras): fundo.draw() mapa.draw() heroi.draw()

Três camadas em velocidades diferentes: o céu não se move, as montanhas quase não se movem, as árvores acompanham. O olho lê isso como distância.

Passo 7 — moedas: sua primeira classe

Aqui você deixa de usar a engine e passa a estendê-la. A moeda é uma classe sua, que herda de Sprite e acrescenta regra própria.

from PPlay.sprite import Sprite from PPlay.object_group import ObjectGroup class Moeda(Sprite): def __init__(self, x, y): super().__init__(“assets/moeda.png”, 8) # SEMPRE a primeira linha self.set_total_duration(700) self.set_position(x, y) self.valor = 10 moedas = ObjectGroup() for x, y in [(150, 130), (200, 130), (250, 130), (450, 200), (500, 200), (860, 100)]: moedas.add(Moeda(x, y)) pontos = 0 # no loop: moedas.update() # anima todas de uma vez pega = moedas.collided(heroi) # devolve a moeda tocada, ou None if pega: pontos += pega.valor moedas.remove(pega) moedas.draw()
💡 Dica do Sênior: por que uma classe própria?

Você poderia guardar as moedas numa lista de Sprite. Mas com uma classe, cada moeda carrega o seu valor — e amanhã, quando existir moeda de ouro valendo 50, basta mudar um atributo. Estado e comportamento juntos: é isso que orientação a objetos compra.

Passo 8 — suco: partículas, tremor e som

Coletar uma moeda precisa sentir bem. Três linhas resolvem.

from PPlay.particles import ParticleEmitter from PPlay.effects import ScreenEffects faiscas = ParticleEmitter(0, 0) faiscas.cor = (245, 197, 66) faiscas.vida_base = 0.5 faiscas.tamanho_base = 2 # no loop, logo no comeco: ScreenEffects.update() if pega: pontos += pega.valor moedas.remove(pega) faiscas.set_pos(pega.x + pega.width / 2, pega.y + pega.height / 2) faiscas.explodir(14) ScreenEffects.shake(4, 0.12) faiscas.update() # … desenhos … faiscas.draw() ScreenEffects.draw_flash()
🐞 Armadilha: o efeito não acontece

São três chamadas independentes e todas obrigatórias: ScreenEffects.update() no começo do laço, apply_to_camera() depois do camera.follow(), e draw_flash() no fim dos desenhos. Faltando a primeira, o tremor nunca termina; faltando a segunda, ele não aparece.

Passos 9 a 11 — inimigo, interface e cenas

Os três últimos passos fecham o jogo: um inimigo que enxerga o jogador e persegue usando o algoritmo A*; a interface com vidas e pontuação pelo módulo ui, que tem tema e layout automático; e as telas de menu e fim de jogo como Scene independentes, trocadas pelo SceneManager.

O código completo dos onze passos, com as ilustrações de cada etapa, está no manual da Power PPlay 2.1, capítulo 3.

Referência dos módulos

O tutorial acima ensina montando um jogo. Estas páginas explicam cada peça da engine isoladamente — use como consulta enquanto constrói.

🚀 Primeiros Passos

🎮 Atores e Controles

⚛️ Física e Colisão

🌍 Construindo Mundos

✨ Game Juice e IA

🛠️ Ferramentas Sênior

Para onde ir agora