Esta é uma introdução ao Pygame para pessoas que já conhecem Python. Este artigo irá ensinar-lhe os passos para construir um jogo simples em que o jogador se esquiva de bolas quicando.
Passos
Parte 1 de 8: Instalando o Pygame
Etapa 1. Baixe Pygame
Encontre-o para sua plataforma em
Etapa 2. Execute o instalador
Etapa 3. Verifique se a instalação funcionou
Abra um terminal Python. Digite "importar pygame". Se você não vir nenhum erro, o Pygame foi instalado com sucesso.
importar pygame
Parte 2 de 8: Configurando uma janela básica
Etapa 1. Abra um novo arquivo
Etapa 2. Importar Pygame
Pygame é uma biblioteca que fornece acesso a funções gráficas. Se você quiser mais informações sobre como essas funções funcionam, você pode procurá-las no site do Pygame.
import pygame de pygame.locals import *
Etapa 3. Defina a resolução da janela
Você estará criando uma variável global para a resolução da tela para que possa ser referenciada em várias partes do jogo. Também é fácil localizá-lo na parte superior do arquivo para que possa ser alterado posteriormente. Para projetos avançados, colocar essas informações em um arquivo separado seria uma ideia melhor.
resolução = (400, 300)
Etapa 4. Defina algumas cores
As cores no pygame são (RBGA, que variam em valores entre 0 e 255. O valor alfa (A) é opcional, mas as outras cores (vermelho, azul e verde são obrigatórios).
branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0)
Etapa 5. Inicialize a tela
Use a variável de resolução que foi definida anteriormente.
screen = pygame.display.set_mode (resolução)
Etapa 6. Faça um loop de jogo
Repita certas ações em todos os quadros do nosso jogo. Faça um loop que sempre se repetirá para percorrer todas essas ações.
enquanto verdadeiro:
Etapa 7. Pinte a tela
screen.fill (branco)
Etapa 8. Exibir a tela
Se você executar o programa, a tela ficará branca e o programa travará. Isso ocorre porque o sistema operacional está enviando eventos para o jogo e o jogo não está fazendo nada com eles. Assim que o jogo receber muitos eventos não controlados, ele irá travar.
enquanto True:… pygame.display.flip ()
Etapa 9. Lidar com eventos
Obtenha uma lista de todos os eventos que ocorreram em cada quadro. Você só vai se preocupar com um evento, o evento de desistência. Isso ocorre quando o usuário fecha a janela do jogo. Isso também evitará que nosso programa falhe devido a muitos eventos.
enquanto True:… para evento em pygame.event.get (): if event.type == SAIR: pygame.quit ()
Etapa 10. Experimente
Esta é a aparência do código agora:
importar pygame de pygame.locals importar * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame.display.set_mode (resolução) enquanto True: screen.fill (white) pygame.display.flip () para evento em pygame.event.get (): if event.type == QUIT: pygame.quit ()
Parte 3 de 8: Fazendo um objeto de jogo
Etapa 1. Faça uma nova classe e construtor
Defina todas as propriedades do objeto. Você também está fornecendo valores padrão para todas as propriedades.
classe Ball: def _init _ (self, xPos = resolução [0] / 2, yPos = resolução [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball"
Etapa 2. Defina como desenhar o objeto
Use as propriedades que foram definidas no construtor para desenhar a bola como um círculo, bem como para passar uma superfície para a função para desenhar o objeto. A superfície será o objeto da tela que foi criado usando a resolução anterior.
def draw (self, surface): pygame.draw.circle (surface, black, (self.x, self.y), self.radius)
Etapa 3. Faça uma instância da classe e também diga ao loop do jogo para desenhar a bola em cada loop
ball = Ball () enquanto True:… ball.draw (tela)
Etapa 4. Faça o objeto se mover
Crie uma função que atualizará a posição do objeto. Chame essa função em cada loop de jogo.
class Ball:… def update (self): self.x + = self.dx self.y + = self.dy
Etapa 5. Limite a taxa de quadros
A bola se moverá muito rápido porque o loop do jogo está rodando centenas de vezes por segundo. Use o relógio do Pygame para limitar a taxa de quadros a 60 fps.
clock = pygame.time. Clock () enquanto True:… clock.tick (60)
Etapa 6. Mantenha a bola na tela
Adicione verificações na função de atualização para reverter a direção da bola se ela atingir uma das bordas da tela.
class Ball:… def update (self):… if (self.x <= 0 ou self.x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y > = resolução [1]): self.dy * = -1
Etapa 7. Experimente
Esta é a aparência do código agora:
importar pygame de pygame.locals importar * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame.display.set_mode (resolução) classe Ball: def _init _ (self, xPos = resolução [0] / 2, yPos = resolução [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball" def draw (self, surface): pygame.draw.circle (surface, black, (self.x, self.y), self.radius) def update (self): self.x + = self.dx self.y + = self.dy if (self.x <= 0 ou self.x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y> = resolução [1]): self.dy * = -1 ball = Ball () clock = pygame.time. Clock () enquanto True: tela. preencher (branco) ball.draw (tela) ball.update () pygame.display.flip () clock.tick (60) para evento em pygame.event.get (): if event.type == QUIT: pygame.quit ()
Parte 4 de 8: Organizando o jogo
Etapa 1. Use as classes para organizar tudo
O jogo vai ficar mais complicado. Use técnicas orientadas a objetos para organizar seu código.
Etapa 2. Transforme o loop do jogo em uma classe
Como nosso jogo agora tem dados incluindo seus objetos e funções de jogo, faz sentido transformar seu loop de jogo em uma classe.
jogo de classe ():
Etapa 3. Adicione um construtor
Aqui você instanciará alguns objetos do jogo, criará nossa tela e relógio e inicializará o Pygame. O Pygame precisa ser inicializado para usar certos recursos como texto ou som.
class game (): def _init _ (self): pygame.init () self.screen = pygame.display.set_mode (resolução) self.clock = pygame.time. Clock ()
Etapa 4. Tratar eventos em uma função
class game ():… def handleEvents (self): para evento em pygame.event.get (): if event.type == QUIT: pygame.quit ()
Etapa 5. Transforme o loop de jogo em uma função
Chame a função de tratamento de eventos a cada loop.
class game ():… def run (self): while True: self.handleEvents () self.screen.fill (branco) self.clock.tick (60) pygame.display.flip ()
Etapa 6. Lidar com vários objetos do jogo
No momento, esse código deve chamar draw e atualizar em nosso objeto a cada quadro. Isso ficaria confuso se você tivesse muitos objetos. Vamos adicionar nosso objeto a uma matriz e, em seguida, atualizar e desenhar todos os objetos na matriz a cada loop. Agora você pode adicionar facilmente outro objeto e dar a ele uma posição inicial diferente.
class game (): def _init _ (self):… self.gameObjects = self.gameObjects.append (Ball ()) self.gameObjects.append (Ball (100))… def run (self): while True: self.handleEvents () para gameObj em self.gameObjects: gameObj.update () self.screen.fill (branco) para gameObj em self.gameObjects: gameObj.draw (self.screen) self.clock.tick (60) pygame.display.virar()
Etapa 7. Experimente
Esta é a aparência do código agora:
importar pygame de pygame.locals importar * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame.display.set_mode (resolução) classe Bola: def _init _ (self, xPos = resolução [0] / 2, yPos = resolução [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball" def draw (self, surface): pygame.draw.circle (surface, black, (self.x, self.y), self.radius) def update (self): self.x + = self.dx self.y + = self.dy if (self.x <= 0 ou self.x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y> = resolução [1]): self.dy * = -1 class game (): def _init _ (self): pygame.init () self.screen = pygame.display.set_mode (resolution) self.clock = pygame.time. Clock () self.gameObjects = self.gameObjects.append (Ball ()) self.gameObjects.append (Ball (100)) def handleEvents (self): para evento em pygame.event.get (): if event.type == QUIT: pygame.quit () def run (self): while True: self.handleEvent s () para gameObj em self.gameObjects: gameObj.update () self.screen.fill (branco) para gameObj em self.gameObjects: gameObj.draw (self.screen) self.clock.tick (60) pygame.display. flip () game (). run ()
Parte 5 de 8: Adicionando um Objeto Jogador
Etapa 1. Faça uma classe de jogador e um construtor
Você vai fazer outro círculo que é controlado pelo mouse. Inicialize os valores no construtor. O raio é o único valor importante.
class Player: def _init _ (self, rad = 20): self.x = 0 self.y = 0 self.radius = rad
Etapa 2. Defina como desenhar o objeto do jogador
Vai ser da mesma forma que você desenhou os outros objetos do jogo.
class Player: … def draw (self, surface): pygame.draw.circle (surface, red, (self.x, self.y), self.radius)
Etapa 3. Adicione o controle do mouse para o objeto do jogador
Em cada quadro, verifique a localização do mouse e defina a localização dos objetos dos jogadores nesse ponto.
class Player:… def update (self): cord = pygame.mouse.get_pos () self.x = cord [0] self.y = cord [1]
Etapa 4. Adicione um objeto de jogador a gameObjects
Crie uma nova instância de jogador e adicione-a à lista.
class game (): def _init _ (self):… self.gameObjects.append (Player ())
Etapa 5. Experimente
Esta é a aparência do código agora:
importar pygame de pygame.locals importar * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame.display.set_mode (resolução) classe Ball: def _init _ (self, xPos = resolução [0] / 2, yPos = resolução [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball" def draw (self, surface): pygame.draw.circle (surface, black, (self.x, self.y), self.radius) def update (self): self.x + = self.dx self.y + = self.dy if (self.x <= 0 ou self.x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y> = resolução [1]): self.dy * = -1 class Player: def _init _ (self, rad = 20): self.x = 0 self.y = 0 self.radius = rad self.type = "player" def draw (self, surface): pygame.draw.circle (surface, red, (self.x, self.y), self.radius) def update (self): cord = pygame.mouse.get_pos () self.x = cord [0] self.y = cord [1] class game (): def _init _ (self): pygame.init () self.screen = pygame.display.set_ modo (resolução) self.clock = pygame.time. Clock () self.gameObjects = self.gameObjects.append (Player ()) self.gameObjects.append (Ball ()) self.gameObjects.append (Ball (100)) def handleEvents (self): para evento em pygame.event.get (): if event.type == SAIR: pygame.quit () def run (self): while True: self.handleEvents () para gameObj em self.gameObjects: gameObj.update () self.screen.fill (branco) para gameObj em self.gameObjects: gameObj.draw (self.screen) self.clock.tick (60) pygame.display.flip () game (). corre()
Parte 6 de 8: Fazendo os objetos interagirem com o jogador
Etapa 1. Altere as funções de atualização
Para que os objetos interajam, eles precisam ter acesso uns aos outros. Vamos adicionar outro parâmetro para Atualizar para passar na lista gameObjects. Você terá que adicioná-lo ao objeto jogador e aos objetos Bola. Se você tiver muitos objetos de jogo, a herança pode ajudá-lo a manter todas as assinaturas de método iguais.
class Ball: … def update (self, gameObjects): … class Jogador: … def update (self, gameObjects):
Etapa 2. Verifique se há colisões entre o jogador e as bolas
Passe por todos os objetos do jogo e verifique se o tipo dos objetos é bola. Em seguida, use os raios dos dois objetos e a fórmula da distância para verificar se eles estão colidindo. Círculos são realmente fáceis de verificar em colisões. Esta é a maior razão pela qual você não usou alguma outra forma para este jogo.
class Jogador:… def update (self, gameObjects):… para gameObj em gameObjects: if gameObj.type == "ball": if (gameObj.x - self.x) ** 2 + (gameObj.y - self.y) ** 2 <= (gameObj.radius + self.radius) ** 2:
Etapa 3. Encerre o jogo se o jogador "acertar"
Vamos apenas encerrar o jogo por enquanto.
if (gameObj.x - self.x) ** 2 + (gameObj.y - self.y) ** 2 <= (gameObj.radius + self.radius) ** 2: pygame.quit ()
Etapa 4. Experimente
Esta é a aparência do código agora:
importar pygame de pygame.locals importar * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame.display.set_mode (resolução) classe Bola: def _init _ (self, xPos = resolução [0] / 2, yPos = resolução [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball" def draw (self, surface): pygame.draw.circle (surface, black, (self.x, self.y), self.radius) def update (self, gameObjects): self.x + = self.dx self.y + = self.dy if (self.x <= 0 ou self.x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y> = resolução [1]): self.dy * = -1 class Player: def _init _ (self, rad = 20): self.x = 0 self.y = 0 self.radius = rad self.type = "jogador" def draw (self, surface): pygame.draw.circle (surface, red, (self.x, self.y), self.radius) def update (self, gameObjects): cord = pygame.mouse.get_pos () self.x = cord [0] self.y = cord [1] para gameObj em gameObjects: if gameObj.type == "ball": if (gameObj.x - self.x) ** 2 + (gameObj.y - self.y) ** 2 <= (gameObj.radius + self.radius) ** 2: pygame.quit () jogo de classe (): def _init _ (self): pygame.init () self.screen = pygame.display.set_mode (resolution) self.clock = pygame.time. Clock () self.gameObjects = self.gameObjects.append (Player ()) self.gameObjects.append (Ball ()) self.gameObjects.append (Ball (100)) def handleEvents (self): para evento em pygame.event.get (): if event.type == QUIT: pygame.quit () def run (self): while True: self.handleEvents () para gameObj em self.gameObjects: gameObj.update (self.gameObjects) self.screen.fill (branco) para gameObj em self.gameObjects: gameObj.draw (self.screen) self.clock.tick (60) pygame.display.flip () game (). run ()
Parte 7 de 8: Adicionando um controlador de jogo para criar objetos
Etapa 1. Crie uma classe de controlador de jogo
Os controladores do jogo são responsáveis por "executar" o jogo. É diferente da nossa classe de jogo que é responsável por desenhar e atualizar todos os nossos objetos. O controlador adicionará periodicamente outra bola à tela para tornar o jogo mais difícil. Adicione um construtor e inicialize alguns valores básicos. O intervalo será o tempo antes de outra bola ser adicionada.
classe GameController: def _init _ (self, interval = 5): self.inter = interval self.next = pygame.time.get_ticks () + (2 * 1000) self.type = "controlador de jogo"
Etapa 2. Adicione a função de atualização
Isso verificará quanto tempo se passou desde o momento em que a bola foi adicionada ou desde o início do jogo. Se o tempo for maior que o intervalo, você zera o tempo e adiciona uma bola.
class GameController:… def update (self, gameObjects): if self.next <pygame.time.get_ticks (): self.next = pygame.time.get_ticks () + (self.inter * 1000) gameObjects.append (Ball ())
Etapa 3. Dê às bolas velocidades aleatórias
Você precisará usar números aleatórios para tornar o jogo diferente a cada vez. No entanto, as velocidades das bolas agora são um número de ponto flutuante em vez de um inteiro.
class GameController:… def update (self, gameObjects): if self.next <pygame.time.get_ticks (): self.next = pygame.time.get_ticks () + (self.inter * 1000) gameObjects.append (Ball (xVel = aleatório () * 2, yVel = aleatório () * 2))
Etapa 4. Corrija a função de desenho
A função de desenho não aceita floats. Vamos converter a posição da bola em números inteiros antes que as bolas sejam sorteadas.
class Ball:… def draw (self, surface): pygame.draw.circle (surface, black, (int (self.x), int (self.y)), self.radius)
Etapa 5. Defina um método de desenho para o controlador de jogo
Por ser um objeto do jogo, o loop principal tentará desenhá-lo. Você precisará definir uma função de desenho que não faz nada para que o jogo não trave.
classe GameController: … def draw (self, screen): pass
Etapa 6. Adicione o controlador de jogo a gameObjects e remova as 2 bolas
O jogo agora deve gerar uma bola a cada cinco segundos.
class game (): def _init _ (self):… self.gameObjects = self.gameObjects.append (GameController ()) self.gameObjects.append (Player ())
Etapa 7. Experimente
Esta é a aparência do código agora:
importar pygame de importação aleatória importação aleatória de pygame.locals import * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame. display.set_mode (resolution) class Ball: def _init _ (self, xPos = resolution [0] / 2, yPos = resolution [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball" def draw (self, surface): pygame.draw.circle (surface, black, (int (self. x), int (self.y)), self.radius) def update (self, gameObjects): self.x + = self.dx self.y + = self.dy if (self.x <= 0 ou self. x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y> = resolução [1]): self.dy * = -1 class Player: def _init _ (self, rad = 20): self.x = 0 self.y = 0 self.radius = rad self.type = "jogador" def draw (self, surface): pygame.draw.circle (surface, red, (self.x, self.y), self.radius) def update (self, gameObjects): cord = pygame.mouse.get_pos () self.x = cord [0] self.y = cord [1] para gameObj no jogo Objetos: if gameObj.type == "ball": if (gameObj.x - self.x) ** 2 + (gameObj.y - self.y) ** 2 <= (gameObj.radius + self.radius) * * 2: classe pygame.quit () GameController: def _init _ (self, interval = 5): self.inter = interval self.next = pygame.time.get_ticks () + (2 * 1000) self.type = "controlador de jogo "def update (self, gameObjects): if self.next <pygame.time.get_ticks (): self.next = pygame.time.get_ticks () + (self.inter * 1000) gameObjects.append (Ball (xVel = random () * 2, yVel = random () * 2)) def draw (self, screen): pass class game (): def _init _ (self): pygame.init () self.screen = pygame.display.set_mode (resolução) self.clock = pygame.time. Clock () self.gameObjects = self.gameObjects.append (GameController ()) self.gameObjects.append (Player ()) def handleEvents (self): para evento em pygame.event.get (): if event.type == QUIT: pygame.quit () def run (self): while True: self.handleEvents () para gameObj em self.gameObjects: gameObj.update (self.gameObjects) self.screen.fill (branco) para gameObj em self.gameO bjects: gameObj.draw (self.screen) self.clock.tick (60) pygame.display.flip () game (). run ()
Parte 8 de 8: Adicionando uma pontuação e o jogo acabou
Etapa 1. Adicione uma pontuação à classe do controlador de jogo
Crie um objeto de fonte e uma variável de pontuação. Você desenhará a fonte em cada quadro para exibir a pontuação e aumentará a pontuação a cada quadro na atualização.
class GameController: def _init _ (self, interval = 5):… self.score = 0 self.scoreText = pygame.font. Font (None, 12) def update (self, gameObjects):… self.score + = 1 def draw (self, screen): screen.blit (self.scoreText.render (str (self.score), True, black), (5, 5))
Etapa 2. Modifique a forma como o jogo termina
Vamos nos livrar do quit quando o jogador detectar uma colisão. Em vez disso, você definirá uma variável no jogador que o jogo pode verificar. Quando gameOver estiver definido, pare de atualizar objetos. Isso congelará tudo no lugar para que o jogador possa ver o que aconteceu e verificar sua pontuação. Observe que os objetos ainda estão sendo desenhados, apenas não atualizados.
class Player: def _init _ (self, rad = 20):… self.gameOver = False def update (self, gameObjects):… para gameObj em gameObjects: if gameObj.type == "ball": if (gameObj.x - self.x) ** 2 + (gameObj.y - self.y) ** 2 <= (gameObj.radius + self.radius) ** 2: self.gameOver = True class game (): def _init _ (self): … Self.gameOver = False def run (self): while True: self.handleEvents () se não self.gameOver: para gameObj em self.gameObjects: gameObj.update (self.gameObjects) if gameObj.type == "player": self.gameOver = gameObj.gameOver
Etapa 3. Experimente
Esta é a aparência do código finalizado agora:
importar pygame de importação aleatória importação aleatória de pygame.locals import * resolução = (400, 300) branco = (255, 255, 255) preto = (0, 0, 0) vermelho = (255, 0, 0) tela = pygame. display.set_mode (resolution) class Ball: def _init _ (self, xPos = resolution [0] / 2, yPos = resolution [1] / 2, xVel = 1, yVel = 1, rad = 15): self.x = xPos self.y = yPos self.dx = xVel self.dy = yVel self.radius = rad self.type = "ball" def draw (self, surface): pygame.draw.circle (surface, black, (int (self. x), int (self.y)), self.radius) def update (self, gameObjects): self.x + = self.dx self.y + = self.dy if (self.x <= 0 ou self. x> = resolução [0]): self.dx * = -1 if (self.y <= 0 ou self.y> = resolução [1]): self.dy * = -1 class Player: def _init _ (self, rad = 20): self.x = 0 self.y = 0 self.radius = rad self.type = "jogador" self.gameOver = False def draw (self, surface): pygame.draw.circle (surface, red, (self.x, self.y), self.radius) def update (self, gameObjects): cord = pygame.mouse.get_pos () self.x = cord [0] self.y = cord [1] para gameObj em gameObjects: if gameObj.type == "ball": if (gameObj.x - self.x) ** 2 + (gameObj.y - self.y) ** 2 <= (gameObj.radius + self.radius) ** 2: self.gameOver = True class GameController: def _init _ (self, interval = 5): self.inter = interval self.next = pygame.time.get_ticks () + (2 * 1000) self. type = "controlador de jogo" self.score = 0 self.scoreText = pygame.font. Font (Nenhum, 12) def update (self, gameObjects): if self.next <pygame.time.get_ticks (): self.next = pygame.time.get_ticks () + (self.inter * 1000) gameObjects.append (Ball (xVel = random () * 2, yVel = random () * 2)) self.score + = 1 def draw (self, screen): screen.blit (self.scoreText.render (str (self.score), True, black), (5, 5)) class game (): def _init _ (self): pygame.init () self.screen = pygame.display.set_mode (resolution) self.clock = pygame.time. Clock () self.gameObjects = self.gameObjects.append (GameController ()) self.gameObjects.append (Player ()) self.gameOver = False def handleEvents (self): para evento em pygame.event.get (): se ev ent.type == SAIR: pygame.quit () def run (self): while True: self.handleEvents () se não self.gameOver: para gameObj em self.gameObjects: gameObj.update (self.gameObjects) se gameObj. type == "player": self.gameOver = gameObj.gameOver self.screen.fill (branco) para gameObj em self.gameObjects: gameObj.draw (self.screen) self.clock.tick (60) pygame.display.flip () jogo (). correr ()