{"id":1062,"date":"2026-08-17T18:09:24","date_gmt":"2026-08-17T21:09:24","guid":{"rendered":"https:\/\/www2.ic.uff.br\/pplay\/?page_id=1062"},"modified":"2026-08-17T18:09:24","modified_gmt":"2026-08-17T21:09:24","slug":"criando-um-pong","status":"publish","type":"page","link":"https:\/\/www2.ic.uff.br\/pplay\/tutoriais\/criando-um-pong\/","title":{"rendered":"Criando um Pong"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Criando a estrutura de arquivos do jogo<\/h2>\n\n\n\n<p>O primeiro passo no desenvolvimento do seu jogo \u00e9 a cria\u00e7\u00e3o do arquivo-fonte. Ap\u00f3s escolher a pasta onde ir\u00e1 armazenar os arquivos do jogo, crie um arquivo chamado <em><strong>pong.py<\/strong><\/em>. Voc\u00ea pode criar esse arquivo utilizando um editor de texto ou IDE de sua prefer\u00eancia. Em seguida, crie uma pasta chamada <em><strong>assets<\/strong><\/em> dentro da mesma pasta do projeto, e coloque nela as duas imagens que usaremos no jogo: <em><strong>bola.png<\/strong><\/em> (a bolinha) e <em><strong>pad.png<\/strong><\/em> (a raquete, usada tanto pelo jogador quanto pela IA).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Importa\u00e7\u00f5es<\/h2>\n\n\n\n<p>Aqui come\u00e7aremos de fato a escrever o c\u00f3digo. Primeiramente importaremos tudo que ser\u00e1 necess\u00e1rio para construir nosso jogo. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from PPlay.sprite import Sprite\nfrom PPlay.window import Window\nfrom PPlay.collision import Collision<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">A classe <a href=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/sprite\/\" data-type=\"link\" data-id=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/sprite\/\"><em>Sprite<\/em><\/a> ser\u00e1 usada para criar a bola e os <em>pads<\/em>. A classe <em><a href=\"https:\/\/www2.ic.uff.br\/pplay\/documentacao\/window\/\" data-type=\"link\" data-id=\"https:\/\/www2.ic.uff.br\/pplay\/documentacao\/window\/\">Window<\/a><\/em> ser\u00e1 respons\u00e1vel por criar e controlar a janela onde o jogo \u00e9 exibido. J\u00e1 a classe <em><a href=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/collision\/\" data-type=\"link\" data-id=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/collision\/\">Colision<\/a><\/em> ser\u00e1 usada para detectar a colis\u00e3o entre a bola e os <em>pads<\/em>.<\/p>\n\n\n\n<p>Al\u00e9m das classes do PPlay, tamb\u00e9m vamos precisar da biblioteca<em> <a href=\"https:\/\/docs.python.org\/3\/library\/random.html\">random<\/a><\/em> do Python, que usaremos para sortear a dire\u00e7\u00e3o da bola a cada in\u00edcio de jogada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import random<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Criando a janela<\/h2>\n\n\n\n<p>Aqui criamos a janela, j\u00e1 passando altura e largura como par\u00e2metros para o construtor: 800 pixels de largura por 600 de altura.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>window = Window(800, 600)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Criando os Sprites e posicionando os pads<\/h2>\n\n\n\n<p>Com a janela criada, \u00e9 hora de criar os tr\u00eas elementos visuais do jogo: a bola e os dois pads. Repare que os dois pads compartilham a mesma imagem (<strong><em>pad.png<\/em><\/strong>) \u2014 o que muda entre eles \u00e9 apenas a posi\u00e7\u00e3o na tela e quem controla cada um:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bola = Sprite('assets\/bola.png')\npad_e = Sprite('assets\/pad.png')\npad_d = Sprite('assets\/pad.png')<\/code><\/pre>\n\n\n\n<p>Agora vamos posicionar os pads. O pad esquerdo (<strong><em>pad_e<\/em><\/strong>), controlado pelo jogador, fica a 10 pixels da borda esquerda da janela. O pad direito (<strong><em>pad_d<\/em><\/strong>), controlado pela IA, fica a 10 pixels da borda direita, para isso, subtra\u00edmos a pr\u00f3pria largura do pad da largura da janela, evitando que ele fique parcialmente fora da tela. Os dois pads come\u00e7am na metade da altura da janela:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pad_e.set_position(10, window.altura \/ 2)\npad_d.set_position(window.largura - pad_d.width - 10, window.altura \/ 2)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pontua\u00e7\u00e3o<\/h2>\n\n\n\n<p>Agora criamos as vari\u00e1veis para que seja poss\u00edvel armazenar a pontua\u00e7\u00e3o de cada lado: <strong><em>pts_player<\/em><\/strong>, para o jogador, e <strong><em>pts_ia<\/em><\/strong>, para a IA:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pts_player = 0\npts_ia = 0<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Constantes de velocidade<\/h2>\n\n\n\n<p>Nesse passo, criamos as constantes que controlam a velocidade e o comportamento do jogo. Concentrar esses valores em constantes, em vez de espalh\u00e1-los pelo c\u00f3digo, facilita bastante o alter\u00e1-las mais tarde:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>VEL_JOGADOR = 400   # pixels por segundo\nVEL_IA = 300        # um pouco mais lenta que o jogador, para a IA ser venc\u00edvel\nZONA_MORTA = 10     # evita a IA tremer quando j\u00e1 est\u00e1 alinhada com a bola\n\nVEL_BOLA_INICIAL = 300\nVEL_BOLA_MAX = 1000\nGANHO_REBATIDA = 25  # quanto a bola acelera a cada rebatida no pad<\/code><\/pre>\n\n\n\n<p><strong><em>VEL_JOGADOR<\/em><\/strong> e <em>VEL_IA<\/em> controlam a velocidade de movimento vertical de cada pad. <strong><em>ZONA_MORTA<\/em><\/strong> \u00e9 a margem de toler\u00e2ncia que evita que a IA fique tremendo para cima e para baixo quando j\u00e1 est\u00e1 praticamente alinhada com a bola. J\u00e1 <strong><em>VEL_BOLA_INICIAL<\/em><\/strong>, <strong><em>VEL_BOLA_MAX<\/em><\/strong> e <strong><em>GANHO_REBATIDA<\/em><\/strong> controlam a bola: a velocidade em que ela come\u00e7a cada jogada, o limite m\u00e1ximo de velocidade que ela pode atingir, e o quanto ela acelera a cada vez que \u00e9 rebatida por um pad.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">resetar_bola()<\/h2>\n\n\n\n<p>Essa fun\u00e7\u00e3o reposiciona a bola no centro da tela e sorteia uma nova dire\u00e7\u00e3o para ela. \u00c9 chamada tanto no in\u00edcio do jogo quanto toda vez que um dos lados marca um ponto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def resetar_bola():\n    bola.set_position(\n        window.largura \/ 2 - bola.width \/ 2, #posiciona o centro da\n        window.altura \/ 2 - bola.height \/ 2  #bola no centro da tela\n    )\n\n    direcao_x = random.choice(&#91;-1, 1])   #escolhe uma dire\u00e7\u00e3o para a bola (esquerda\/direita)\n    direcao_y = random.uniform(-1, 1)    #escolhe uma dire\u00e7\u00e3o para a bola(qu\u00e3o para cima ou baixo ela desloca-se)\n\n    # Normaliza o vetor de dire\u00e7\u00e3o\n    comprimento = (direcao_x ** 2 + direcao_y ** 2) ** 0.5\n\n    direcao_x \/= comprimento\n    direcao_y \/= comprimento\n\n    # Aplica a velocidade normalizada\n    bola.vx = direcao_x * VEL_BOLA_INICIAL\n    bola.vy = direcao_y * VEL_BOLA_INICIAL<\/code><\/pre>\n\n\n\n<p>Primeiro, posicionamos a bola exatamente no centro da janela, compensando metade da largura e da altura da pr\u00f3pria bola. Em seguida, sorteamos uma dire\u00e7\u00e3o horizontal (esquerda ou direita, com igual probabilidade) e uma dire\u00e7\u00e3o vertical qualquer entre -1 e 1.<\/p>\n\n\n\n<p><strong><em>direcao_x<\/em><\/strong> e <strong><em>direcao_y<\/em><\/strong> formam um vetor, e esse vetor precisa ser normalizado, ou seja, ter comprimento igual a 1, antes de virar velocidade de fato. Fazemos isso dividindo cada componente pelo comprimento do vetor, calculado com o teorema de Pit\u00e1goras (<em><strong>comprimento<\/strong><\/em>). Sem essa normaliza\u00e7\u00e3o, uma bola lan\u00e7ada na diagonal se moveria mais r\u00e1pido do que uma lan\u00e7ada na horizontal, deixando o jogo inconsistente. Por fim, multiplicamos o vetor j\u00e1 normalizado por <strong><em>VEL_BOLA_INICIAL<\/em><\/strong>, obtendo <strong><em>vx<\/em><\/strong> e <strong><em>vy<\/em><\/strong>, dois atributos novos que estamos criando agora no objeto <strong><em>bola<\/em><\/strong>, para guardar sua velocidade em cada eixo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">rebater_no_pad(pad)<\/h2>\n\n\n\n<p>Essa fun\u00e7\u00e3o calcula o que acontece quando a bola bate em um dos pads: o novo \u00e2ngulo (baseado em qual parte do pad foi atingida) e o aumento de velocidade da bolinha.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def rebater_no_pad(pad):\n    # Calcula o ponto de impacto da bola em rela\u00e7\u00e3o ao pad\n    centro_pad = pad.y + pad.height \/ 2\n    centro_bola = bola.y + bola.height \/ 2\n\n    # -1 = topo do pad bola vai para cima\n    #  0 = centro bola vai reta\n    #  1 = base do pad bola vai para baixo\n\n    direcao_y = (centro_bola - centro_pad) \/ (pad.height \/ 2)\n\n    # Calcula a nova velocidade\n    velocidade_atual = (bola.vx ** 2 + bola.vy ** 2) ** 0.5\n    nova_velocidade = min(velocidade_atual + GANHO_REBATIDA,VEL_BOLA_MAX) #limitamos a nova velocidade pela\n                                                                          #velocidade m\u00e1xima\n\n    # Define a nova dire\u00e7\u00e3o x\n    direcao_x = 1 if bola.vx &lt; 0 else -1 # se a bola vai para esquerda passa a ir para direita e vice-versa\n\n    # Normaliza o vetor de dire\u00e7\u00e3o\n    comprimento = (direcao_x ** 2 + direcao_y ** 2) ** 0.5\n\n    direcao_x \/= comprimento\n    direcao_y \/= comprimento\n\n    # Aplica a velocidade normalizada\n    bola.vx = direcao_x * nova_velocidade\n    bola.vy = direcao_y * nova_velocidade\n\nresetar_bola()<\/code><\/pre>\n\n\n\n<p>A parte mais interessante dessa fun\u00e7\u00e3o \u00e9 o c\u00e1lculo de <strong><em>direcao_y<\/em><\/strong>. Comparamos o centro da bola com o centro do pad no momento da colis\u00e3o. Se a bola acertou bem no meio do pad, a diferen\u00e7a \u00e9 0 e ela volta reta; se acertou perto do topo, a diferen\u00e7a \u00e9 negativa e a bola sobe; se acertou perto da base, a diferen\u00e7a \u00e9 positiva e a bola desce. Dividir pela metade da altura do pad normaliza esse valor para o intervalo aproximado de -1 a 1.<\/p>\n\n\n\n<p>Em seguida, calculamos a velocidade atual da bola (de novo com o teorema de Pit\u00e1goras, agora sobre <strong><em>vx<\/em><\/strong> e <em><strong>vy<\/strong><\/em>) e somamos <strong><em>GANHO_REBATIDA<\/em><\/strong>, sem deixar passar de <em><strong>VEL_BOLA_MAX<\/strong><\/em>, isso faz o jogo ficar mais r\u00e1pido a cada rebatida. A dire\u00e7\u00e3o horizontal simplesmente se inverte: se a bola vinha da direita, agora vai para a esquerda, e vice-versa. Por fim, assim como em <strong><em>resetar_bola()<\/em><\/strong>, normalizamos o vetor (<strong><em>direcao_x<\/em><\/strong>, <strong><em>direcao_y<\/em><\/strong>) antes de multiplic\u00e1-lo pela nova velocidade, garantindo que a bola sempre se mova na velocidade correta, n\u00e3o importa o \u00e2ngulo de sa\u00edda.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pr\u00e9 Game Loop<\/h2>\n\n\n\n<p>Com as duas fun\u00e7\u00f5es auxiliares prontas, chamamos <strong><em>resetar_bola()<\/em><\/strong> uma \u00fanica vez, fora de qualquer loop, para posicionar e lan\u00e7ar a bola antes da primeira jogada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>resetar_bola()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Game Loop<\/h2>\n\n\n\n<p>Esse \u00e9 o cora\u00e7\u00e3o do nosso jogo: um <strong><em>while True<\/em><\/strong> onde toda a l\u00f3gica do jogo est\u00e1 contida.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Movimento do Pad do Jogador<\/h3>\n\n\n\n<p>O pad esquerdo \u00e9 controlado pelo jogador atrav\u00e9s das setas Cima e Baixo do teclado, usando o m\u00e9todo <strong><em>move_key_y()<\/em><\/strong> do <strong><em><a href=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/sprite\/\" data-type=\"link\" data-id=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/sprite\/\"><em>Sprite<\/em><\/a><\/em><\/strong>. Em seguida, limitamos a posi\u00e7\u00e3o do pad para que ele n\u00e3o ultrapasse o topo ou a base da janela:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pad_e.move_key_y(VEL_JOGADOR)\npad_e.y = max(0, min(pad_e.y, window.altura - pad_e.height))#Limita o quanto o pad pode se mover para cima ou baixo<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Movimento do Pad da IA<\/h3>\n\n\n\n<p>O pad direito \u00e9 controlado por uma IA simples, que persegue verticalmente o centro da bola. Comparamos o centro do pad com o centro da bola e movemos o pad na dire\u00e7\u00e3o correspondente, respeitando a <strong><em>ZONA_MORTA<\/em><\/strong> para evitar tremula\u00e7\u00e3o quando os dois j\u00e1 est\u00e3o praticamente alinhados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>centro_pad_d = pad_d.y + pad_d.height \/ 2\ncentro_bola = bola.y + bola.height \/ 2\n\nif centro_bola &lt; centro_pad_d - ZONA_MORTA:\n    pad_d.move_y(VEL_BOLA_INICIAL * -1)\nelif centro_bola > centro_pad_d + ZONA_MORTA:\n    pad_d.move_y(VEL_BOLA_INICIAL)\n\npad_d.y = max(0, min(pad_d.y, window.altura - pad_d.height))<\/code><\/pre>\n\n\n\n<p>Assim como no pad do jogador, a posi\u00e7\u00e3o do pad da IA tamb\u00e9m \u00e9 limitada com o mesmo padr\u00e3o max\/min, para que ela nunca saia da \u00e1rea jog\u00e1vel.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Movimento da bola<\/h3>\n\n\n\n<p>Movemos a bola de acordo com sua velocidade atual, os valores <strong><em>vy<\/em><\/strong> e <strong><em>vx<\/em><\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bola.move_x(bola.vx)\nbola.move_y(bola.vy)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Colis\u00e3o com o Topo e a Base da Tela<\/h3>\n\n\n\n<p>A bola precisa quicar ao tocar a borda superior ou inferior da janela. Verificamos a posi\u00e7\u00e3o da bola e, ao detectar o contato, invertemos o sinal de <strong><em>vy<\/em><\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if bola.y &lt;= 0:\n   bola.y = 0\n   bola.vy *= -1\nelif bola.y + bola.height >= window.altura:\n   bola.y = window.altura - bola.height\n   bola.vy *= -1<\/code><\/pre>\n\n\n\n<p>Al\u00e9m de inverter <strong><em>vy<\/em><\/strong>, tamb\u00e9m reposicionamos a bola exatamente na borda (<strong><em>bola.y<\/em><\/strong> = 0 ou <strong><em>bola.y<\/em><\/strong> = <strong><em>window.altura<\/em><\/strong> &#8211; <strong><em>bola.height<\/em><\/strong>). Isso evita que a bola fique presa fora da \u00e1rea vis\u00edvel caso ela tenha avan\u00e7ado um pouco al\u00e9m do limite entre um quadro e o outro.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Colis\u00e3o com os Pads<\/h3>\n\n\n\n<p>Aqui usamos a classe <strong><em><em><a href=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/collision\/\" data-type=\"link\" data-id=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/collision\/\">Colision<\/a><\/em><\/em><\/strong>, importada l\u00e1 no in\u00edcio do arquivo, para verificar se a bola colidiu com algum dos pads. <strong>Collision.collided()<\/strong> \u00e9 um m\u00e9todo est\u00e1tico, ent\u00e3o chamamos passando os dois sprites que queremos comparar. Ao detectar colis\u00e3o, reposicionamos a bola encostada no pad (para n\u00e3o atravess\u00e1-lo) e chamamos <strong>rebater_no_pad()<\/strong> para calcular o novo \u00e2ngulo e a nova velocidade:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if Collision.collided(bola, pad_e):\n    bola.x = pad_e.x + pad_e.width  # evita grudar\/atravessar o pad\n    rebater_no_pad(pad_e)\nelif Collision.collided(bola, pad_d):\n    bola.x = pad_d.x - bola.width\n    rebater_no_pad(pad_d)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pontua\u00e7\u00e3o e Reset da Bola<\/h3>\n\n\n\n<p>Por fim, verificamos se a bola saiu completamente da tela pela esquerda ou pela direita. Se saiu pela esquerda, a IA marca ponto; se saiu pela direita, o jogador marca ponto. Nos dois casos, chamamos <strong>resetar_bola()<\/strong> para recome\u00e7ar a jogada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if bola.x + bola.width &lt; 0:\n    pts_ia += 1\n    resetar_bola()\n\nif bola.x > window.largura:\n    pts_player += 1\n    resetar_bola()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Desenhando os Elementos na Tela<\/h3>\n\n\n\n<p>Agora que toda a l\u00f3gica do quadro j\u00e1 foi calculada, chamamos as fun\u00e7\u00f5es de <strong><em>draw<\/em><\/strong> dos <strong><em><a href=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/sprite\/\" data-type=\"link\" data-id=\"http:\/\/www2.ic.uff.br\/pplay\/documentacao\/sprite\/\"><em>Sprites<\/em><\/a><\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bola.draw()\npad_e.draw()\npad_d.draw()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">HUD: FPS e Placar<\/h3>\n\n\n\n<p>Usando o <strong><em><a href=\"https:\/\/www2.ic.uff.br\/pplay\/documentacao\/window\/\">draw_text()<\/a><\/em><\/strong>, desenhamos na tela contador de FPS e Placar. Vale ressaltar que o <strong><em><a href=\"https:\/\/www2.ic.uff.br\/pplay\/documentacao\/window\/\">draw_text()<\/a><\/em><\/strong> \u00e9 uma fun\u00e7\u00e3o relativamente cara e \u00e9 bom evitar cham\u00e1-la mais que o necess\u00e1rio.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>window.draw_text(f\"FPS: {int(window.get_fps())}\", 10, 10, cor=\"green\")\nwindow.draw_text(f\"Player: {pts_player}\", 10, 30, cor=\"green\")\nwindow.draw_text(f\"IA: {pts_ia}\", window.largura - 30, 30, cor=\"green\")<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Atualizando a Janela<\/h3>\n\n\n\n<p>Para fechar o loop, chamamos <strong><em><a href=\"https:\/\/www2.ic.uff.br\/pplay\/documentacao\/window\/\">window.update()<\/a><\/em><\/strong>, que redesenha a tela e processa os eventos do jogo a cada quadro:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>window.update()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pronto! Seu Pong est\u00e1 completo.<\/h2>\n\n\n\n<p>Se voc\u00ea chegou at\u00e9 esta parte do tutorial e o seu jogo funcionou corretamente, parab\u00e9ns! Voc\u00ea acabou de finalizar o seu primeiro <em>Pong<\/em>!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">O que fazer agora?<\/h3>\n\n\n\n<p>Agora que seu jogo est\u00e1 pronto, est\u00e1 na hora de melhor\u00e1-lo! Fa\u00e7a uma lista com os melhoramentos que voc\u00ea deseja fazer em seu jogo e m\u00e3os \u00e0 obra. Caso voc\u00ea n\u00e3o tenha muitas ideias, eis algumas sugest\u00f5es de adi\u00e7\u00f5es que voc\u00ea pode fazer ao seu\u00a0<em>Pong<\/em>:<\/p>\n\n\n\n<ul>\n<li>adicionar uma tela de menu inicial para o jogo;<\/li>\n\n\n\n<li>adicionar efeitos sonoros (rebatida na raquete, ponto marcado, quique na parede etc);<\/li>\n\n\n\n<li>criar uma condi\u00e7\u00e3o de vit\u00f3ria, com uma tela de fim de jogo quando um dos lados atingir uma certa pontua\u00e7\u00e3o;<\/li>\n\n\n\n<li>transformar o jogo em modo 2 jogadores, com o pad direito controlado por outro conjunto de teclas (por exemplo, W e S);<\/li>\n\n\n\n<li>criar n\u00edveis de dificuldade para a IA, ajustando sua velocidade de rea\u00e7\u00e3o e o tamanho da zona morta;<\/li>\n<\/ul>\n\n\n\n<p>As possibilidades s\u00e3o infinitas! Utiliza a sua criatividade e teste os seus limites melhorando esse jogo. Agora s\u00f3 depende de voc\u00ea!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Cr\u00e9ditos do Tutorial<\/strong>:\u00a0Miguel Faria<br>Tutorial baseado no tutorial do <a href=\"https:\/\/www2.ic.uff.br\/pplay\/tutoriais\/criando-um-space-invaders\/\">Space Invaders<\/a> do PPlay original.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Criando a estrutura de arquivos do jogo O primeiro passo no desenvolvimento do seu jogo \u00e9 a cria\u00e7\u00e3o do arquivo-fonte. Ap\u00f3s escolher a pasta onde ir\u00e1 armazenar os arquivos do jogo, crie um arquivo chamado pong.py. Voc\u00ea pode criar esse arquivo utilizando um editor de texto ou IDE de sua prefer\u00eancia. Em seguida, crie uma [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":0,"parent":57,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"tutorial-template.php","meta":{"footnotes":""},"_links":{"self":[{"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/pages\/1062"}],"collection":[{"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/comments?post=1062"}],"version-history":[{"count":19,"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/pages\/1062\/revisions"}],"predecessor-version":[{"id":1083,"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/pages\/1062\/revisions\/1083"}],"up":[{"embeddable":true,"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/pages\/57"}],"wp:attachment":[{"href":"https:\/\/www2.ic.uff.br\/pplay\/wp-json\/wp\/v2\/media?parent=1062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}