Aula 01 - Criando games em python - Utilizando o Tkinter

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_01/

Link da documentação oficial do Tkinter:

https://tkdocs.com/

Uma visão geral do jogo Breakout

O jogo Breakout começa com um rebatedor e uma bola na parte inferior da tela e alguns linhas de tijolos no topo. O jogador deve eliminar todos os tijolos batendo neles com o bola, que se rebate contra as bordas da tela, os tijolos e o rebatedor inferior. Como em Pong, que foi o primeiro videojogo lucrativo da história, e deu origem a um novo setor da indústria, o jogador controla o movimento horizontal do rebatedor. O jogador começa o jogo com três vidas e se ele perder o rebote da bola e atingir a borda inferior da tela, uma vida é perdida. O jogo acaba quando todos os tijolos são destruídos, ou quando o jogador perde todas as suas vidas. Esta é uma captura de tela da versão final do nosso jogo:

Dicas de livros relacionados:

                                   

O layout básico da GUI( Graphical User Interface )

Vamos começar o jogo criando uma janela de nível superior. Usaremos o Tkinter para essa interface. O Tkinter é um framework para criação de interfaces gráficas do usuário em python. Veja a lista abaixo, ela mostra além do Tkinter, outros frameworks para desenvolver interfaces gráficas em Python:
  • WxWidgets;
  • Tkinter;
  • Kivy;
  • PyGTK;
  • PySide;
  • QT.
O Tkinter já vem com a instalação padrão do python, com exceção de algumas distribuições Linux, nesses casos é necessário fazer o download do módulo e a instalação.

Nesse link você encontrará os detalhes de como instalar o Tkinter, caso seja necessário.

https://tkdocs.com/tutorial/install.html

Usaremos dois widgets aninhados: um container frame e o canvas, isto é, a tela onde os objetos do jogo serão desenhados: Com o Tkinter podemos fazer isso usando o seguinte código:

import tkinter as tk
lives = 3
root = tk.Tk()
frame = tk.Frame(root)
canvas = tk.Canvas(frame, width=600, height=400, bg='#aaaaff')
frame.pack()
canvas.pack()
root.title('Primeira Janela')
root.mainloop()
Através do tk, acessamos as classes definidas no módulo tkinter, tk.Frame(moldura), e tk.Canvas(tela). O tk é o apelido do tkinter no nosso código. Quando fizemos: import tkinter as tk, apelidamos o tinker de tk. Observe o primeiro argumento de cada chamada do construtor que indica o widget (child container) , e o pack() é chamado para exibir os widgets no container pai. O pack() é o gerenciador de geometria que organiza widgets em blocos antes de colocá-los no widget pai. Isso não é necessário para a instância Tk, já que é a janela raiz. No entanto, essa abordagem não é exatamente orientada a objetos, já que usamos variáveis globais e não definimos nenhuma nova classe para representar nossas novas estruturas de dados. Se a base de código cresce, isso pode levar a projetos mal organizados e a códigos altamente acoplados.

Podemos começar a encapsular as peças do nosso jogo dessa maneira, crie o arquivo abaixo:

/python_games/aula_01/exemplo_01.py


import tkinter as tk
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()
if __name__ == '__main__':
    root = tk.Tk()
    root.title('Janela do Game!')
    game = Game(root)
    #essa linha é só para abrir a janela, é a chamada a instância do Game.
    game.mainloop()
O mainloop() é um método que é usado quando tá tudo pronto para o aplicativo ser executado. O mainloop() é um loop infinito usado para executar o aplicativo e esperar que um evento ocorra para processar esse evento até que a janela seja fechada. Ele só para de executar quando a janela é fechada.

Nosso novo tipo, chamado Game, herda da classe Frame do Tkinter.

A classe Game (tk.Frame): define o nome da classe e da superclasse entre parênteses. Se você é novo em programação orientada a objetos com Python, esta sintaxe pode não parecer familiar. Se for esse seu caso, acesse as aulas de orientação a objetos em python aqui do blog: https://www.codigofluente.com.br/aula-15-python-orientacao-a-objeto-01/ https://www.codigofluente.com.br/aula-16-python-orientacao-a-objetos-02/ Os conceitos mais importantes aqui são o método __init__ e a variável self:
  • O método __init__ é um método especial que é invocado quando uma nova instância de classe é criada. Aqui, definimos os atributos do objeto, como largura, altura e widget de tela. Também chamamos a inicialização da classe pai com o super (Game, self) .__ init __ (master), então o estado inicial do Frame é propriamente inicializado.
  • A variável self refere-se ao objeto em memória, a instância do Game na memória, e deve ser o primeiro argumento de um método se você quiser acessar a instância dele. Não é estritamente uma palavra-chave da linguagem, mas, uma convenção do Python, equivalente ao this do Java.
No pedaço de código anterior, introduzimos a condição if __name__ == '__main__', que está presente em muitos scripts Python. Na aula 13 do curso de python aqui do blog código fluente tem uma explicação mais detalhada sobre o if __name__ == '__main__': https://www.codigofluente.com.br/aula-13-python-modules-modulos/

Execute o código do /python_games/aula_01/exemplo_01.py.


python /python_games/aula_01/exemplo_01.py
Ou se o terminal já tiver na mesma pasta é só executar:

python exemplo_01.py
O loop principal será executado indefinidamente até você clicar no botão fechar da janela, ou então, você pode matar o processo a partir da linha de comando. Este é o ponto de partida do nosso jogo, por isso vamos começar a mergulhar no widget Canvas e ver como podemos desenhar e animar itens nele.

Widget de Tela

Até agora, temos a janela configurada e podemos começar a desenhar itens na tela. O widget de tela é bidimensional e usa o sistema de coordenadas cartesianas. A origem, o par ordenado (0, 0), é colocado no canto superior esquerdo e o eixo pode ser representado conforme mostrado na captura de tela a seguir: Mantendo este layout em mente, podemos usar dois métodos do widget Canvas para desenhar o rebatedor, os tijolos e a bola:
  • canvas.create_rectangle(x0, y0, x1, y1, **options)
  • canvas.create_oval(x0, y0, x1, y1, **options)
Cada uma dessas chamadas retorna um inteiro, que identifica o item. Esta referência é usada posteriormente para manipular a posição do item e suas opções. A sintaxe das opções, representa um par chave / valor de argumentos adicionais que podem ser passados para a chamada do método. Em nosso caso, usaremos o fill e as tags options. As coordenadas x0 e y0 indicam o canto superior esquerdo do objeto e x1 e y1 são indicam o canto inferior direito. Por exemplo, podemos chamar canvas.create_rectangle (250, 300, 330, 320, fill = 'blue', tags = 'rebatedor') para criar o rebatedor de um jogador, onde:
  • O canto superior esquerdo está nas coordenadas (250, 300).
  • O canto inferior direito está nas coordenadas (300, 320).
  • O fill = 'blue' significa que a cor de fundo do item é azul.
  • As tags = 'rebatedor' significa que o item é marcado como um rebatedor. Esta string será útil mais tarde para encontrar itens na tela com tags específicas.
Vamos invocar outros métodos do Canvas para manipular os itens e recuperar o widget em formação.

Esta tabela fornece as referências ao widget Canvas que será usado nessas aulas:

Método Descrição
canvas.coords(item) Retorna as coordenadas da caixa delimitadora de um item.
canvas.move(item, x, y) Move um item fazendo um deslocamento horizontal e vertical.
canvas.delete(item) Exclui um item da tela.
canvas.winfo_width() Recupera a largura da tela.
canvas.itemconfig(item, **options) Altera as opções de um item, como a cor de preenchimento ou suas tags.
canvas.bind(event, callback) Vincula um evento de entrada com a execução de uma função. O manipulador de retorno de chamada recebe um parâmetro do tipo Tkinter event.
canvas.unbind(event) Desvincula o evento de entrada para que não haja nenhuma função de retorno de chamada executada quando o evento ocorre.
canvas.create_text(*position, **opts) Desenha o texto na tela. A posição e os argumentos de opções são semelhantes aos passados em canvas.create_rectangle e canvas.create_oval.
canvas.find_withtag(tag) Retorna os itens com uma tag específica.
canvas.find_overlapping(*position) Retorna os itens que se sobrepõem ou são completamente delimitados por um determinado retângulo.

Você pode conferir uma referência completa da sintaxe dos eventos, bem como alguns exemplos em:

https://tkdocs.com/tutorial/canvas.html

Ficamos por aqui e até a próxima.

Para baixar o código acesse o link abaixo:

https://github.com/toticavalcanti/curso_python_games/Jogo_Breakout/aula_01/

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. ;)