Aula 03 – Criando games em python – Adicionando os itens ao jogo
Adicionando os itens ao jogo
Voltar para página principal do blog
Todas as aulas desse curso
Aula 02
Aula 04
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Hostinger
Digital Ocean
One.com
Para baixar o código acesse o link abaixo:
https://github.com/toticavalcanti/curso_python_games/Jogo_Breakout/aula_03/
Link da documentação oficial do Tkinter:
https://tkdocs.com/
Dicas de livros relacionados:
O código completo dessa aula é esse, o que tá em azul é o que foi inserido de novo:
import tkinter as tk
class GameObject(object):
def __init__(self, canvas, item):
self.canvas = canvas
self.item = item
def get_position(self):
return self.canvas.coords(self.item)
def move(self, x, y):
self.canvas.move(self.item, x, y)
def delete(self):
self.canvas.delete(self.item)
class Ball(GameObject):
def __init__(self, canvas, x, y):
self.radius = 10
self.direction = [1, -1]
self.speed = 10
item = canvas.create_oval(x-self.radius, y-self.radius,
x+self.radius, y+self.radius,
fill='white')
super(Ball, self).__init__(canvas, item)
class Paddle(GameObject):
def __init__(self, canvas, x, y):
self.width = 80
self.height = 10
self.ball = None
item = canvas.create_rectangle(x - self.width / 2,
y - self.height / 2,
x + self.width / 2,
y + self.height / 2,
fill='blue')
super(Paddle, self).__init__(canvas, item)
def set_ball(self, ball):
self.ball = ball
def move(self, offset):
coords = self.get_position()
width = self.canvas.winfo_width()
if coords[0] + offset >= 0 and coords[2] + offset <= width:
super(Paddle, self).move(offset, 0)
if self.ball is not None:
self.ball.move(offset, 0)
class Brick(GameObject):
COLORS = {1: '#999999', 2: '#555555', 3: '#222222'}
def __init__(self, canvas, x, y, hits):
self.width = 75
self.height = 20
self.hits = hits
color = Brick.COLORS[hits]
item = canvas.create_rectangle(x - self.width / 2,
y - self.height / 2,
x + self.width / 2,
y + self.height / 2,
fill=color, tags='brick')
super(Brick, self).__init__(canvas, item)
def hit(self):
self.hits -= 1
if self.hits == 0:
self.delete()
else:
self.canvas.itemconfig(self.item,
fill=Brick.COLORS[self.hits])
class Game(tk.Frame):
def __init__(self, master):
super(Game, self).__init__(master)
self.lives = 3
self.width = 610
self.height = 400
self.canvas = tk.Canvas(self, bg='#aaaaff',
width=self.width,
height=self.height,)
self.canvas.pack()
self.pack()
self.items = {}
self.ball = None
self.paddle = Paddle(self.canvas, self.width/2, 326)
self.items[self.paddle.item] = self.paddle
for x in range(5, self.width - 5, 75):
self.add_brick(x + 37.5, 50, 2)
self.add_brick(x + 37.5, 70, 1)
self.add_brick(x + 37.5, 90, 1)
self.hud = None
self.setup_game()
self.canvas.focus_set()
self.canvas.bind('',
lambda _: self.paddle.move(-10))
self.canvas.bind('',
lambda _: self.paddle.move(10))
def setup_game(self):
self.add_ball()
self.update_lives_text()
self.text = self.draw_text(300, 200,
'Press Space to start')
self.canvas.bind('', lambda _: self.start_game())
def add_ball(self):
if self.ball is not None:
self.ball.delete()
paddle_coords = self.paddle.get_position()
x = (paddle_coords[0] + paddle_coords[2]) * 0.5
self.ball = Ball(self.canvas, x, 310)
self.paddle.set_ball(self.ball)
def add_brick(self, x, y, hits):
brick = Brick(self.canvas, x, y, hits)
self.items[brick.item] = brick
def draw_text(self, x, y, text, size='40'):
font = ('Helvetica', size)
return self.canvas.create_text(x, y, text=text, font=font)
def update_lives_text(self):
text = 'Lives: %s' % self.lives
if self.hud is None:
self.hud = self.draw_text(50, 20, text, 15)
else:
self.canvas.itemconfig(self.hud, text=text)
def start_game(self):
pass
if __name__ == '__main__':
root = tk.Tk()
root.title('Breakout Game')
game = Game(root)
game.mainloop()
Vamos a explicação do código.
Agora que a organização de nossos itens está separada nessas classes de nível superior, podemos estender o método __init__() da nossa classe Game.
Inicialização
Essa inicialização é mais complexa do que a que vimos na aula passada.
O master que o __init__() do Game recebe como parâmetro, é sua classe pai( tk.Frame ), que será passado para a nova instância da classe Game quando for inicializada.
Nós podemos dividir a inicialização em duas seções:
Primeira, a instanciação do objeto jogo e sua inserção no dicionário self.items.
Este atributo contém todos os itens da tela que podem colidir com a bola, portanto, adicionamos apenas os tijolos e o rebatedor do jogador.
As chaves são referências aos itens da tela e os valores são os objetos do jogo correspondentes.
Vamos usar esse atributo mais tarde na verificação de colisão, quando teremos os itens em colisão e precisaremos buscar o objeto do jogo.
E a segunda, a ligação da chave de entrada, através do Canvas widget.
A chamada canvas.focus_set () define o foco na tela, para que os eventos de entrada sejam diretamente vinculados a esse widget.
Em seguida, vinculamos as teclas esquerda e direita ao método move() do rebatedor e à barra de espaço para acionar o início do jogo.
Graças à construção lambda, podemos definir funções anônimas como manipuladores de eventos.
Como o argumento de retorno de chamada do método bind() é uma função que recebe um evento Tkinter como argumento, definimos um lambda que ignora o primeiro parâmetro( lambda _: <expressão> ).
Adiciona Bola e Adiciona Tijolo
Nossos novos métodos add_ball() e add_brick() são usados para criar objetos de jogo e executar uma inicialização básica.
O primeira cria uma nova bola em cima da rebatedor do jogador e o segundo é um atalho para adicionar uma instância do tijolo( brick ).
Desenha o Texto
O método draw_text() será usado para exibir mensagens de texto na tela.
O item criado com canvas.create_text() é retornado e pode ser usado para modificar as informações.
Mostra e Atualiza o número de vidas
O método update_lives_text() exibe o número de vidas restantes e altera seu texto quando uma vida é perdida.
O update_lives_text() é chamado quando o jogo é inicializado, o texto é desenhado pela primeira vez e também é invocado quando o jogador erra um rebote da bola.
Deixamos start_game() não implementado por enquanto, pois ele aciona o ciclo do jogo e essa lógica será adicionada mais a frente.
Como o Python requer um bloco de código para cada método, usamos a declaração pass.
Isso não executa nenhuma operação e pode ser usado como um espaço reservado quando uma declaração é necessária sintaticamente.
Executando o script, ele exibirá uma janela do Tkinter como a mostrada na figura abaixo.
Nesse ponto, podemos mover a raquete horizontalmente, para estarmos prontos para iniciar o jogo e bater em alguns tijolos.
😉
Ficamos por aqui e até a próxima.
Aula 02
Aula 04
Todas as aulas desse curso
Voltar para página principal do blog
Para baixar o código acesse o link abaixo:
https://github.com/toticavalcanti/curso_python_games/exemplo_03/
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Link do código fluente no Pinterest
Novamente deixo meus link de afiliados:
Hostinger
Digital Ocean
One.com
Obrigado, até a próxima e bons estudos. 😉