• Jogos
  • 01. Introdução
  • Adicionando interação

Adicionando interação#

Nossa etapa final da introdução será permitir que nosso usuário interaja com nosso jogo. Já sabemos

  1. criar uma estrutura de jogo básica
  2. desenhar imagens na tela
  3. escrever texto na tela

Em nossa função recebe_eventos também já recebemos o evento pygame.QUIT, que significa que o usuário clicou no botão de fechar de nossa janela. De fato, todas as interações do usuário com nosso jogo chegam via retorno da função pygame.event.get()! Vamos ver alguns exemplos:

  • quando o usuário aperta o botão esquerdo do mouse no nosso jogo recebemos um evento do tipo pygame.MOUSEBUTTONDOWN. Quando este botão é liberado é enviado um evento do tipo pygame.MOUSEBUTTONUP.
  • toda tecla pressionada gera eventos similares pygame.KEYDOWN e em seguida pygame.KEYUP
  • se a tela do jogo for redimensionada recebemos um evento do tipo pygame.VIDEORESIZE

Note que os nomes dos eventos são bastante descritivos. Vamos agora olhar novamente a função recebe_eventos:

def recebe_eventos():
    for evento in pygame.event.get():
        if evento.type == pygame.QUIT:
            return False

    return True

Exercise 1

Levando em conta as informações acima, como você modificaria o código da função recebe_eventos para mostrar a mensagem "Apertou teclado!" quando o usuário pressionar uma tecla do teclado?

Answer

O evento pygame.KEYDOWN é recebido quando a tecla é pressionada e, quando o usuário soltá-la o evento pygame.KEYUP é enviado para nosso programa. Note que existem vários tipos de eventos, então a primeira opção não é válida: ela mostra a mensagem em qualquer evento que não seja pygame.QUIT.

Agora vamos ver como extrair informações relevantes destes eventos. De acordo com o tipo do evento, a variável evento do código acima pode conter os seguintes atributos:

Tipo do Evento Atributos
pygame.MOUSEBUTTONDOWN pos, button
pygame.MOUSEBUTTONUP pos, button
pygame.MOUSEMOTION pos, button, rel
pygame.KEYUP key, mod
pygame.KEYDOWN key, mod

Exercise 2

Queremos detectar se o usuário pressionou a seta para a esquerda no nosso código. Qual linha abaixo contém a condição que usaríamos no código abaixo para fazer essa checagem?

def recebe_eventos():
    for evento in pygame.event.get():
        if evento.type == pygame.QUIT:
            return False
        elif evento.type == pygame.KEYDOWN:
            if __________ :
                print('Apertou seta para esquerda')

    return True

Para fazer essa questão será necessário ler a documentação de pygame.key.

Answer

Como vimos na tabela no texto acima, todo evento do tipo KEYDOWN possui um atributo key contendo a tecla pressionada. A documentação mostra uma grande tabela com todas as teclas disponíveis como constantes começando com K_. Assim como os eventos, elas estão disponíveis como atributos de pygame.

Finalmente, precisamos checar se evento.key é igual à constante pygame.K_LEFT. Isso resulta na terceira opção como correta.

Nesta sequência de exercícios vamos produzir o seguinte "jogo":

Temos uma novidade em relação aos outros exercícios de introdução: precisamos saber onde está a nave atualmente para podermos movimentá-la para a direita ou esquerda. Ou seja, o jogo tem um estado que representa o que está acontecendo no jogo neste momento. Uma das partes importantes da função recebe_eventos é modificar o estado do jogo baseado nas ações do usuário.

Exercise 3

Vamos representar o estado do jogo como um dicionário em que guardamos na chave "nave_x" a coordenada x da nave. O mesmo vale para a coordenada y da nave.

Como você pintaria na tela a nave? Suponha que as seguintes variáveis existem.

window # tela do jogo
assets = {
    'nave': ... # imagem da nave
}
state # dicionário descrito acima

Answer

Para mostrar pintar a imagem da nave na tela usamos

window.blit(assets['nave'], (
    state['nave_x'], state['nave_y']
))

Lembrando que blit recebe a imagem a ser mostrada seguido de uma tupla com sua posição.

Exercise 4

Agora vamos modificar a função recebe_eventos. Seguimos usando as variáveis definidas no exercício anterior. Dado o código da função recebe eventos abaixo, qual das opções você usaria para mexer a nave para a direita?

def recebe_eventos(state):
    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            return False

        # TODO: qual código vai aqui?

    return True

Answer

Precisamos checar duas coisas:

  1. o evento recebido é um evento de tecla pressionada?
  2. se sim, a tecla pressionada é seta para direita?

As duas primeiras alternativas checam direto ev.key, porém esse atributo key ´so existe em eventos de teclado. Se o evento for de mouse, por exemplo, o código daria erro.

Agora falta só mexer no estado do jogo. As coordenadas de pygame crescem para a direita e para baixo. Ou seja, para mover a nave para direita precisamos somar em state['nave_x'].

Exercise 5

Agora falta só implementar! Seu trabalho será:

  1. Criar o dicionário state na função inicializa e retorná-lo junto com assets e window.
  2. usá-lo na função desenha como fizemos no roteiro anterior
  3. usá-lo na função recebe_eventos como fizemos acima

O exercício já tem algum código base usando a estrutura que vimos no início da introdução e também uma imagem de nave para ser usada no jogo.

Este exercício não tem testes automatizados. Você deverá verificar seu funcionamento executando o jogo e verificando que o comportamento esperado acontece.

Acessar exercício