Galera, tenho esse código pro carro andar, e oque ocorre é que ele ta andando t udo certo sozinho (simplifiquei os metodos dos cases só pra dar uma idéia). Cada tecla que o usuário aperta ele vai para o lado correto sozinho, mas oque ocorre é que cada tecla ele cria uma nova Thread, entao se aperto pra ele ir pra cima ele vai na velocidade correta, mas se aperta direita ou para baixo, ele vai na direção correta só que mais rápido e vai ficando mais e mais rápido.
Será que tem como evitar que essa thread seja criada mais de uma vez? Alguém poderia me ajudar? Tentei singleton mas nao deu muito c erto, nao sei como poder no código a instancia com o run.
Fiz um exemplo aqui para vc. Apenas uma thread fica executando e mandando o painel se repintar.
Carro.java
importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.RenderingHints;importjava.awt.geom.Ellipse2D;/** * Um carro. * * @author David */publicclassCarro{privateintx;privateinty;// velocidadesprivateintvx;privateintvy;publicintgetVx(){returnvx;}publicvoidsetVx(intvx){this.vx=vx;}publicintgetVy(){returnvy;}publicvoidsetVy(intvy){this.vy=vy;}publicintgetX(){returnx;}publicvoidsetX(intx){this.x=x;}publicintgetY(){returny;}publicvoidsetY(inty){this.y=y;}// pinta o carropublicvoidpaintMe(Graphicsg){Graphics2Dg2d=(Graphics2D)g;g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);g2d.fill(newEllipse2D.Double(getX(),getY(),20,20));}}
ThreadCarro.java
/** * Repinta o painel. * * @author David */publicclassThreadCarroimplementsRunnable{privatebooleanexecutando;privatePainelCarropainelCarro;publicThreadCarro(PainelCarropainelCarro,booleanexecutar){this.painelCarro=painelCarro;this.executando=executar;}publicvoidrun(){try{while(executando){painelCarro.repaint();Thread.sleep(100);}}catch(InterruptedExceptionexc){exc.printStackTrace();}}publicbooleanisExecutando(){returnexecutando;}publicvoidsetExecutando(booleanexecutando){this.executando=executando;}}
PainelCarro.java
importjava.awt.Graphics;importjavax.swing.JPanel;/** * Atualiza o carro e o repinta. * * @author David */publicclassPainelCarroextendsJPanel{privateCarrocarro;publicPainelCarro(Carrocarro){this.carro=carro;}@OverrideprotectedvoidpaintComponent(Graphicsg){super.paintComponent(g);carro.setX(carro.getX()+carro.getVx());carro.setY(carro.getY()+carro.getVy());carro.paintMe(g);}}
Janela.java
importjava.awt.BorderLayout;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjavax.swing.JFrame;/** * * @author David */publicclassJanelaextendsJFrameimplementsKeyListener{privateCarrocarro;privateThreadCarrothreadCarro;privatePainelCarropainelCarro;publicJanela(){// instancia os componentescarro=newCarro();painelCarro=newPainelCarro(carro);threadCarro=newThreadCarro(painelCarro,true);// configura o frameadd(painelCarro,BorderLayout.CENTER);setSize(400,400);setTitle("Olha o Carro!");setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);addKeyListener(this);// cria uma nova thread e a inicianewThread(threadCarro).start();}@OverridepublicvoidkeyTyped(KeyEvente){}@OverridepublicvoidkeyPressed(KeyEvente){// atualiza os valores do carroif(e.getKeyCode()==KeyEvent.VK_UP){carro.setVy(carro.getVy()-1);}elseif(e.getKeyCode()==KeyEvent.VK_DOWN){carro.setVy(carro.getVy()+1);}elseif(e.getKeyCode()==KeyEvent.VK_LEFT){carro.setVx(carro.getVx()-1);}elseif(e.getKeyCode()==KeyEvent.VK_RIGHT){carro.setVx(carro.getVx()+1);}}@OverridepublicvoidkeyReleased(KeyEvente){}publicstaticvoidmain(String[]args){newJanela().setVisible(true);}}
Qualquer dúvida avise.
[]´s
A
alexandrehdk
Péraí, quem é que chama o método andarCarro() ? Se esse método já é executado a cada evento de tecla, então você não tem porquê de executar uma thread a cada vez que uma tecla é pressionada.
Já se você quer que ele mantenha o carro andando em uma determinada direção indefinidamente até alguém dar outro comando para mudar a direção, aí é melhor postar mais do código para tentarmos adaptá-lo.
B
BlacK1
O andarCarro() é executado por um keyListener que fica na JFrame principal.
O lance é que se o cara apertar pra frete o carro deve continuar andando pra frente até ele apertar pro lado ou pra trás, entende?
aí esse método que cada vez que o keylistner dispara o evento ele cria uma Thread e acho que é isso que está errado. Teria que criar a Thread no Jframe principal?
valeu :d
ViniGodoy
O ideal é fazer como o David Postou. Dá uma estudada no código dele, está muito bom.