Escolar Documentos
Profissional Documentos
Cultura Documentos
Trabalho Prático nº 3
Pygame1
Índice
1. Introdução ............................................................................................................. 3
2. Métodos.................................................................................................................. 3
3. Resultados............................................................................................................ 18
3.1. Menu Inicial .................................................................................................. 18
3.2. Inicio do jogo ................................................................................................ 19
3.3. Inimigos a disparar ...................................................................................... 19
3.4. Jogador a disparar ....................................................................................... 20
3.5. Morte de um inimigo .................................................................................. 20
3.6. Jogador alvejado .......................................................................................... 21
3.7. Game Over ................................................................................................... 21
3.8. Token para passar de nivel ........................................................................ 22
3.9. Variedade de níveis ..................................................................................... 23
3.10. Luta com o boss......................................................................................... 23
3.10.1. Luta com o boss – Fase 1 ...................................................................... 24
3.10.2. Luta com o boss – Fase 2 ...................................................................... 24
3.11. Token que duplica o dano ........................................................................ 25
3.12. Vitoria ......................................................................................................... 25
4. Discussão.............................................................................................................. 26
5. Conclusão ............................................................................................................ 26
Referências............................................................................................................... 27
1. Introdução
Este projeto tem como objetivo o desenvolvimento de um jogo utilizado a linguagem
de programação Python.
O jogo desenvolvido é um jogo de plataformas onde o jogador vai poder saltar, correr
e eliminar os vários inimigos que estão em locais fixos no mapa e o seu objetivo é chegar ao
final de cada mapa sem perder as vidas todas para que no final enfrente um Boss no ultimo
nível.
Foram realizadas animações para as entidades mais importantes do jogo, o jogador, os
inimigos e o boss final. O jogador tem animação para quando fica parado, corre ou salta, os
inimigos como vão ficar fixos num local apenas vão ter uma animação e o Boss vai ter duas
animações que vão ser o seu estado normal e a segunda fase. O Boss entra nesta segunda fase
quando a vida chega a metade e faz com que o tamanho do sprite seja maior e tenham uma
aparência um pouco diferente.
Todas as funcionalidades vão ser melhor explicadas nas secções abaixo.
2. Métodos
Para que seja possível o bom funcionamento do jogo, é necessário ter um ideia de
como funciona a programação orientada a objetos sendo que é necessário criar várias classes
com diferentes métodos para as várias entidades do jogo.
A classe que foi mais trabalhosa foi a do jogador. Esta classe é constituída por vários
métodos para que seja possível o movimento, o disparo e as colisões.
Por isso foram criados os seguintes métodos para a classe do jogador:
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.animation_list = []
self.index = 0
self.update_timer = pygame.time.get_ticks()
for i in range(4):
img = pygame.image.load(f'Player/{i}.png')
img = pygame.transform.scale(
img, (int(img.get_width() * 3), int(img.get_height() *
3)))
self.animation_list.append(img)
self.image = self.animation_list[self.index]
self.rect = self.image.get_rect()
self.jumped = False
self.jumping = False
self.vel_y = 0
self.flip = False
self.rect.center = (200, 400)
self.width = self.image.get_width()
self.height = self.image.get_height()
self.in_air = False
O parâmetro animation_list serve para guardar os sprites2 que vão ser utilizados para
fazer as animações do objeto da classe Player que vão ser percorridas de uma forma
sequencial através da variável index que é inicializada a zero com um intervalo de tempo que
vai ser calculado através de outra variável update_timer. De seguida é necessário iniciar o
objeto com a sua primeira animação que vai ser feita através de um ciclo for que vai adicionar
os sprites ao vetor de animações. Outras variáveis também necessárias são variáveis de
controlo para que seja possivel saber se o Player está a saltar ou pode saltar, a velocidade do
salto, o lado para onde o player está virado e a posição onde vai ser inicializado.
Depois de ser inicializado, o Player vai ter acesso ao seguintes métodos:
def idle(self):
self.animation_list = []
for i in range(4):
if self.in_air:
img = pygame.image.load(f'Player/j{i}.png')
else:
img = pygame.image.load(f'Player/{i}.png')
img = pygame.transform.scale(img, (int(img.get_width() * 3),
int(img.get_height() * 3)))
img = pygame.transform.flip(img, self.flip, False)
self.animation_list.append(img)
A função Idle vai dar ao player uma nova animação enquanto este está parado,
dependendo se o player está totalmente parado ou a saltar no mesmo local, os sprites da
animação vão ser diferentes.
Esta função vai fazer com que o player se possa mover e que seja possível ter
animações de corrida e de corrida enquanto salta.
def animation(self):
COOLDOWN = 100
try:
self.image = self.animation_list[self.index]
if pygame.time.get_ticks() - self.update_timer > COOLDOWN:
self.update_timer = pygame.time.get_ticks()
self.index += 1
if self.index >= len(self.animation_list):
self.index = 0
except:
self.index = 0
A função animation é utilizada para fazer a animação dos sprites por ordem e com
intervalos de tempo fixos para que a animação seja bem feita.
def jump(self):
dy = 0
if jumping and self.in_air == False:
self.vel_y = -27
self.in_air = True
Esta função permite fazer o player saltar e ao mesmo tempo verificar se existe alguma
colisão com o chão, isto permite que seja possivel interagir com os mapas que foram criados.
def getFlip(self):
return self.flip
def setFlip(self,aflip):
self.flip = aflip
Estes dois métodos servem para devolver o valor da variável flip da classe Player e para
alterar o valor dessa mesma variável.
def getX(self):
return self.rect.centerx
def getY(self):
return self.rect.centery
Estes dois métodos servem para devolver a posição do Player no ecrã. Vão ser
utilizadas, por exemplo, pelos inimigos para calcularem se vão disparar para a esquerda ou
direita, dependendo da sua posição em relação á do Player.
def colisao(self,x):
for tile in world.obstacle_list:
#check collision in the x direction
if tile[1].colliderect(self.rect.x + x, self.rect.y,
self.width, self.height):
return True
return False
Este método tem como objetivo calcular se o retângulo do player fez colisão com
algum bloco do mapa para que seja possivel a interação do player com o mapa.
Este método tem como objetivo criar balas que se vão deslocar na tela de jogo até que
colidam com algum objeto e as remova.
def reset(self):
self.rect.center = (200, 400)
Este método, quando chamado, vai desenhar o jogado na posição onde este inicia o
jogo.
def draw(self):
display.blit(self.image, self.rect)
class Enemy(pygame.sprite.Sprite):
def __init__(self,x,y):
super().__init__()
self.animation_list = []
self.alive = True
self.index = 0
self.flip = True
self.update_timer = pygame.time.get_ticks()
self.vel_y = 0;
for i in range(4):
img = pygame.image.load(f'enemy/i{i}.png')
img = pygame.transform.flip(img,self.flip, False)
img = pygame.transform.scale(img, (int(img.get_width() * 3),
int(img.get_height() * 3)))
self.animation_list.append(img)
self.image = self.animation_list[self.index]
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.width = self.image.get_width()
self.height = self.image.get_height()
def whereisplayer(self,playerx):
if self.rect.centerx < playerx:
self.flip = False
else :
self.flip = True
Este método tem como objetivo virar o inimigo para o lado onde se encontra o player.
Vai ser passado como parâmetro a posição do jogador para que tal seja feito.
def animation(self):
COOLDOWN = 200
try:
self.image = self.animation_list[self.index]
if pygame.time.get_ticks() - self.update_timer > COOLDOWN:
self.update_timer = pygame.time.get_ticks()
self.index += 1
if self.index >= len(self.animation_list):
self.index = 0
except:
self.index = 0
Esta função tal como no player vai fazer o controlo da transição entre sprites.
def createBullet_left(self, name):
pygame.mixer.Channel(4).play(pygame.mixer.Sound('enemy_gun.wav'))
return EnemyBullet_left(name, self.rect.centerx-10,
self.rect.centery-15)
Estes dois métodos são responsáveis por criar balas que vão ser adicionadas ao vetor
de balas para a esquerda ou direita. O vetor para onde vai ser adicionada a bala depende da
posição do player e esta vai ser determinada através dos métodos getX da classe player.
def hit(self,bullet):
if self.rect.colliderect(bullet):
self.kill
Este método vai determinar quando o inimigo é atingido por uma bala do player, e se
for, vai eliminar o objeto inimigo em questão.
def move(self,scroll):
self.rect.centerx += scroll
def gravity(self):
dy = 0
self.vel_y += 2
if self.vel_y > 10:
self.vel_y = 10
dy += self.vel_y
for tile in world.obstacle_list:
if tile[1].colliderect(self.rect.x, self.rect.y + dy,
self.width, self.height):
if self.vel_y < 0:
dy = tile[1].bottom - self.rect.top
self.vel_y = 0
elif self.vel_y >= 0:
self.in_air = False
dy = tile[1].top - self.rect.bottom
self.vel_y = 0
self.rect.y += dy
Este método consiste em puxar o jogador para baixo simulando assim a gravidade do
personagem. Para isso é definida uma variável que vai auxiliar o cálculo da altura que o
personagem irá descer em relação á altura que esta. Em geral, apenas as primeiras 6 linhas
deste código já fornecem gravidade ao personagem mas, para que o jogador não caia para o
infinito, é necessário o resto do código que vai verificar se existe colisão do personagem com
algum dos blocos do mapa e alterar o valor da variável dy para o valor necessário. Caso se
verifique que houve impacto com algum bloco é de seguida verificada a velocidade y do
jogador o que vai permitir descobrir se o jogador estava a cair ou a saltar quando colidiu com
o bloco. Caso ele esteja a saltar a posição vertical da aresta superior do retângulo que define o
personagem será igualada á posição vertical da aresta inferior do bloco em que colidiu. Caso
contrário a posição vertical da aresta inferior do personagem será igualada á superior do bloco
em que colidiu. Por fim a posição do jogador é atualizada em relação ao dy.
def getX(self):
return self.rect.centerx
def getY(self):
return self.rect.centery
Tal como no player, foram criados estes métodos. Apesar de não terem sido
utilizados, durante uma fase inicial do desenvolvimento do jogo estes métodos foram utilizados
para determinar a trajetória que a bala do inimigo deveria ter até chegar á posição inicial do
jogador. Apesar de não ter sido implementada, mantivemos as funções caso fosse necessário.
def draw(self):
display.blit(self.image, self.rect)
class EnemyBullet_right(pygame.sprite.Sprite):
def __init__(self, name, x, y):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.width = self.image.get_width()
self.height = self.image.get_height()
def update(self,player,stats):
self.rect.centerx += 10
if self.rect.centerx == 800:
self.kill()
if self.rect.colliderect(player):
stats.updateHP()
self.kill()
Este método vai atualizar a posição da bala dependendo da direção para onde esta vai
ser disparada. Por fim vai ser verificado se existe, ou não, colisão entre o jogador ou o
terreno.
class PlayerBullet(pygame.sprite.Sprite):
def __init__(self,name,x,y):
super().__init__()
self.path = 5
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.width = self.image.get_width()
self.height = self.image.get_height()
Esta classe é bastante vai ser responsável por criar as balas do jogador, vão ter um
parâmetro a mais do que a classe EnemyBullet_right que vai ser self.path que corresponde ao
caminho que a bala vai percorrer, se for positivo vai se deslocar para a direita, caso contrario
vai se mover para a esquerda.
def setPath(self,condition):
if condition:
self.path = -10
else :
self.path = 10
Este método vai alterar o self.path para positivo ou negativo para dar a direção das
balas do jogador.
def update(self):
self.rect.centerx += self.path
pygame.mixer.Channel(5).play(pygame.mixer.Sound('enemy_death.wav'))
self.kill()
_enemy.setAlive(False)
_enemy.kill()
for _boss in gameboss:
if self.rect.colliderect(_boss.rect.x, _boss.rect.y,
_boss.width, _boss.height):
pygame.mixer.Channel(1).play(pygame.mixer.Sound('hit.wav'))
_boss.damage()
self.kill()
O jogador também tem uma barra de vida que é também uma classe e os seus
métodos são os seguintes:
class Stats(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.index = 0
self.image = pygame.image.load(f'Stats/hp_0.png')
self.rect = self.image.get_rect()
self.rect.center = (60,15)
Esta classe vai servir para criar uma barra de vida. É constituída pelos parâmetros
index que vai ser utilizado para alterar o sprite que vai corresponder á vida atual do player.
Esta classe é constituída pelos seguintes métodos:
def updateHP(self):
self.index += 1
def gethp(self):
return self.index
Este método vai devolver a vida do player que corresponde ao index, se este tiver o
valor de seis então o jogador não tem mais vidas e vai recomeçar o jogo.
def reset(self):
self.image = pygame.image.load(f'Stats/hp_0.png')
self.rect = self.image.get_rect()
self.index = 0
Este método vai fazer com que o jogar tenha todas as vidas de novo. Este vai ser
chamado cada vez que o player passe de nível sendo que vai necessitar mais do que uma vida
por nível.
def draw(self):
display.blit(self.image, self.rect)
class Boss(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.animation_list = []
self.index = 0
self.damageplayer = True
self.second_stage = False
self.flip = True
self.stop = False
self.hp = 20
self.update_timer = pygame.time.get_ticks()
self.damage_ = 1
for i in range(4):
img = pygame.image.load(f'boss/{i}.png')
img = pygame.transform.flip(img, self.flip, False)
img = pygame.transform.scale(img, (int(img.get_width() * 2),
int(img.get_height() * 2)))
self.animation_list.append(img)
self.image = self.animation_list[self.index]
self.width = self.image.get_width()
self.height = self.image.get_height()
self.rect = self.image.get_rect()
self.rect.center = (x, y)
Os objetos da casse Boss são iniciados de uma forma semelhante á do player e inimigo
, mas, este vai ter parâmetros adicionais como second_stage que vai fazer o Boss do jogo
entrar na segunda fase, o parâmetro hp que vai corresponder á vida do Boss, damage_ que vai
corresponder ao valor que vai ser subtraído á vida do boss e finalmente stop que vai fazer o
Boss parar durante poucos segundos cada vez que toque no jogador para que seja possivel ao
jogador que se possa reposicionar.
def secondstage(self):
if self.second_stage == False:
self.second_stage = True
self.rect.y -= 100
self.animation_list = []
for i in range(4):
img = pygame.image.load(f'boss/e{i}.png')
img = pygame.transform.flip(img, self.flip, False)
img = pygame.transform.scale(
img, (int(img.get_width() * 3), int(img.get_height() *
3)))
self.animation_list.append(img)
Este método é responsável por alterar o estado do Boss. Quando este método é
chamado, o Boss vai entrar no segundo estado que vai alterar os sprites de animação e o
tamanho deles o que vai fazer com que o jogador tenha de ser mais cuidadoso durante a luta
com o Boss
def animation(self):
COOLDOWN = 100
try:
self.image = self.animation_list[self.index]
Este método tal como nas outras classes onde existe, vai fazer a animação dos sprites
a um determinado intervalo de tempo, neste caso 100 milissegundos.
if x > self.rect.centerx:
self.rect.centerx += 1
Este método leva como parâmetros a posição X do jogador, depois, comparando com
a posição do Boss, este vai se movimentar para a esquerda ou direita até chegar á posição do
jogador.
def gethp(self):
return self.hp
Este método vai devolver o valor da variável hp do boss que vai ser importante para
depois o fazer entrar na segunda fase.
def setDamage(self):
self.damage_ = 2
Este método vai se chamado para aumentar o valor que vai ser subtraído á vida do
Boss, para que este método seja chamado o jogador vai ter de colidir com um objeto que vai
estar escondido no mapa final na luta contra o Boss.
def damage(self):
self.hp -= self.damage_
Este é o método que vai remover vida ao Boss dependendo do valor da variável
damage_ .
def hit(self,player,stats):
if self.rect.colliderect(player):
self.stop = True
if self.damageplayer == True:
pygame.mixer.Channel(2).play(pygame.mixer.Sound('boss.wav'))
self.damageplayer = False
stats.updateHP()
Sempre que existir uma colisão com o jogador, este método vai se chamado e vai
chamado e vai alterar o valor das variáveis stop e damageplayer, estas que servem para
controlar o dano que o boss vai causar ao jogador e para parar o boss durante alguns
segundos para dar tempo ao jogador para se reposicionar.
def continuar(self):
self.stop = False
self.damageplayer = True
Passado alguns segundos depois do Boss atacar o jogador, as variáveis que foram
anteriormente alteradas, vão voltar ao seu estado normal para que o Boss se possa voltar a
mover e causar dano ao jogador.
def move(self,scroll):
self.rect.centerx += scroll
Este método vai fazer com que o boss acompanhe o movimento do mapa.
def bosskill(self):
if self.hp <= 0:
self.kill()
self.bosskillsound()
return True
return False
Quando o Boss for derrotado, este método vai ser chamado, que vai eliminar o objeto
da classe Boss, e retorna um boolean que vai desbloquear a tela de vitoria para o jogador.
Para fazer uma imagem de fundo chamativa foi necessário criar duas classes, uma para
carregar imagens de fundo com animações para a resolução especifica da janela de jogo e outra
apenas para inserir imagens de fundo.
class Background(pygame.sprite.Sprite):
def __init__(self,name,x,y):
super().__init__()
self.index = 0
self.update_timer = pygame.time.get_ticks()
img = pygame.image.load(name)
self.image = pygame.transform.scale(img, (int(img.get_width() *
1.85), int(img.get_height() * 1.85)))
self.rect = self.image.get_rect()
self.rect.center = (x,y)
A classe Background vai ter a função de inicializar imagens e fundo para depois serem
feitas animações. Foi utilizado para fazer as animações do menu inicial do jogo. Os métodos
desta classe são os seguintes :
def animation(self,acooldown,move):
COOLDOWN = acooldown
if pygame.time.get_ticks() - self.update_timer > COOLDOWN:
self.update_timer = pygame.time.get_ticks()
self.rect.centerx += -move
if self.rect.centerx <= 0:
self.rect.centerx = 1060
Este método vai fazer uma animação da própria imagem, movendo-a para a esquerda
até chegar a um limite. Quando o limite é alcançado, a posição da imagem é reposta para que a
animação pareça continua.
class LoadImage(pygame.sprite.Sprite):
def __init__(self,name,y):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = (400,y)
A classe LoadImage apenas vai carregar imagens que vão ser utilizadas em várias partes
de jogo, como por exemplo, a imagens de “Game Over” , “Victory” e de “Restart”.
Para que o jogador consiga passar de nível, foi criado uma classe Token que vai criar
objetos que vão ser colocados no final de cada nível. Quando o jogador colide com esses
Tokens, vai ser mostrado o nível seguinte. Existe uma variação dos Tokens que servem para
amplificar o dano que o jogador vai causar ao Boss, este Token vai ser introduzido no ultimo
nível.
class Token(pygame.sprite.Sprite):
def __init__(self,x,y,tipo):
super().__init__()
self.tipo = tipo
if self.tipo == 1:
name = "next.png"
else:
name = "upgrade.png"
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.level = 0
def update(self,player):
if self.rect.colliderect(player):
if self.tipo == 1:
self.kill()
self.level += 1
return True
else:
if level >= 3:
for _boss in gameboss:
_boss.setDamage()
self.kill()
return False
O método update ter duas funções dependendo do tipo do objeto. Se o tipo for 1
então vai ser um Token de passagem de nível, se for de outro tipo, vai servir para aumentar o
dano que o jogador vai causar ao Boss.
def move(self,scroll):
self.rect.centerx += scroll
Este método vai fazer com que o Token acompanhe o movimento do mapa.
Por fim a ultima classe que foi criada foi a classe World que vai carregar através de
ficheiros .csv os mapas do jogo. Isto é possível porque é aplicada uma grelha na janela de jogo
e cada espaço dessa grelha vai ser preenchido com um sprite de uma determinada dimensão.
O ficheiro .csv é necessário para guardar os números que vão depois corresponder ao nome
de ficheiros .png. Os métodos utilizados nessa classe foram os seguintes :
def __init__(self):
self.obstacle_list = []
Este método inicia o array que vai armazenar todos os obstáculos presentes no mapa
para depois poder ser usado para verificar a colisão dos personagens com o mapa.
if tile == 4:
nextlevel = Token(x*TAMANHO, y*TAMANHO,1)
next_level.add(nextlevel)
elif tile == 5:
enemy = Enemy(x*TAMANHO-20, y*TAMANHO-20)
all_enemy.add(enemy)
elif tile == 6:
leboss = Boss(x*TAMANHO,y*TAMANHO)
gameboss.add(leboss)
elif tile == 7:
Damage_Boost = Token(x*TAMANHO, y*TAMANHO,2)
next_level.add(Damage_Boost)
Este é o método que vai processar cada número presente no ficheiro csv que
representa o mapa. Para cada número que encontrar em cada célula do ficheiro csv vai
adicionar o respetivo bloco ao mundo. Caso o número esteja entre 0 e 3 será adicionado ao
array dos obstáculos já que estes são os blocos que o personagem utiliza para andar. Caso seja
o número 4, será adicionado um “token” que vai permitir ao utilizador interagir com ele e
passar para o próximo nível. Para o caso em que o número é 5, é adicionado um inimigo na
posição atual sendo que o 6 adiciona o boss. O numero 7 cria um “token” que permite ao
personagem duplicar o seu dano, passa assim a dar 2 de dano ao boss.
def removemap(self):
self.obstacle_list = []
Este método vai remover todos os blocos sólidos inseridos na lista de obstáculos,
fazendo com que o mapa desapareça do ecrã do jogador.
def screen_scroll(self,scroll):
for tile in self.obstacle_list:
tile[1][0] += scroll
Este método vai fazer com que o mapa mova dependendo da posição do jogador para
que seja possível construir mapas maiores do que o tamanho da janela com que o jogo é
iniciado.
3. Resultados
Nesta secção do relatório vão ser mostradas imagens do jogo, com uma breve
explicação acerca do que se está a passar, dos resultados expectados e obtidos.
Esta será a interface que o utilizador irá observar ao entrar no jogo pela primeira vez.
Aqui, ao pressionar qualquer tecla o jogo irá começar como se pode observar na imagem
seguinte.
Aqui comeca então a aventura do jogador, 6 vidas e muitos inimigos pela frente
prontos para o impedirem de chegar ao seu lider.
Como referido os inimigos vão fazer de tudo para impedir o jogador de chegar ao fim
inclusive disparar balas a partir do seu peito de cyborg. Podemos então observar na imagem
acima os inimigos a disparar apenas quando o jogador se aproxima deles.
Quando o jogador dispara contra os inimigos ele morrem apenas com 1 tiro como se
pode observar na imagem acima.
Quando o jogador é alvejado ele perde uma vida por cada tiro que sofre, na imagem
acima podemos observar que o jogador já foi alvejado 2 vezes. Caso o jogador perca as 6 vidas
ele irá morrer e será mostrada a tela persente na imagem abaixo mostrada.
3.7. Game Over
Ao aparecer esta tela o utilizador terá de pressionar a tecla “R” para voltar a jogar. Ira
voltar para o menu inicial (Imagem 1) onde pode voltar a jogar. Isto implica ele começar o jogo
novamente no nível 1 e com a vida cheia.
3.12. Vitoria
Ao derrotar o boss surgira o overlay da vitoria informando o jogador de que ganhou o
jogo. Neste overlay o jogador poderá carregar R para voltar ao menu inicial.
4. Discussão
Na resolução deste projeto foram utilizadas cerca de 6 horas semanais o que
corresponde a cerca de 18 horas no total.
Foi conseguido fazer o pretendido no jogo, os fundamentais do jogo funcionam
bastante bem que são os movimentos do jogado e do Boss, as colisões, o disparo de balas
tanto do jogador como dos inimigos e finalmente as animações que foi uma parte bastante
divertida de fazer.
As forças do trabalho estão nas colisões entre o jogador e os obstáculos, que é
essencial para o bom funcionamento do jogo e as animações para dar ao utilizador satisfação
enquanto joga. Estes dois tópicos foram bastante trabalhados. Para isso assistimos alguns
vídeos de um canal que encontramos no Youtube que nos foi muito útil.3
Achamos este trabalho muito interessante de fazer já que nos mostra uma das
maneiras de criar um jogo em 2D. Existem maneiras mais fáceis de o fazer já que raramente se
encontram jogos criados em Pygame atualmente.
Tivemos algumas dificuldades no inicio do desenvolvimento do jogo já que ainda não
estávamos muito bem decididos com o jogo que iriamos fazer, isto fez com que perdêssemos
um pouco de tempo a criar muitos métodos que acabaram por nem ser usados no jogo final.
Por fim quando chegamos a um veredicto do jogo que iriamos desenvolver foi tudo
rapidamente desenvolvido por ambos.
Mais para o fim do desenvolvimento foi-nos sugerido pelo professor utilizar a
ferramenta do Git que permite sincronizar o ficheiro em ambos os computadores sem ser
necessário utilizar ferramentas externas tais como o Gmail, Discord, entre outras. Esta
ferramenta ajudou muito já que sempre que um de nos fazia uma alteração podia dar commit á
alteração e essa erá mostrada ao outro junto dos detalhes do que tinha sido alterado.
5. Conclusão
Pode-se então concluir que é possível desenvolver alguns jogos simples em Pygame
com um pouco de conhecimento sobre o sistema. Isto é, este projeto foi desenvolvido com o
conhecimento abordado em aulas que decorreram em 2 semanas ou menos o que totaliza
menos de 10 horas de aulas sobre o Pygame, logo claramente com um pouco mais de
conhecimento e tempo é possível desenvolver muitos jogos que são muito mais complexos
que o que foi desenvolvido por nós. Gostamos muito de programar em Pygame e das
funcionalidades que ele dispõem para a criação de jogos. Concluímos também que a utilização
de classes facilita muito a organização do código já que possibilita ter as funções de cada
objeto dentro dele.
Referências
1. Pygame Front Page — pygame v2.1.4 documentation. https://www.pygame.org/docs/.