pratica

Organizando o Código com Funções

Aprenda sobre organizando o código com funções

40 min
Aula 1 de 5

Aula: Organizando o Código com Funções

Olá, futuros desenvolvedores de jogos! 👋 Sejam bem-vindos a mais uma aula emocionante do nosso curso. Até agora, vocês aprenderam a fazer personagens se moverem, a desenhar coisas na tela e a interagir com o teclado. Mas, à medida que seus jogos ficam mais complexos, o código pode começar a ficar um pouco bagunçado, não é? 😅

Nesta aula, vamos aprender uma ferramenta superpoderosa para manter nosso código limpo, organizado e fácil de entender: as funções! Elas são como pequenas caixas de ferramentas que guardam um pedaço específico do seu código, pronto para ser usado quando você precisar.

🎯 Objetivos da Aula:

  • Entender o que são funções e por que elas são importantes.
  • Aprender a criar suas próprias funções em Python com Pgzero.
  • Saber como passar informações para as funções (parâmetros).
  • Ver como funções podem retornar valores.
  • Praticar a organização do código do seu jogo usando funções.

1. Introdução: Por Que Organizar o Código? 🤔

Imaginem que vocês estão construindo uma casa de LEGO. Se todas as peças estivessem misturadas em uma única caixa gigante, seria muito difícil encontrar o que você precisa, certo? 😫

Com o código é a mesma coisa! Quando escrevemos um jogo, temos muitas tarefas diferentes:

  • Desenhar o jogador.
  • Mover o inimigo.
  • Verificar se o jogador pegou uma moeda.
  • Atualizar a pontuação.
  • Reproduzir um som.

Se colocarmos todo esse código em um único lugar (como dentro das funções draw() ou update() do Pgzero), ele se torna:

  • Difícil de ler: Uma parede de texto sem pausas.
  • Difícil de modificar: Mudar uma pequena parte pode afetar outras sem querer.
  • Difícil de reutilizar: Se você precisa desenhar um tipo de inimigo várias vezes, teria que copiar e colar o código. 😱

É aí que as funções entram! Elas nos permitem agrupar um conjunto de instruções que realizam uma tarefa específica, dando a esse grupo um nome. Pensem nelas como "mini-programas" dentro do seu programa principal.


2. Explicação Detalhada com Exemplos 🧑‍🏫

O que é uma Função?

Uma função é um bloco de código que só é executado quando é chamado. Você define a função uma vez e pode chamá-la (executá-la) quantas vezes quiser, de qualquer lugar do seu programa.

Como Definir uma Função?

Em Python, usamos a palavra-chave def (de "define") para criar uma função, seguida do nome da função, parênteses () e dois pontos :. O código que faz parte da função deve ser indentado (com espaços ou tab).

# Exemplo 1: Uma função simples que diz "Olá!"
def saudar():
    print("Olá, aventureiro!")
    print("Bem-vindo ao meu jogo!")
 
# Nada acontece até chamarmos a função!

Como Chamar uma Função?

Para executar o código dentro de uma função, você simplesmente escreve o nome dela seguido de parênteses ().

# Chamando a função que definimos acima
saudar()
# Saída:
# Olá, aventureiro!
# Bem-vindo ao meu jogo!
 
saudar() # Podemos chamar a mesma função várias vezes!
# Saída:
# Olá, aventureiro!
# Bem-vindo ao meu jogo!

Parâmetros e Argumentos: Passando Informações para as Funções 📥

Muitas vezes, uma função precisa de algumas informações para fazer seu trabalho. Por exemplo, uma função para desenhar um personagem pode precisar saber onde ele deve ser desenhado (posição X e Y). Essas informações são chamadas de parâmetros na definição da função e argumentos quando a função é chamada.

# Exemplo 2: Função com parâmetros
def desenhar_mensagem(texto, cor):
    print(f"Desenhando: '{texto}' na cor {cor}")
    # No Pgzero, usaríamos algo como: screen.draw.text(texto, (10, 10), color=cor)
 
# Chamando a função com argumentos
desenhar_mensagem("Pontuação: 100", "white")
# Saída: Desenhando: 'Pontuação: 100' na cor white
 
desenhar_mensagem("Fim de Jogo!", "red")
# Saída: Desenhando: 'Fim de Jogo!' na cor red
  • texto e cor são parâmetros na definição da função.
  • "Pontuação: 100" e "white" são argumentos passados para a função.

Retornando Valores de uma Função 📤

Às vezes, uma função faz um cálculo ou processamento e queremos que ela nos dê um resultado de volta. Usamos a palavra-chave return para isso.

# Exemplo 3: Função que retorna um valor
def calcular_dano(ataque_jogador, defesa_inimigo):
    dano = ataque_jogador - defesa_inimigo
    if dano < 0:
        dano = 0 # Dano mínimo é 0
    return dano # A função "devolve" o valor de 'dano'
 
# Usando o valor retornado
dano_causado = calcular_dano(20, 5)
print(f"O jogador causou {dano_causado} de dano.")
# Saída: O jogador causou 15 de dano.
 
dano_fraco = calcular_dano(5, 10)
print(f"O jogador causou {dano_fraco} de dano.")
# Saída: O jogador causou 0 de dano.

Funções no Contexto do Pgzero: Organizando Seu Jogo 🎮

No Pgzero, as funções draw() e update() são chamadas automaticamente. Podemos usar nossas próprias funções para organizar o que acontece dentro delas!

Por exemplo, em vez de ter todo o código de desenho do jogador, inimigos e moedas dentro de draw(), podemos criar funções separadas para cada um:

# Código sem funções (exemplo ruim)
# def draw():
#     player.draw()
#     enemy.draw()
#     coin.draw()
#     screen.draw.text("Score: " + str(score), (10, 10), color="white")
 
# Código com funções (exemplo bom!)
def desenhar_personagens():
    player.draw()
    enemy.draw()
 
def desenhar_itens():
    coin.draw()
 
def desenhar_hud(): # HUD = Head-Up Display (informações na tela)
    screen.draw.text("Score: " + str(score), (10, 10), color="white")
 
def draw(): # Agora, draw() fica limpo e fácil de entender!
    screen.clear()
    desenhar_personagens()
    desenhar_itens()
    desenhar_hud()

Isso torna o código muito mais legível! Se você precisar mudar como o jogador é desenhado, sabe exatamente onde ir: na função desenhar_personagens().


3. Código de Exemplo Oficial (Adaptado para Pgzero) 🚀

A documentação oficial do Pgzero foca nas funcionalidades da biblioteca, mas a forma de usar funções é um conceito fundamental do Python. Vamos adaptar um exemplo simples de jogo para mostrar como as funções podem organizar o código.

Cenário: Um jogador que se move e coleta moedas.

Código "Bagunçado" (para entender o problema):

# game_baguncado.py
WIDTH = 800
HEIGHT = 600
 
player = Actor('player', (WIDTH / 2, HEIGHT / 2))
coin = Actor('coin', (100, 100))
score = 0
 
def draw():
    screen.clear()
    player.draw()
    coin.draw()
    screen.draw.text(f"Score: {score}", (10, 10), color="white", fontsize=30)
 
def update():
    global score
    # Movimento do jogador
    if keyboard.left:
        player.x -= 5
    if keyboard.right:
        player.x += 5
    if keyboard.up:
        player.y -= 5
    if keyboard.down:
        player.y += 5
 
    # Limitar o jogador dentro da tela
    if player.left < 0:
        player.left = 0
    if player.right > WIDTH:
        player.right = WIDTH
    if player.top < 0:
        player.top = 0
    if player.bottom > HEIGHT:
        player.bottom = HEIGHT
 
    # Colisão com a moeda
    if player.colliderect(coin):
        score += 1
        coin.pos = (random.randint(50, WIDTH - 50), random.randint(50, HEIGHT - 50))
 
import random

Mesmo para um jogo simples, o update() já está ficando grandinho. Agora, vamos organizar!

Código Organizado com Funções:

# game_organizado.py
import random
 
WIDTH = 800
HEIGHT = 600
 
# Cores
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
 
# Atores
player = Actor('player', (WIDTH / 2, HEIGHT / 2))
coin = Actor('coin', (random.randint(50, WIDTH - 50), random.randint(50, HEIGHT - 50)))
 
# Variáveis do jogo
score = 0
game_over = False
 
# --- Funções de Desenho ---
def desenhar_jogador():
    """Desenha o ator do jogador na tela."""
    player.draw()
 
def desenhar_moeda():
    """Desenha o ator da moeda na tela."""
    coin.draw()
 
def desenhar_hud():
    """Desenha o placar e outras informações na tela."""
    screen.draw.text(f"Score: {score}", (10, 10), color=WHITE, fontsize=30)
    if game_over:
        screen.draw.text("GAME OVER!", center=(WIDTH/2, HEIGHT/2), color=BLUE, fontsize=80)
 
# --- Funções de Lógica do Jogo ---
def mover_jogador():
    """Atualiza a posição do jogador com base nas teclas pressionadas."""
    if keyboard.left:
        player.x -= 5
    if keyboard.right:
        player.x += 5
    if keyboard.up:
        player.y -= 5
    if keyboard.down:
        player.y += 5
 
    # Limitar o jogador dentro da tela
    if player.left < 0:
        player.left = 0
    if player.right > WIDTH:
        player.right = WIDTH
    if player.top < 0:
        player.top = 0
    if player.bottom > HEIGHT:
        player.bottom = HEIGHT
 
def verificar_colisao_moeda():
    """Verifica se o jogador colidiu com a moeda e atualiza o placar."""
    global score # Precisamos do 'global' para modificar a variável global 'score'
    if player.colliderect(coin):
        score += 1
        coin.pos = (random.randint(50, WIDTH - 50), random.randint(50, HEIGHT - 50))
 
# --- Funções Principais do Pgzero ---
def draw():
    """Função principal de desenho do Pgzero."""
    screen.clear()
    desenhar_jogador()
    desenhar_moeda()
    desenhar_hud()
 
def update():
    """Função principal de atualização do Pgzero."""
    if not game_over: # Só atualiza se o jogo não acabou
        mover_jogador()
        verificar_colisao_moeda()
 
# Exemplo de uma função de evento (opcional, para mostrar mais organização)
def on_mouse_down(pos):
    """Função chamada quando o botão do mouse é clicado."""
    global game_over
    if game_over:
        if player.collidepoint(pos): # Se clicou no jogador quando o jogo acabou
            print("Clicou no jogador para reiniciar!")
            # Reiniciar jogo (exemplo)
            score = 0
            game_over = False
            player.pos = (WIDTH / 2, HEIGHT / 2)
            coin.pos = (random.randint(50, WIDTH - 50), random.randint(50, HEIGHT - 50))
        else:
            print("Clicou em outro lugar.")
 

Observe como as funções draw() e update() agora estão muito mais curtas e fáceis de ler. Cada função tem uma responsabilidade clara, tornando o código mais modular e fácil de dar manutenção!


4. Exercícios/Desafios: Mão na Massa! 🛠️

Agora é a sua vez de colocar em prática o que aprendeu! Pegue o código game_organizado.py como base e faça as seguintes modificações usando funções.

📝 Tarefas:

  • Tarefa 1: Adicionar um Inimigo Simples 👾

    • Crie um novo ator chamado enemy (use a imagem 'enemy' ou 'alien').
    • Crie uma função chamada desenhar_inimigo() que seja responsável por desenhar o enemy.
    • Chame desenhar_inimigo() dentro da função draw().
  • Tarefa 2: Movimento do Inimigo ➡️⬅️

    • Crie uma função chamada mover_inimigo() que faça o inimigo se mover de um lado para o outro na tela (por exemplo, mudando enemy.x e invertendo a direção quando ele atinge as bordas).
    • Chame mover_inimigo() dentro da função update().
  • Tarefa 3: Colisão com o Inimigo (Game Over) 💥

    • Crie uma função chamada verificar_colisao_inimigo() que detecta se o player colidiu com o enemy.
    • Se houver colisão, defina a variável game_over como True.
    • Chame verificar_colisao_inimigo() dentro da função update().
    • Desafio Extra: Na função desenhar_hud(), adicione uma condição para que, se game_over for True, o placar não seja mais atualizado e uma mensagem "GAME OVER!" apareça no centro da tela. (Já implementado no exemplo, mas revise para entender!)
  • Tarefa 4: Reiniciar o Jogo 🔄

    • Crie uma função chamada reiniciar_jogo() que:
      • Define score = 0.
      • Define game_over = False.
      • Reseta a posição do player para o centro.
      • Reseta a posição da coin para um lugar aleatório.
      • Reseta a posição do enemy para um lugar inicial.
    • Modifique a função on_mouse_down(pos) para que, se o game_over for True e o mouse for clicado em qualquer lugar da tela, a função reiniciar_jogo() seja chamada.

Dica: Lembre-se de usar global quando precisar modificar uma variável que foi definida fora da função (como score, game_over, player.pos, etc.).


5. Resumo e Próximos Passos 📚

Parabéns! 🎉 Você deu um grande passo para se tornar um programador mais organizado e eficiente.

O que aprendemos hoje:

  • Funções são blocos de código reutilizáveis que realizam uma tarefa específica.
  • Elas tornam seu código mais legível, modular e fácil de dar manutenção.
  • Usamos def para definir uma função e () para chamá-la.
  • Podemos passar informações para as funções usando parâmetros e argumentos.
  • Funções podem nos dar um resultado de volta usando return.
  • No Pgzero, funções são essenciais para organizar as lógicas dentro de draw(), update() e os manipuladores de eventos.

Organizar seu código com funções é uma das habilidades mais importantes que você pode aprender. Isso fará uma enorme diferença na complexidade dos jogos que você poderá criar!

Próximos Passos: Na próxima aula, vamos explorar como lidar com múltiplos objetos do mesmo tipo (por exemplo, vários inimigos ou várias moedas) de uma forma ainda mais elegante, usando listas e talvez até introduzindo o conceito de classes. Preparem-se para mais aventura! 🚀

© 2025 Escola All Dev. Todos os direitos reservados.

Organizando o Código com Funções - Game Maker: Python com Pgzero para Crianças | escola.all.dev.br