Neste tutorial, você usará a função turtle
do Python para criar um clone do Space Invaders. O jogo Space Invaders não precisa de apresentação. O jogo original foi lançado em 1978 e é um dos videogames mais reconhecidos de todos os tempos. É inegável que ele definiu seu próprio gênero de videogame. Neste tutorial, o senhor criará um clone básico desse jogo.
O turtle
que o senhor usará para criar o jogo faz parte da biblioteca padrão do Python e permite desenhar e mover sprites na tela. O módulo turtle
não é um pacote de desenvolvimento de jogos, mas fornece instruções sobre como criar um turtle
jogo, que o ajudará a entender como os videogames são criados.
Neste tutorial, o senhor aprenderá a:
- Projetar e construir um videogame clássico
- Use o
turtle
para criar sprites animados - Adicionar interação com o usuário em um programa baseado em gráficos
- Criar um loop de jogo para controlar cada quadro do jogo
- Use as funções para representar as principais ações do jogo
Este tutorial é ideal para qualquer pessoa que esteja familiarizada com os principais tópicos do Python e queira usá-los para criar um videogame clássico do zero. Não é necessário que o senhor esteja familiarizado com o turtle
para trabalhar com este tutorial. O senhor pode fazer download do código de cada etapa clicando no link abaixo:
Na próxima seção, você poderá ver a versão do jogo que criará ao seguir as etapas descritas neste tutorial.
Demonstração: Um jogo de invasores de espaço com tartarugas Python
O senhor criará uma versão simplificada do clássico jogo Space Invaders e controlará o canhão laser com as teclas do teclado. O senhor disparará lasers do canhão pressionando a barra de espaço, e os alienígenas aparecerão em intervalos regulares na parte superior da tela e se moverão para baixo. Sua tarefa é atirar nos alienígenas antes que eles cheguem à parte inferior da tela. O jogo termina quando um alienígena chega à parte inferior da tela.
Isso é o que o senhor turtle
terá a aparência do jogo quando o senhor concluir este tutorial:
Aqui o senhor pode ver a jogabilidade principal do jogo, pois o canhão laser se move para frente e para trás e atira nos alienígenas que caem. O jogo também exibe o tempo decorrido e o número de alienígenas abatidos na tela.
Visão geral do projeto
Neste projeto, o senhor começará criando a tela que conterá o jogo. Em cada etapa, o senhor criará os componentes do jogo, como o canhão laser, os lasers e os alienígenas, e adicionará os recursos necessários para criar um jogo funcional.
Para criar isso turtle
o senhor realizará as etapas a seguir:
- Criar o jogo tela e o canhão laser
- Mova o canhão para a esquerda e para a direita usando as teclas
- Atire em lasers com a barra de espaço
- Criar alienígenas e mova-os para a parte inferior da tela
- Determine quando um laser atinge um alienígena
- Terminar o jogo quando um alienígena chega ao fundo do poço
- Adicionar um cronômetro e um pontuação
- Melhorar o movimento do canhão para tornar o jogo mais suave
- Defina o taxa de quadros
O senhor começará com uma tela em branco e verá o jogo ganhar vida, um recurso de cada vez, à medida que avança em cada etapa deste tutorial.
Pré-requisitos
Para concluir este tutorial, o senhor deve estar familiarizado com os seguintes conceitos:
Não é necessário que o senhor esteja familiarizado com o turtle
do Python para começar este tutorial. No entanto, o senhor pode ler uma visão geral do turtle
módulo para saber mais sobre os conceitos básicos.
Se o senhor não tiver todo o conhecimento necessário antes de começar, não tem problema! Na verdade, o senhor pode aprender mais se for em frente e começar! O senhor sempre pode parar e analisar os recursos vinculados aqui se tiver dúvidas.
Etapa 1: Configurar o jogo da tartaruga com uma tela e um canhão de laser
Não é possível ter um jogo sem uma tela onde toda a ação acontece. Portanto, a primeira etapa é criar uma tela em branco. Em seguida, o senhor pode adicionar sprites para representar os itens do jogo. Nesse projeto, o senhor pode executar seu código a qualquer momento para ver o jogo em seu estado atual.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_1/
no link abaixo:
É hora de dar o primeiro passo para configurar seu jogo com o turtle
e criar a tela.
Criar a tela
Para começar, crie um novo arquivo e importe o arquivo turtle
:
O senhor chama turtle.done()
, que exibe a janela e a mantém aberta. Essa linha deve ser sempre a última linha em qualquer programa que use o turtle
. Isso evitará que o programa seja encerrado quando chegar à última linha. Para interromper o programa, feche a janela clicando no botão fechar janela no canto superior da janela, da mesma forma que faria com qualquer outra janela do sistema operacional.
Embora esse código crie e exiba uma tela, o senhor pode criar explicitamente a tela no seu código e atribuí-la a um nome de variável. Essa abordagem permite que o senhor personalize o tamanho e a cor da tela:
O senhor usa floats como argumentos para .setup()
que define o tamanho da tela como uma fração da tela do seu computador. A largura da janela é 50% da largura da tela e sua altura é 75% da altura da tela. O senhor pode experimentar o uso de valores de pixel para definir as dimensões da tela, usando inteiros em vez de floats como argumentos em .setup()
.
O modo de cor padrão no turtle
requer o módulo componentes vermelho, verde e azul para serem flutuantes no intervalo [0, 1]. O senhor também deve atualizar o texto na barra de título. Ao executar esse código, o senhor verá esta tela:

Esta versão tem um fundo escuro, mas o senhor pode personalizar o jogo com as cores de sua preferência. Agora, o senhor está pronto para criar o canhão laser.
Criar o canhão de laser
Assim como não é possível ter um jogo sem uma tela, não é possível ter um jogo clone do Space Invaders sem um canhão de laser. Para configurar o canhão, o senhor cria um Turtle
usando turtle.Turtle()
. Cada item independente no jogo precisa de seu próprio Turtle
objeto.
Quando o senhor cria um objeto Turtle
ele fica localizado no centro da tela e voltado para a direita. A imagem padrão é uma seta que mostra a direção do objeto. O senhor pode alterar esses valores usando Turtle
métodos:
O canhão agora é um quadrado branco. O senhor chama cannon.penup()
para que o Turtle
não desenhe uma linha quando o senhor o mover. O senhor pode ver o canhão quando executar o código:

No entanto, o senhor quer que o canhão fique na parte inferior da tela. Veja como o senhor define a nova posição do canhão:
O senhor define as bordas da tela usando window.window_height()
e window.window_width()
já que esses valores serão diferentes em diferentes configurações de computador. O centro da tela tem as coordenadas (0, 0)
. Portanto, o senhor divide a largura e a altura por dois, para obter o x- e y-para as quatro bordas.
O senhor também define FLOOR_LEVEL
como 90 por cento do y-da borda inferior. Em seguida, coloque o canhão nesse nível usando .setposition()
de modo que ele fique ligeiramente elevado em relação à parte inferior da tela.
Lembre-se de que este é um clone de um jogo dos anos 1970, portanto, o senhor só precisa de gráficos simples! O senhor pode desenhar o canhão esticando a forma da tartaruga em retângulos de diferentes tamanhos usando .turtlesize()
e chamando .stamp()
para deixar uma cópia dessa forma na tela. O código abaixo mostra apenas a seção do código que foi alterada:
Ao executar esse código, o senhor verá o canhão na parte inferior da tela:

Sua próxima tarefa é introduzir alguma interatividade para que o senhor possa mover o canhão para a esquerda e para a direita.
Etapa 2: Mover o canhão usando as teclas
Na etapa anterior, o senhor escreveu um código para desenhar o canhão na tela. Mas um jogo precisa de um jogador que possa interagir com ele. Portanto, agora é hora de aprender sobre keybindings, para que o senhor possa usar o teclado para mover o canhão.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_2/
no link abaixo:
Para começar, o senhor se familiarizará com as principais técnicas usadas em animação.
Mova o Turtle
Objeto
O senhor pode vincular uma função a uma chave usando window.onkeypress()
. O pressionamento da tecla chama a função vinculada a essa tecla. O senhor pode definir duas funções para mover o canhão para a esquerda e para a direita e associá-las à tecla Esquerda e Certo em seu teclado:
O senhor notou que usou os nomes das funções move_left
e move_right
sem parênteses como argumentos para .onkeypress()
? Se o senhor adicionar parênteses, o programa chamará a função quando executar a linha com .onkeypress()
e vincula o valor de retorno da função à chave. As funções move_left()
e move_right()
retorno None
Portanto, se o senhor incluir parênteses, as teclas de seta permanecerão inativas.
As funções para mover o canhão usam CANNON_STEP
que o senhor define na parte superior do seu código. O nome é escrito com letras maiúsculas para mostrar que se trata de um constante que o senhor usa para configurar o jogo. Tente alterar esse valor para ver como isso afetará o jogo.
O senhor também traz o foco para a tela usando window.listen()
para que os eventos de pressionamento de tecla sejam coletados pelo programa. Por padrão, o turtle
não usa recursos de computação para ouvir os pressionamentos de tecla enquanto o programa está em execução. Chamada window.listen()
substitui esse padrão. Se as teclas não funcionarem quando o usuário executar um turtle
verifique se o senhor incluiu o .listen()
pois é fácil esquecer-se dele ao usar o .onkeypress()
.
Agora que está familiarizado com os atalhos de teclas, o senhor adicionará um recurso para sair do programa atrelando a tecla Q chave para turtle.bye
. Como fez com as funções anteriores, o senhor não adiciona parênteses ao turtle.bye
mesmo que seja uma função. Certifique-se de usar uma letra minúscula q
porque se usar uma letra maiúscula no código, o senhor precisará pressionar Shift+Q para sair do programa.
Agora, ao executar o programa, o senhor pode pressionar as teclas de seta para a direita e para a esquerda para mover o Turtle
objeto.
Observação: Funções usadas como argumentos para .onkeypress()
não podem aceitar nenhum argumento obrigatório. Embora as funções possam ter um return
o senhor não pode acessar os dados retornados em seu programa, pois essas funções são chamadas de dentro do .onkeypress()
.
Veja como é o resultado nesta etapa:
Esse não é exatamente o comportamento que o senhor deseja. Observe como apenas uma parte do desenho se move quando o senhor pressiona as teclas de seta. Esse é o sprite que representa o Turtle
objeto. O restante do desenho é o resultado do .stamp()
na seção do código em que o senhor desenha o canhão laser.
Mover todo o canhão de laser
Sempre que mover o canhão de laser, o senhor pode limpar o desenho anterior e redesenhar o canhão no novo local. Para evitar a repetição, o senhor pode mover o código para desenhar o canhão em uma função draw_cannon()
. No código a seguir, a maioria das linhas em draw_cannon()
são as mesmas linhas que o senhor tinha na versão anterior, mas agora elas estão recuadas:
Quando o senhor chama cannon.clear()
, todos os desenhos feitos pela cannon
são excluídos da tela. O senhor chama draw_cannon()
em ambos os move_left()
e move_right()
para redesenhar o canhão sempre que o senhor o mover. O senhor também chama draw_cannon()
na seção principal do programa para desenhar o canhão no início do jogo.
Veja como o jogo está agora:
O canhão laser inteiro se move quando o senhor pressiona as teclas de seta para a esquerda ou para a direita. A função draw_cannon()
exclui e redesenha os três retângulos que compõem o canhão.
No entanto, o movimento do canhão não é suave e pode apresentar falhas se o usuário tentar movê-lo muito rapidamente, como pode ser visto na segunda parte do vídeo. O senhor pode corrigir esse problema controlando quando os itens são desenhados na tela na função turtle
módulo.
Controle quando os itens são exibidos
O turtle
exibe várias pequenas etapas quando o Turtle
os objetos se movem. Quando o senhor se move cannon
de sua posição central inicial para a parte inferior da tela, o senhor pode ver o quadrado se mover para baixo até sua nova posição. Quando o senhor redesenha o canhão, o Turtle
precisa se mover para vários locais, mudar de forma e criar um carimbo com essa forma.
Essas ações levam tempo e, se o senhor pressionar uma tecla de seta durante esse processo de desenho, o Turtle
se moverá antes de ter tempo de concluir o desenho.
Esse problema se torna ainda mais perceptível quando há mais eventos ocorrendo no jogo. Agora é um bom momento para corrigir esse problema. O senhor pode impedir que qualquer alteração seja exibida na tela definindo window.tracer(0)
.
O programa ainda alterará as coordenadas de um Turtle
e seu cabeçalho, mas não exibirá as alterações na tela. O senhor pode controlar quando a tela é atualizada chamando window.update()
. Isso permite que o senhor controle quando a tela será atualizada.
O senhor pode chamar window.tracer(0)
logo após criar a tela e window.update()
no draw_cannon()
:
Agora não há falhas quando o senhor move o canhão, e o posicionamento inicial do cannon
do centro para a parte inferior não é mais visível. Aqui está o seguinte turtle
jogo até agora:
O senhor melhorará a suavidade com que o canhão se move mais adiante neste tutorial. Na próxima etapa, o senhor resolverá outro problema. Observe como, no final do vídeo, é possível ver o canhão laser saindo da tela quando a tecla de seta para a esquerda é pressionada muitas vezes. O senhor precisa impedir que o canhão saia da tela para que ele possa manter o centro do terreno e defender o planeta dos alienígenas invasores!
Impedir que o canhão laser saia da tela
As funções move_left()
e move_right()
são chamados sempre que o jogador pressiona uma das teclas de seta para mover o canhão laser para a esquerda ou para a direita. Para verificar se o canhão laser alcançou a borda da tela, é possível adicionar um if
. Em vez de usar LEFT
e RIGHT
que são as bordas da tela, o senhor incluirá uma calha para parar o canhão logo antes de ele chegar às bordas:
Agora, o canhão de laser não pode sair da tela. O senhor usará técnicas semelhantes nas etapas seguintes ao adicionar lasers e alienígenas ao seu turtle
jogo.
Etapa 3: Atire nos lasers com a barra de espaço
Não adianta ter um canhão laser se ele não puder disparar lasers. Nesta etapa, o senhor criará lasers que podem ser disparados pressionando a barra de espaço. O senhor aprenderá a armazenar todos os lasers ativos em uma lista e a mover cada laser para frente em cada quadro do jogo. O senhor também começará a trabalhar no loop do jogo que controla o que acontece em cada quadro.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_3/
no link abaixo:
Para começar, o senhor usará Turtle
para criar e armazenar os lasers.
Criar lasers
O senhor quer poder disparar lasers sempre que pressionar Espaço. Como seu código precisa armazenar todos os lasers presentes, o senhor pode criar um Turtle
para cada laser e armazená-lo em uma lista. O senhor também precisará de uma função para criar novos lasers:
A barra de espaço está vinculada a create_laser()
que cria um novo Turtle
para representar um laser, define seus atributos iniciais e o anexa à lista de todos os lasers. Para não complicar o código, este tutorial faz algumas simplificações, sobre as quais o senhor poderá ler na seção a seguir:
Há duas simplificações para evitar que o código fique muito complexo:
- A altura do canhão é codificada para 20 pixels. Esse valor é usado no
draw_cannon()
para posicionar os retângulos que compõem o canhão, e emcreate_laser()
para posicionar o ponto inicial do laser na ponta do canhão. Em geral, o senhor deve tentar evitar a codificação de valores. Esse valor poderia ser definido como uma porcentagem da altura da tela e as alterações apropriadas poderiam ser feitas nodraw_cannon()
para definir a largura e a altura dos três retângulos usados para desenhar o canhão. - A função
create_laser()
modifica uma lista no diretório do programa escopo global do programa. Em geral, é melhor que as funções retornem valores em vez de alterar o estado dos variáveis globais existentes. No entanto, o senhor chamarácreate_laser()
por meio de um pressionamento de tecla, e isso impede que o senhor acesse os objetos retornados.
O programa cria novos Turtle
para cada laser quando o senhor pressiona Espaço. O senhor pode adicionar print(len(lasers))
em create_laser()
para garantir que o programa crie um novo laser quando o senhor pressionar a barra de espaço.
Na próxima seção, o senhor moverá os lasers em cada quadro do jogo. Em seguida, o senhor criará um loop de jogo para levar em conta tudo o que ocorre em cada quadro.
Criar o loop do jogo para mover os lasers
A estrutura de um jogo pode ser dividida em três partes:
- Inicialização: É aqui que o senhor cria os objetos necessários e seus estados iniciais para configurar o ambiente do jogo. Também é aqui que o senhor inclui definições de funções para ações que precisam ocorrer no jogo.
- Loop do jogo: Essa é a parte central de um jogo. Ela verifica e processa as entradas do usuário, altera o estado dos objetos no jogo e outros valores, como a pontuação, e atualiza a exibição para refletir as alterações. O loop do jogo é um loop porque precisa ser executado continuamente para executar o jogo. Cada iteração do loop do jogo representa um quadro do jogo.
- Finalização: Quando o loop do jogo termina, seja porque o jogador ganha ou perde, o programa pode terminar instantaneamente. Normalmente, os jogos exibem uma tela final, mas também podem salvar qualquer resultado em um arquivo e oferecer opções ao jogador, como jogar novamente.
O senhor já lidou com uma parte significativa da inicialização desse turtle
jogo. Agora, é hora de trabalhar no loop do jogo.
A estrutura de um loop de jogo depende da plataforma que o senhor usa. Na plataforma turtle
o senhor precisará escrever seu próprio while
para atualizar o estado dos objetos no jogo e verificar se há eventos, como colisões entre objetos. Entretanto, outros eventos são gerenciados pelo turtle
métodos como o .onkeypress()
. A turtle
executa um loop de eventos, que começa quando o senhor chama turtle.done()
e trata de eventos como o pressionamento de teclas.
O senhor pode comparar o game loop de que precisará ao trabalhar com turtle
com as estruturas de loop de jogo em outros pacotes de jogos Python, como pygame
e arcade
.
Neste turtle
até o momento, o único item que se move é o canhão, que o senhor move com as teclas de seta. Em outras ocasiões, o canhão não se move.
Entretanto, na maioria dos jogos, há itens que precisam se mover ou executar outras ações continuamente. Aqui, os lasers que o senhor cria quando pressiona a barra de espaço precisam se mover para cima em uma quantidade fixa em cada quadro do jogo. Portanto, agora o senhor criará um while
para fazer essas alterações que ocorrem em cada quadro:
O senhor define a função move_laser()
, que aceita um Turtle
objeto. A função limpa o desenho anterior de um laser e move o Turtle
para frente em uma quantidade que representa a velocidade do laser. Essa é a primeira das três chamadas para laser.forward()
.
Para desenhar o laser na tela, o senhor usa uma técnica diferente. Quando criou o canhão, o senhor usou a forma do Turtle
objeto. Para desenhar o laser, o senhor desenhou uma linha com o objeto Turtle
objeto.
Veja o que aconteceu com o create_laser()
e observe que o senhor chamou laser.hideturtle()
para ocultar o sprite, e o senhor chamou laser.pendown()
e laser.pensize(5)
para habilitar o Turtle
desenhe linhas de cinco pixels de largura quando se mover. Agora, o senhor precisará trazer o Turtle
de volta à sua posição inicial no move_laser()
para que ele esteja pronto para o próximo quadro.
O while
contém um for
que itera por todos os lasers e os move para frente. O senhor também pode adicionar window.update()
no loop do jogo para atualizar a tela uma vez em cada quadro. Nesse ponto, o senhor também pode remover window.update()
do draw_cannon()
pois o senhor não precisa mais dele.
Ao executar esse código e pressionar a barra de espaço, o senhor verá lasers disparando do canhão:
Em seguida, o senhor tratará do que fazer com os lasers quando eles saírem da parte superior da tela.
Remover lasers que saem da tela
Quando um laser sai da tela, o senhor não o verá mais. Porém, o Turtle
ainda está na lista de lasers e o programa ainda precisa lidar com esse laser. Mesmo quando o laser está fora de vista, o programa ainda move o laser para cima, até o infinito e além! Com o tempo, a lista de lasers conterá um grande número de objetos que não têm mais nenhuma função no jogo.
Quando o programa move um laser, o gargalo de desempenho é o processo de desenhar o laser na tela. A atualização do Turtle
do objeto y-coordenadas é uma solução rápida. Quando um laser sai da tela, o programa não precisa mais desenhá-lo. Portanto, o senhor precisará disparar muitos lasers antes de observar uma desaceleração perceptível do jogo. No entanto, é sempre uma boa prática remover os objetos de que o senhor não precisa mais.
Para remover esses objetos quando eles saírem da tela, o senhor os remove da lista lasers
e isso impede que o loop do jogo os mova para frente. Mas como o turtle
mantém uma lista interna de todos os Turtle
se o senhor remover os lasers dessa lista interna usando o turtle.turtles()
os objetos também serão removidos da memória:
Observe como o for
itera através de uma cópia do lasers
já que é melhor não fazer um loop em uma lista que está sendo alterada dentro da mesma for
loop.
Neste ponto, o senhor pode adicionar print(len(turtle.turtles()))
e print(len(lasers))
no loop do jogo para confirmar que os lasers são removidos dessas listas quando saem da tela.
Bom trabalho! O senhor está pronto para criar alienígenas e movê-los pela tela.
Etapa 4: Criar e mover os alienígenas
É a calmaria antes da tempestade. O canhão laser está ocioso no momento, pois não há alienígenas invasores para atirar. Chegou a hora de adicionar os alienígenas ao seu jogo.
O senhor já fez a maior parte do trabalho árduo para criar e mover os alienígenas, pois pode lidar com eles de forma semelhante aos lasers. Mas há algumas pequenas diferenças:
- Novos alienígenas aparecem a cada poucos segundos em vez de quando o jogador pressiona uma tecla.
- Os alienígenas aparecem na parte superior da tela de forma aleatória x-em vez de na ponta do canhão.
- O forma e a cor dos alienígenas são diferentes dos lasers.
Exceto por essas pequenas diferenças, o restante do código espelhará o código que o senhor escreveu para criar e mover lasers.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_4/
no link abaixo:
Para iniciar essa parte do projeto, o senhor criará alienígenas que aparecerão em intervalos de tempo regulares. Quando isso estiver pronto, o senhor poderá se concentrar em movê-los.
Criar novos alienígenas
Para começar, o senhor define a nova função create_alien()
e uma lista para armazenar os aliens:
O senhor coloca os alienígenas na parte superior da tela de forma aleatória x-posição. Os alienígenas estão voltados para baixo. O senhor também atribui valores aleatórios para os componentes de cor vermelho, verde e azul, de modo que cada alienígena tenha uma cor aleatória.
Os alienígenas aparecem em intervalos de tempo regulares nesse turtle
jogo. O senhor pode importar os time
e definir um cronômetro para gerar um novo alienígena:
O código agora gera um novo alienígena a cada 1,2 segundos. O senhor pode ajustar esse valor para tornar o jogo mais difícil ou mais fácil. Aqui está o jogo até agora:
Os alienígenas estão surgindo em intervalos regulares, mas estão presos na parte superior da tela. A seguir, o senhor aprenderá a mover os alienígenas pela tela.
Mover os alienígenas
É aqui que o senhor moverá todos os alienígenas da lista de alienígenas do loop do jogo:
Os alienígenas agora estão se movendo continuamente para baixo:
Se os alienígenas não estiverem se movendo na velocidade correta, o senhor pode ajustar a velocidade deles usando um valor diferente para ALIEN_SPEED
. Lembre-se de que a velocidade do jogo varia de acordo com o sistema em que o senhor está trabalhando. O senhor definirá a taxa de quadros do jogo na última etapa deste tutorial, portanto, não precisa se preocupar com a velocidade por enquanto.
Este turtle
está mais perto de ser concluído, mas ainda há algumas etapas importantes que o senhor precisa seguir antes de poder jogar. A primeira dessas etapas é detectar quando um laser atinge um alienígena.
Etapa 5: Determinar quando os lasers atingem os alienígenas
O senhor provavelmente notou no vídeo anterior que os lasers estavam atravessando os alienígenas sem afetá-los. Esse comportamento não impedirá a invasão alienígena! Atualmente, o programa não está verificando se um laser atinge um alienígena. Portanto, o senhor precisará atualizar o código para lidar com esse importante recurso do jogo.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_5/
no link abaixo:
Em cada quadro do jogo, é provável que o senhor tenha vários lasers voando para cima e vários alienígenas caindo para baixo. Portanto, o senhor precisa verificar se algum dos lasers atingiu algum dos alienígenas. Nesta parte do tutorial, o senhor aplicará uma técnica simples para lidar com esse problema: verificará a distância de cada laser em relação a cada alienígena para detectar qualquer acerto.
É verdade que essa não é a opção mais eficiente, mas é boa o suficiente para essa versão simplificada de invasores espaciais.
No loop do jogo, o senhor já tem um loop que itera pela lista de lasers. O senhor pode adicionar outro loop para iterar através de cada alienígena para cada laser:
O novo for
itera através de uma cópia do aliens
e está aninhado dentro do loop for
que itera através do lasers
. O senhor usa aliens.copy()
pois o senhor removerá alienígenas dessa lista em alguns quadros. Certifique-se de evitar alterar a lista que o senhor está usando para iteração.
O código acima mostra um # TODO
em vez do bloco de código necessário. O código que o senhor precisa escrever aqui deve executar as seguintes ações:
- Remover o laser da tela e da memória.
- Remover o alienígena da tela e da memória.
O senhor já escreveu o código para remover o laser. Essas são as linhas que limpam o desenho e removem o Turtle
das duas listas quando um laser deixa a tela:
O senhor deve evitar repetir as mesmas linhas de código. Portanto, o senhor pode colocar essas linhas em uma função e chamá-la duas vezes. Entretanto, essas são as mesmas etapas necessárias para remover o alienígena do jogo. Portanto, o senhor pode escrever uma função que possa remover qualquer sprite e usá-la para os lasers e os alienígenas:
A função remove_sprite()
aceita um Turtle
e uma lista, e limpa o objeto Turtle
e todos os desenhos vinculados a ele. O senhor chama remove_sprite()
duas vezes para os lasers: uma vez quando um laser sai da tela e outra vez quando ele atinge um alienígena. O senhor também chama remove_sprite()
uma vez para os alienígenas no loop do jogo.
Há também dois break
declarações. A primeira é quando o laser sai da tela, já que o senhor não precisa mais verificar se o laser colidiu com um alienígena. A segunda é no interior do for
quando um laser atinge um alienígena, já que esse laser não pode atingir outro alienígena.
Seu jogo deve ter a seguinte aparência agora:
Como o senhor pode ver, tanto o laser quanto o alienígena desaparecem quando há uma colisão. Há apenas mais uma etapa necessária para que o senhor possa jogar esse jogo. Então, será Game Over se um alienígena atingir o nível do piso.
Etapa 6: Encerrar o jogo
O jogo termina quando um dos alienígenas atinge o nível do piso. A invasão alienígena foi bem-sucedida! Então, agora o senhor adicionará uma tela inicial para mostrar Fim do jogo na tela.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_6/
no link abaixo:
O loop do jogo já percorre a lista de alienígenas e o senhor pode verificar se cada alienígena chegou ao solo. Há várias maneiras de interromper o loop do jogo quando isso acontece. Na próxima parte, o senhor criará um sinalizador booleano para controlar quando o while
loop deve parar:
Quando o alienígena y-estiver abaixo do nível do piso, o senhor define o sinalizador booleano game_running
para False
e quebrar o for
loop. O sinalizador indica que o while
para que o loop pare de se repetir.
Antes de fazer essa última alteração, o senhor tinha um loop infinito de while
loop. Agora, o loop não é mais infinito, e o senhor pode adicionar código após o loop que será executado quando o jogo terminar:
O senhor cria um novo Turtle
para escrever texto na tela. O jogo está quase completo agora:
Parabéns, o senhor tem um jogo que funciona! Se quiser, pode parar por aqui, mas há três etapas adicionais que podem ser seguidas se o senhor quiser aperfeiçoar o jogo turtle
um pouco mais.
Etapa 7: Adicionar um cronômetro e uma pontuação
Nesta etapa, o senhor adicionará um cronômetro e exibirá o número de alienígenas atingidos pelo jogador.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_7/
no link abaixo:
Para começar, o senhor criará e exibirá um cronômetro.
Criar um cronômetro
O senhor já importou o time
quando gerou os alienígenas. O senhor pode usar esse módulo para armazenar a hora no início do loop do jogo e calcular quanto tempo se passou em cada quadro. O senhor também pode criar um novo módulo Turtle
para exibir texto na tela:
O senhor escreve o tempo decorrido no canto superior direito da tela no início de cada quadro. No primeiro argumento do .write()
, o senhor usa o especificador de formato :5.1f
para exibir o tempo decorrido com um total de cinco caracteres e um dígito após o ponto decimal.
Adicionar a pontuação
Crie outra variável para manter a pontuação. Aumente a pontuação sempre que o jogador atingir um alienígena e exiba a pontuação abaixo do tempo decorrido:
Isso turtle
agora mostra o número de alienígenas atingidos e o tempo decorrido em cada quadro do jogo:
O jogo está totalmente funcional, mas o senhor notou que o canhão laser salta de uma posição para outra? E, se o senhor quisesse mover o canhão mais rapidamente, os saltos seriam ainda mais perceptíveis. Na próxima etapa, o senhor alterará a forma como o canhão laser se move para torná-lo mais suave.
Etapa 8: Melhorar o movimento do canhão
Na versão atual do jogo, o canhão laser se move em um número fixo de pixels cada vez que o jogador pressiona as teclas de seta para a esquerda ou para a direita. Se quiser mover o canhão mais rapidamente pela tela, o senhor precisa aumentar esses saltos. Nesta etapa do tutorial, o senhor alterará a forma como o canhão se move para tornar o movimento mais suave. Isso pode até aumentar suas chances de salvar o planeta da invasão alienígena!
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_step_8/
no link abaixo:
O canhão de laser se move de forma diferente de como os lasers e os alienígenas se movem. O canhão se move em um passo largo nas funções move_left()
e move_right()
. Essas funções são chamadas quando o senhor pressiona as teclas de seta. Se quiser que o canhão tenha um movimento mais suave, o senhor precisa movê-lo continuamente em incrementos menores. Para isso, o senhor precisa mover o canhão laser no loop do jogo, como os lasers e os alienígenas.
Entretanto, o senhor precisa controlar se o canhão laser está se movendo para a esquerda, para a direita ou se está parado. Para fazer isso, o senhor pode criar uma nova variável para armazenar a direção em que o canhão está se movendo em qualquer ponto do jogo. Aqui estão os três valores que essa nova variável pode ter:
- 1 representa o movimento para a direita
- -1 representa movimento para a esquerda
- 0 indica que o canhão não está se movendo
O senhor pode então alterar esse valor em move_left()
e move_right()
e use-o para controlar o movimento do canhão no loop do jogo:
As teclas de seta esquerda e direita ainda estão vinculadas às mesmas funções, move_left()
e o move_right()
. No entanto, essas funções alteram o valor do atributo de dados cannon.cannon_movement
.
O senhor define isso como um atributo de dados em vez de uma variável padrão. Um atributo de dados é semelhante a uma variável, mas é anexado a um objeto. O Turtle
já tem outros atributos de dados definidos na seção Turtle
mas o .cannon_movement
é um atributo de dados personalizado que o senhor adiciona em seu código.
O motivo pelo qual o senhor precisa usar um atributo de dados em vez de uma variável padrão é para que possa modificar seu valor nas funções. Se o senhor definir uma variável padrão para esse valor, as funções move_left()
e move_right()
precisariam retornar esse valor. Mas essas funções estão vinculadas a chaves e são chamadas de dentro do .onkeypress()
e, portanto, o senhor não pode acessar os dados que elas retornam.
O senhor também diminui o valor de CANNON_STEP
na última modificação para diminuir a velocidade do canhão quando ele se move. O senhor pode escolher um valor que seja adequado para seu sistema.
Ao executar esse código, o senhor perceberá que pode configurar o canhão para se mover para a esquerda ou para a direita e pode alterar sua direção. Mas quando o canhão começa a se mover, ele nunca para. O senhor nunca define cannon.cannon_movement
de volta a 0 no código. Em vez disso, o senhor deseja que esse valor volte a 0 quando soltar as teclas de seta. Use .onkeyrelease()
para conseguir isso:
Agora o senhor pode pressionar e manter pressionadas as teclas de seta para mover o canhão. Quando o senhor solta as teclas de seta, o canhão para de se mover:
O movimento do canhão está muito mais suave. O jogo funciona perfeitamente. No entanto, se tentar executar esse jogo em computadores diferentes, o senhor perceberá que a velocidade do jogo varia. Para compensar isso, talvez seja necessário ajustar os valores de velocidade do canhão, do laser e dos alienígenas, dependendo do tipo de computador que estiver executando o jogo.
Na etapa final deste tutorial, o senhor definirá a taxa de quadros do jogo para que possa controlar a velocidade de execução do jogo em qualquer computador.
Etapa 9: Definir a taxa de quadros do jogo
Cada iteração do while
representa um quadro do jogo. Há várias linhas de código que precisam ser executadas em cada iteração do loop. O tempo que o programa leva para realizar todas as operações no loop depende da velocidade do computador e se o sistema operacional está ocupado com outras tarefas.
Nesta etapa, o senhor fixará a duração de um quadro escolhendo um taxa de quadros.
O senhor pode fazer o download do código como ele será exibido no final desta etapa na pasta chamada source_code_final/
no link abaixo:
Aqui o senhor definirá a taxa de quadros em quadros por segundo e calculará o tempo para um quadro nessa taxa de quadros:
Em seguida, meça o tempo necessário para executar uma iteração do while
loop. Se esse tempo for menor que o tempo necessário para um quadro, pause o jogo até atingir o tempo necessário para um quadro. O loop pode então continuar com a próxima iteração. Enquanto o tempo necessário para executar o loop while
seja menor do que o tempo necessário para um quadro, cada quadro levará a mesma quantidade de tempo depois que a pausa for concluída:
Esse é o momento certo para ajustar os parâmetros do jogo de acordo com suas preferências, como os valores que determinam a velocidade do canhão, dos lasers e dos alienígenas.
E aqui está a versão final do jogo:
O código completo do jogo está na seção recolhível abaixo:
Conclusão
O senhor chegou ao final deste tutorial e escreveu um clone de Space Invaders totalmente funcional. Ao longo do caminho, o senhor explorou vários recursos do turtle
muitos dos quais são semelhantes a ferramentas que o senhor encontrará em outros pacotes gráficos. O senhor também trabalhou com técnicas usadas para animações e jogos.
Neste tutorial, o senhor aprendeu a:
- Projetar e construir um videogame clássico
- Use o
turtle
para criar sprites animados - Adicionar interação com o usuário em um programa baseado em gráficos
- Criar um loop de jogo para controlar cada quadro do jogo
- Use as funções para representar as principais ações do jogo
Agora o senhor pode jogar o tempo que quiser e tentar bater sua pontuação mais alta. Não se esqueça de fazer intervalos!
Próximas etapas
Quando o senhor jogar o jogo por tempo suficiente, ficará muito bom nele. Esse é o momento certo para tornar o jogo mais difícil. Aqui estão algumas idéias de como o senhor pode estender isso turtle
jogo ainda mais:
- Adicionar níveis de dificuldade: O senhor pode aumentar a velocidade dos alienígenas e a taxa de aparecimento após um determinado intervalo de tempo ou quando destruir um certo número de alienígenas. Isso tornará o jogo cada vez mais difícil.
- Limitar o número de lasers: Defina um limite para o número de lasers disponíveis para que o senhor só receba uma recarga após um determinado período de tempo ou quando destruir um determinado número de alienígenas. Isso é o fim de manter a barra de espaço pressionada!
- Criar uma versão com canhão fixo: Modifique o jogo de modo que o canhão não se mova, mas possa girar quando o usuário pressionar as teclas de seta para atirar em direções diferentes. Isso cria uma variação divertida do jogo.
Aproveite a criatividade e escreva sua própria versão desse jogo, e fique à vontade para compartilhar suas versões nos comentários abaixo.