Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Diminuir Ifs no processamento de eventos

O método " processar_eventos" do Pacman faz um loop pela lista de eventos e verifica evento a evento o tipo com um 'if', caso verdadeiro faz uma serie de outros 'ifs' para identificar a tecla pressionada. 

```
for e in eventos : 
    if e.type == pygame.KEYDOWN:
        if e.key == pygame.K_RIGHT:
            # executa ação 
        elif e.key == pygame.K_LEFT:
            # executa ação
        .
        .
        .
```

Quais 'desing patterns' poderiam ser implementados em uma refatoração do código para que fosse reduzida a quantidade de 'ifs' e melhorasse a escalabilidade ( facilitando implementações de novas teclas futuramente ) ?

1 resposta
solução!

Um design pattern que pode ser aplicado neste processo é o Strategy, no qual podem ser criados diversos algoritmos de maneira a empacotá-los como classes, para acoplá-los ao Pacman, dependendo do algoritmo desejado.

Neste caso os algoritmos não seriam trocados e sim incrementados uns aos outros, então pode ser feita uma variação do Strategy, criando um conjunto de classes com os algoritmos desejados e adicionando estes algoritmos em uma lista no Pacman.

As mudanças a serem feitas serão:

1) Criar uma classe abstrata chamada EventBehaviour apenas para padronizar o nome do método como processa_evento e seus parâmetros.

class EventBehaviour(metaclass=ABCMeta):
    @abstractmethod
    def processa_evento(self, elemento_jogo, event):
        pass

2) Os algoritmos podem ser divididos em subclasses de EventBehaviour da maneira que convier, porém um jeito prático talvez seja dividi-los em eventos de pressionamento de tecla e eventos de soltura de tecla, conforme o exemplo a seguir:

class SoltarTecla(EventBehaviour):
    def processa_evento(self, elemento_jogo, event):
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                elemento_jogo.vel_x = 0
            elif event.key == pygame.K_LEFT:
                elemento_jogo.vel_x = 0
            elif event.key == pygame.K_UP:
                elemento_jogo.vel_y = 0
            elif event.key == pygame.K_DOWN:
                elemento_jogo.vel_y = 0

class PressionarTecla(EventBehaviour):
    def processa_evento(self, elemento_jogo, event):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                elemento_jogo.vel_x = VELOCIDADE
            elif event.key == pygame.K_LEFT:
                elemento_jogo.vel_x = -VELOCIDADE
            elif event.key == pygame.K_UP:
                elemento_jogo.vel_y = -VELOCIDADE
            elif event.key == pygame.K_DOWN:
                elemento_jogo.vel_y = VELOCIDADE

3) No constructor da classe Pacman, deverá ser criada uma lista chamada event_rules que vai guardar os algoritmos:

class Pacman(ElementoJogo, Movivel):
    def __init__(self, tamanho):
        ...
        self.event_rules = []

4) Na classe Pacman é importante criar um método para adicionar as regras (algoritmos) na lista event_rules, como exemplo:

def add_event_rule(self, event_rule):
    self.event_rules.append(event_rule)

5) O comportamento processar_eventos da classe Pacman deve ser alterado para buscar os comportamentos da lista event_rules e não mais localmente:

def processar_eventos(self, eventos):
    for e in eventos:
        for event_rule in self.event_rules:
            event_rule.processa_evento(self, e)

6) No trecho de código principal (main) onde a instância do Pacman é criada, deverão ser criadas também as instâncias de PressionarTecla e SoltarTecla, colocando-as na lista event_rules do Pacman.

if __name__ == "__main__":
    size = 600 // 30
    pacman = Pacman(size)
    evento_soltar_tecla = SoltarTecla()
    evento_pressionar_tecla = PressionarTecla()
    pacman.add_event_rule(evento_soltar_tecla)
    pacman.add_event_rule(evento_pressionar_tecla)
    ...

Pronto agora os comportamentos de teclas estão desacoplados da classe Pacman e podem ser adicionados, modificados criando uma nova classe do tipo EventBehaviour e adicionando uma instância na lista event_rules da instância de Pacman.