Criando jogos e simulações com a biblioteca Pygame

Criando jogos e simulações com a biblioteca Pygame

A habilidade de criar jogos e simulações é algo que acrescenta bastante no currículo de um programador, pois é necessário utilizar em conjunto vários dos conhecimentos essenciais para a sua formação profissional, como estruturas de dados, orientação a objetos, concorrência e paralelismo, interface humano-computador, Inteligência Artificial, dentre outros.

Neste artigo falaremos a respeito dos jogos no geral e como utilizar a biblioteca Pygame do Python para criar projetos desse tipo.

Dependendo da complexidade, desenvolver um jogo será um dos projetos mais desafiadores para um programador, podendo levar meses ou anos para ele ficar completo, pois estamos essencialmente criando todo um novo mundo, com história, personagens, desafios, efeitos sonoros, trilha sonora, efeitos visuais, leis da física e muito mais.

Preparando o ambiente

Para começar um novo projeto, primeiro temos que criar um ambiente virtual e depois instalar a biblioteca do Pygame, para isso execute os comandos a seguir respectivamente no terminal:

Crie um arquivo chamado main.py e duas pastas, uma para colocar imagens e outra para o áudio. Na pasta de imagens você vai colocar arquivos em formato png ou jpg que serão os sprites do seu personagem, o cenário e obstáculos. Já na pasta do áudio, você pode colocar arquivos no formato mp3 que serão a trilha sonora ou efeitos sonoros.

Dentro do arquivo main.py importaremos a biblioteca, algumas variáveis importantes, o mixer para o áudio e a biblioteca random para gerar elementos de forma aleatória:


Agora criaremos a tela e o loop infinito. Esse loop é importante para que o jogo fique sendo executado até que você feche a janela do jogo. Dentro dele, colocaremos uma função de clock do Pygame que serve para limitar a quantidade de vezes que a tela do jogo é atualizada, sem ele, o computador iria rodar o loop o máximo de vezes que conseguisse conforme a sua capacidade, assim, teríamos diferentes experiências em máquinas com diferentes configurações.

O clock previne isso limitando a quantidade de quadros desenhados por segundo (também chamado de Frames Per Second ou FPS):


Dentro do game loop, devemos verificar os eventos para saber se o botão de fechar a janela foi pressionado, se sim, a variável running é definida como false e o loop acaba e então a janela fecha. Ao executar esse código, você verá apenas uma tela preta.

A primeira coisa que podemos fazer é mudar a cor de fundo, para isso chamamos a função fill da janela e passaremos para ela uma tupla contendo três valores, que são referentes às cores vermelho, verde e azul (RGB), os valores vão de 0 à 255 e com diferentes combinações obtemos diferentes cores. Todas as funções para desenhar algo na tela devem ser chamadas antes da função pygame.display.update() dentro do loop. Caso contrário, o que desenhamos não vai aparecer na tela.


Adicionando formas geométricas

Em seguida, adicionaremos formas geométricas à tela. Para adicionar um círculo, basta chamar a função pygame.draw.circle e passar como parâmetro a tela onde vai ser desenhada, uma tupla contendo os valores de RGB, uma tupla com a posição no eixo X e a posição no eixo Y em pixels, o raio do círculo e por fim tem um parâmetro opcional que é para dizer se o círculo vai ser aberto (só a linha da borda) ou todo preenchido, é um valor em pixel referente à espessura da borda, se não for passado, ele será todo preenchido:


Um retângulo é da mesma forma, a diferença é que para ele não é passado o raio e dentro da tupla da posição, também tem que ser especificada a altura e largura do retângulo:


Para desenhar uma linha, temos que passar duas tuplas contendo a posição no eixo X e outra no eixo Y, que vão representar o ponto de início e o ponto onde a linha acaba.


Por fim, outra figura que podemos desenhar é um polígono, para ele é passado no lugar da posição uma lista contendo listas com os valores da posição no eixo X e no eixo Y para cada um dos seus vértices, no exemplo abaixo temos um triângulo:


A forma que fazemos para as coisas se moverem, é modificar esses valores da posição das formas geométricas, esse processo pode ser automático aumentando e diminuindo uma variável fora do loop que é responsável pela posição ou manualmente, pegando os inputs do teclado e mouse. O manual geralmente é utilizado para mover o seu personagem no jogo, enquanto o automático vai mover o restante dos objetos:


Dessa forma, a cada novo processamento do loop, o valor a ser incrementado na posição no eixo X vai aumentar em 1, o que vai fazer o retângulo se mover para a direita na horizontal.

Um movimento oscilatório, que faz o retângulo ir e voltar, poderia ser criado simplesmente com uma condição para verificar se o valor a ser incrementado já passou de um certo ponto, se sim, ele vai começar a diminuir o valor, se não, vai continuar incrementando:


Para detectar uma colisão entre as formas geométricas, basta verificar se a posição de uma está dentro da outra. Para isso várias técnicas podem ser utilizadas, algumas mais eficientes e outras menos. Uma coisa a se levar em consideração na hora de detectar uma colisão é a forma de um objeto, a forma mais simples de se detectar são círculos, pois basta verificar se a distância é menor que a soma dos raios, alguns objetos vão ter formas distintas, mas você pode criar pontos de colisão em forma de círculos posicionados nas bordas do objeto.

Outra coisa a se levar em consideração é a quantidade de objetos na tela, pois se você programar para detectar a colisão de cada objeto com cada objeto, o custo computacional vai ficando exponencialmente mais alto à medida que novos objetos são adicionados. Uma forma de contornar esse problema é separar a tela em blocos e verificar a colisão apenas entre os objetos que estão em cada bloco.

Simulações físicas também podem ser feitas apenas modificando a posição do objeto e detectando colisões com outros objetos, por exemplo, pode ter outra variável que vai incrementar esse valor da variável que utilizamos para modificar a posição, dessa forma a primeira variável seria a velocidade e a segunda que incrementa a primeira seria a aceleração do objeto. Outro exemplo de simulação física seria um movimento circular, que pode ser feito utilizando a biblioteca nativa math para calcular o cosseno de um ângulo que será adicionado a posição X e o seno do mesmo ângulo para adicionar a posição Y.

Adicionando imagens para o plano de fundo e personagens

Para adicionar as imagens utilizamos a função pygame.image.load, passando o caminho para a imagem que queremos carregar e para desenhar na tela utilizamos a função blit da tela passando a imagem e uma tupla contendo a posição X e Y:


Para adicionar o personagem, faremos da mesma forma, carregamos a imagem e depois desenhamos na tela, pode ser que algumas imagens fiquem muito grandes ou muito pequenas, para corrigir isso, utilizamos a função pygame.transform.scale antes de desenhar a imagem na tela:


As imagens são colocadas na ordem que são desenhadas, então aquelas que forem desenhadas primeiro ficam por baixo e as mais recentes ficam em cima. Então quando for desenhar o seu personagem e os outros objetos, você deve desenhá-los depois do plano de fundo.


Assim como as formas geométricas, as imagens possuem, posição X e Y, tamanho e largura. Você pode obtê-los com a função get_rect do objeto da imagem carregada:

Com as informações do retângulo da imagem, você consegue fazer o mesmo que já mencionei com as outras formas geométricas, mover no eixo X e Y, adicionar velocidade, aceleração, detectar colisão, etc.

Gerando naves inimigas e obstáculos aleatoriamente

Apenas utilizando a biblioteca random para gerar números aleatórios, podemos criar uma função para gerar os inimigos, passando os números gerados como parâmetros da posição, velocidade, aceleração e até mesmo diferentes arquivos de imagem. Dessa forma, diferentes inimigos e obstáculos podem ser gerados em diferentes posições. Segue abaixo um exemplo deste algoritmo:


Nesse exemplo verificamos se a quantidade de elementos na tela é menor que um determinado número, se for, ele gera uma probabilidade de adicionar um novo inimigo e se essa probabilidade for menor do que um determinado valor o objeto da nave inimiga, é gerada com os valores aleatórios.

Colocando texto na tela

Para adicionar texto na tela, primeiramente iniciamos a função pygame.font.init e depois criamos um objeto que será a fonte, passando o tipo e o tamanho. Depois utilizamos a função render da fonte passando o texto que queremos, o número 1 para ativar o antialias e uma tupla com os valores RGB:

Nesse exemplo verificamos se a quantidade de elementos na tela é menor que um determinado número, se for, ele gera uma probabilidade de adicionar um novo inimigo e se essa probabilidade for menor do que um determinado valor o objeto da nave inimiga, é gerada com os valores aleatórios.


Adicionando trilha e efeitos sonoros

Uma trilha sonora pode ser adicionada com a função mixer.music.load, ela vai receber como parâmetro o caminho da música. Depois basta chamar a função mixer.music.play com o parâmetro -1 que é para tocar em loop.


Já para os efeitos sonoros, utilizamos a função mixer.Sound, passando o caminho do efeito sonoro e depois chamando a função play.


O som do efeito sonoro pode ser tocado sempre que uma nova ação no jogo ocorrer, por exemplo, o disparo de uma arma laser de uma nave.


Conclusão

Neste artigo vimos o básico sobre a criação de jogos utilizando a biblioteca Pygame. Com os conhecimentos aprendidos aqui, já é possível programar algumas simulações e jogos simples, criando formas e combinando um pouco de matemática para modificar a posição do objeto e algoritmos para detectar colisão. Utilizando conceitos de orientação a objetos, podem ser criados diferentes tipos de jogos com um código mais organizado, sem muita repetição.

A área de desenvolvimento de games é muito ampla e apesar do mercado ser bastante competitivo, vale a pena investir tempo para aprender a criar jogos pois sempre há espaço para jogos que combinem diferentes mecânicas, tecnologias, estilos de arte e trilhas sonoras para criar algo novo.

E esse conhecimento não se restringe aos jogos, você também pode utilizá-lo para criar simulações para trabalhar com robótica, biologia computacional, física de partículas, ciência de foguetes, desenvolvimento web criando sites únicos, dentre várias outras possibilidades.

Até logo!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.