Tenho um problema que acho que sera simples de resolver, que é justamente o titulo do topico.
No meu caso, a interface grafica do meu jogo de xadrez, não atualiza a ultima jogada do jogador na tela até que a IA tenha processado seu proximo movimento.
Mesmo o metodo para atualizar esteja antes do metodo que chama a IA.
Como eu faço a IA “esperar” até que a tela tenha sido atualizada?
[code]//…
//atualizar interface grafica
repintar();
if (jogou) {
//consulta engine para determinar continuidade do jogo
consultarEngine();
}
//…
private void consultarEngine() {
//…
//IA procura a melhor jogada
Jogada moveIA = storm.buscarMovimento(tab);
//…[/code]
Cara ta muito abstrato, tem como você explicar melhor?
Exemplificando:
realiazo uma jogada.
é chamado o metodo para atualizar o tabuleiro da interface grafica.
mas antes que a tela tenha terminado de atualizar o proximo metodo ja esta sendo chamado, que no meu caso é a IA para realizar a proxima jogada.
E enquanto a IA não termina de calcular o proximo movimento e jogar, a tela fica travada no exato momento em que você clicou para executar a proxima jogada.
Bom acho que com uma imagem fica mais facil entender o problema:
no caso eu joguei e2-e4, mas a tela vai ficar sem aparecer a nova posição do Peão até que a IA decida o proximo movimento dela, só então a tela “descongela” e atualiza tudo de uma vez.
[URL=http://imageshack.us/photo/my-images/10/interfacecongelada.png/]
[/URL]
Agora entendi Beregula!
Pelo que você falou esses dois processos devem estar juntos de alguma forma, de repente um metodo que faz as duas coisas juntas, não sei.
Veja se não tem nada desse jeito no seu codigo, executando os dois processos com se fossem apenas um quando ao jogar vc dispara o evento.
Deveria ser algo assim:
recebeJogadaJogador();
this.repaint();
this.validate();
IAfazJogada();
this.repaint();
this.validate();
Fazendo cada coisa de uma vez. Posta o seu codigo ai caso você não tenha entendido ou caso não seja isso!
é fiquei meio perdido no que você esta dizendo então segue o codigo
se não intender alguma coisa do codigo eu explico, por que não comentei praticamente nada nele
[code]@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
JButton auxiliar = (JButton) e.getSource();
Peca peca;
if (selecionado == null) {
boolean sair = false;
for (int a1 = 0; a1 < 8; a1++) {
for (int a2 = 0; a2 < 8; a2++) {
JButton teste = tabButton[a1][a2];
if (teste.equals(auxiliar)) {
if (cor) {
peca = tab.getPeca(a2, 7 - a1);
if (peca != null) {
peca.setPosicao(new Posicao(a2, 7 - a1));
}
} else {
peca = tab.getPeca(a2, a1);
if (peca != null) {
peca.setPosicao(new Posicao(a2, a1));
}
}
if (peca != null) {
if (peca.getCor() == tab.getTurno()) {
l = peca.getMovimentos(tab);
l = tab.retirarJogadasInvalidas(l);
if (!l.isEmpty()) {
selecionado = auxiliar;
auxiliar.setBackground(new Color(100, 100, 204));
for (Jogada jogada : l) {
auxiliar = getButton(jogada.getFin().getX(), jogada.getFin().getY());
auxiliar.setBackground(new Color(160, 160, 254));
}
}
}
sair = true;
}
}
if (sair) {
break;
}
}
if (sair) {
break;
}
}
} else {
boolean jogou = false;
for (int a1 = 0; a1 < 8; a1++) {
for (int a2 = 0; a2 < 8; a2++) {
JButton teste = tabButton[a1][a2];
if (teste.equals(selecionado)) {
if (cor) {
peca = tab.getPeca(a2, 7 - a1);
} else {
peca = tab.getPeca(a2, a1);
}
for (Jogada jogada : l) {
if (auxiliar.equals(getButton(jogada.getFin().getX(), jogada.getFin().getY()))) {
tab.moverPeca(peca, jogada);
ligarTabuleiro(tab);
jogou = true;
break;
}
}
}
}
}
selecionado = null;
repintar();
if (jogou) {
consultarEngine();
}
}
}
}
private void repintar() {
for (int a1 = 0; a1 < 8; a1++) {
for (int a2 = 0; a2 < 8; a2++) {
Color c;
if (a1 % 2 == 1) {
if (a2 % 2 == 1) {
c = Color.LIGHT_GRAY;
} else {
c = Color.WHITE;
}
} else {
if (a2 % 2 == 0) {
c = Color.LIGHT_GRAY;
} else {
c = Color.WHITE;
}
}
if (cor) {
tabButton[7 - a2][a1].setBackground(c);
} else {
tabButton[a2][a1].setBackground(c);
}
}
}
marcarUltimaJogada();
}
private void consultarEngine() {
if (tab.empateIniciativa()) {
exibirMensagem("Empate: 50 jogadas realizadas sem captura de Peças ou movimento de peão");
Relatorio rl = new Relatorio();
rl.setVisible(true);
rl.adicionarRelatorio(tab.relatorioJogadas(storm, null));
return;
}
//receber todas jogas possiveis
List<Jogada> l = tab.getPossiveis(tab.getTurno());
//corrigir qualquer problema na posição gravada na peça
tab.fixPosicao();
if (l.isEmpty()) {
String s = "Fim do jogo: ";
if (tab.emXeque(tab.getTurno())) {
if (tab.getTurno()) {
s = "Xeque-Mate!\nVitoria das Pretas";
} else {
s = "Xeque-Mate!\nVitoria das Brancas";
}
} else {
s += "Empate por afogamento";
}
exibirMensagem(s);
continuar = false;
Relatorio rl = new Relatorio();
rl.setVisible(true);
rl.adicionarRelatorio(tab.relatorioJogadas(storm, null));
}
if ((storm != null) && (continuar)) {
if (storm.isBranca() == tab.getTurno()) {
Jogada moveIA = storm.buscarMovimento(tab);
if (moveIA != null) {
tab.moverPeca(moveIA.getPeca(), moveIA);
ligarTabuleiro(tab);
repintar();
consultarEngine();
} else {
System.out.println("Travou aki");
}
}
}
}[/code]
Caramba cara, queria poder te ajudar mais!
Contudo estou tendo dificuldades para compreender exatamente o que o seu codigo está fazendo. Por isso vou tentar explicar o que eu acho que esta acontecendo para você mesmo poder implementar essa mudança ai!
O seu codigo, pelo que pude entender, está fazendo o movimento do jogador e o movimento do computador juntos, porque eles estão no mesmo trecho de codigo.
Experimenta criar dois metodos separados para esses problemas, um sendo por exemplo:
jogadorFazJogada(){
//E aqui vc atualiza o seu frame com a jogado do jogador, so a do jogador
}
Depois cria um
maquinaFazJogada(){
//E aqui vc le a jogado da jogador, calcula o proximo passo da maquina e em seguida atualiza novamente o frame
}
Como não entendi direito o seu codigo, não posso te mostrar o que exatamente fazer, mas deve ser mais ou menos isso.
Dai quando for chamar os metodos vocÊ pode primeiramente atualizar quando o jogador faz a jogada e mandar o sistema esperar 2 segundos para fazer a sua jogada. Eu fiz isso usando usando o metodo sleep da classe Thread. Então ficaria mais ou menos assim:
jogadorFazJogada();
Thread t = new Thread("rei");
ExecutorService threadExecutor = Executors.newFixedThreadPool(1);
try {
t.sleep(200);
threadExecutor.execute(t);
if (t.isInterrupted()) {
System.exit(0);
}
} catch (InterruptedException ex) {
Logger.getLogger(TelaInicializacao.class.getName()).log(Level.SEVERE, null, ex);
}
MaquinaFazJogada();
Essa Thread obrigada que o programa espere.
Caso vc queira continuar sem fazer os 2 metodos conforme te falei, vc pode encontrar no seu codigo onde essas duas ações acontecem e entre elas colocar a thread para forçar a espera.
Flw
Então, oq eu preciso é quase isso.
é um comando para obrigar terminar de atualizar a tela antes de entrar no outro comando que chama a IA.
tentei com essa tread que vc coloco mas continua acontecendo a mesma coisa.
@Edit: O problema era que a propria classe chamava o metodo da IA.