É hora de dar vida as nossas peças. O nosso tabuleiro de Xadrez precisa nos proporcionar movimentos, para que você possa usar aquela sua jogada bem trabalhada e causar arrepios em seu adversário.
Chega de conversa, vamos trabalhar porque temos muito o que fazer.
Para começar, vou partir do princípio de que você já esteja um pouco familiarizado com os eventos do Java (ActionListener, MouseListener, etc). Caso não faça ideia do que eu estou falando, é melhor dar uma lida aqui. Caso contrário, saberá que alguma de nossas classes terá que responder aos eventos de mouse (clique). Como saber qual peça está selecionada e qual casa eu cliquei? Usaremos um MouseListener que "escutará" os eventos de clique no tabuleiro para nos ajudar a responder essas perguntas.
Não postarei o código todo novamente, e sim as partes que formos alterando, ok?
Bom, então a primeira coisa a fazer é com que a nossa classe Tabuleiro implemente a interface MouseListener para escutar os eventos de clique:
public class Tabuleiro extends JPanel implements MouseListener{...}
Ao fazer isso, nós temos que fornecer implementações "válidas" para todos os métodos abstratos declarados nessa interface. Por "válidas" entenda que o método tem que ter um corpo (par de chaves). De todos os métodos, o único que realmente precisaremos escrever alguma lógica é o mouseClicked que é efetivamente o clique do mouse.
Vamos para a implementação?
@Override
public void mouseClicked(MouseEvent arg0) {
Celula c = (Celula)arg0.getSource();
this.tabuleiroModel.realizaJogada(c.getLinha(), c.getColuna());
}
Hey! Que método é esse de "realizaJogada"? Calma, já vamos chegar lá. Primeiro vamos entender esse método. Na primeira linha, usamos o método getSource() do argumento MouseEvent para descobrirmos e pegarmos que tipo de objeto veio como resposta ao clique. Como nosso tabuleiro é preenchido somente com células, o downcast é extremamente seguro, não sendo necessário fazer a verificação com instanceof. Na segunda linha, passamos a linha e a coluna da célula selecionada para um método realizaJogada do objeto TabuleiroModel, que será explicado e criado a seguir.
Como estamos aplicando boas práticas MVC no nosso projeto, a "lógica" do negócio não pode estar na camada de apresentação. E é por isso que o método realizaJogada será criado no TabuleiroModel. Mas, o que esse método precisa fazer? Como você deve lembrar, na classe TabuleiroModel possuímos uma matriz de peças. A lógica é basicamente tirar a peça selecionada da posição antiga e colocá-la na nova posição. Exemplo:
Figura 01: Preparando movimento da Torre
Observe que selecionamos a peça TORRE e queremos andar uma "casa" para frente. Vamos implementar essa lógica. Primeiramente, vamos criar uma variável na classe TabuleiroModel para representar a peca que está sendo selecionada no momento:
private PecaModel pecaSelecionada = null;
A seguir, veja a lógica do método:
public void realizaJogada(int linha, int coluna) {
// se não há peça selecionada, pegue a peça da linha e coluna e marque-a como selecionada = true
if (pecaSelecionada == null) {
pecaSelecionada = this.getPeca(linha, coluna);
if (pecaSelecionada != null) {
pecaSelecionada.setSelecionada(true);
}
} else {
// caso haja uma peça selecionada, quer dizer que falta definir o destino da peça selecionada.
PecaModel outraPeca = this.getPeca(linha, coluna);
// aqui verificamos se o usuário clicou na mesma peça. Caso tenha clicado, só setar a propriedade "selecionada" para false.
if (outraPeca != null && outraPeca.equals(pecaSelecionada)) {
pecaSelecionada.setSelecionada(false);
pecaSelecionada = null;
} else {
// caso o destino selecionado não seja a própria peça selecionada, então "atualizamos" a posição da peça.
this.pecas[pecaSelecionada.getLinha()][pecaSelecionada.getColuna()] = null;
this.pecas[linha][coluna] = pecaSelecionada;
pecaSelecionada.setSelecionada(false);
pecaSelecionada.setLinha(linha);
pecaSelecionada.setColuna(coluna);
pecaSelecionada = null;
}
}
}
Observe que o método "realizaJogada" será chamado a cada vez que o usuário clicar o mouse.
Se compilarmos e executarmos este código, não vamos notar diferença nenhuma na nossa tela. Isso porque nós não atualizamos o nosso tabuleiro visual! E agora, quem poderá nos salvar?
Precisamos criar uma forma de "avisar" a camada de visão (o nosso tabuleiro visual) que o modelo foi alterado. Se você já ouviu falar no padrão "Observer", sabe do que estou falando. Vamos criar uma simples interface "ouvidora" de tabuleiros:
public interface TabuleiroListener {
public void tabuleiroChanged();
}
Esta interface define apenas um método que será responsável por atualizar o nosso tabuleiro visual. E quem deve implementar essa interface? O "provedor" dos eventos, ou seja, aquela classe que irá disparar os eventos. Você já sabe. É claro que é a classe Tabuleiro quem deve implementar esta interface, visto que os cliques (ações) ocorrem lá. Vamos ao código?
public class Tabuleiro extends JPanel implements TabuleiroListener, MouseListener {
...
@Override
public void tabuleiroChanged() {
this.montaTabuleiro();
}
}
Se você olhar nos posts anteriores, saberá que o método montaTabuleiro coloca as peças no lugar e reorganiza o layout. Então a ideia é simples, mas quem que vai chamar esse método tabuleiroChanged()? Beleza, ele está aí declarado, implementado, mas não vejo ninguém o chamando. Bom, se o modelo foi alterado, quem é responsável por avisar a visão de que houve alguma mudança? É claro que é o próprio modelo quem deverá invocar esse método!
Vamos fazer isso funcionar de vez.
Crie uma variável do tipo TabuleiroListener na classe TabuleiroModela:
private TabuleiroListener listener;
Em seguida, crie um método configurador na mesma classe, para atribuirmos um valor a essa variável:
public void setTabuleiroListener(TabuleiroListener listener) {
this.listener = listener;
}
Agora, no construtor da classe Tabuleiro, registre-o como "ouvinte" do modelo:
tabuleiroModel.setTabuleiroListener(this);
Esta linha está dizendo: "hey, quero ficar sabendo de todas as alterações aí no seu modelo!".
Pois bem, agora só falta dizer para o modelo avisar a visão de que ele mesmo se alterou.
Lembra do método realizaJogada()? Pois bem, ao final dele, basta fazer esse aviso a visão:
listener.tabuleiroChanged();
Ou seja, a cada jogada realizada, esse método será invocado. E adivinha... ? O método tabuleiroChanged remonta todo o tabuleiro, pegando as alterações que foram feitas!
Veja o resultado abaixo:
Imagem 02: Torre prestes a ser movida
Imagem 03: Torre em sua nova posição
Ufa! Quanta coisa! Mas não se iluda, falta muuuuita coisa a ser feita. Por exemplo, ainda não estamos validando o movimento das peças... a torre pode se movimentar em todos os sentidos, o que em um jogo de Xadrez isso não é permitido. Então, mãos a obra e aguardem o próximo POST para fazermos o movimento válido das peças, verificando se existem peças "inimigas"e todas as particularidades do jogo.
É agora que começa a ficar divertido, então, não percam!
Um abraço e até a próxima :)

Nenhum comentário:
Postar um comentário