Olá pessoal, tudo bem.
Estou criando um jogo, no entando cheguei na parte de fazer o movimento da nave (o jogo é uma espécie de space invaders).
O programa está estruturado da seguinte forma (por enquanto):
Classe Main a qual instancia o objeto da classe janela , a Classe Janela que extends JFrame (a qual adiciona o painel) e a Classe PainelGame extends JPanel implements KeyListener a qual possui os components do jogo, invasores e a nave que você controla.
Código:
class Janela extends JFrame
{
public Janela()
{
PainelGame painelGame = new PainelGame();
add(painelGame);
// mudar focus para o painel.
}
}
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
public class PainelGame extends JPanel implements KeyListener
{
private JLabel barra;
private JLabel label[] = new JLabel[10];
private JLabel nave;
private JLabel tiro;
private Rectangle invasores[] = new Rectangle[10];
private int k;
public PainelGame()
{
setBackground(Color.black);
setLayout(null);
nave = new JLabel();
nave.setIcon(new ImageIcon(getClass().getResource("/Imagens/nave.jpg")));
tiro = new JLabel();
tiro.setIcon(new ImageIcon(getClass().getResource("/Imagens/tiro.jpg")));
barra = new JLabel();
barra.setBounds(0,644,1000,30);
barra.setIcon(new ImageIcon(getClass().getResource("/Imagens/barraInfo.jpg")));
add(barra);
add(nave);
add(tiro);
nave.setBounds(0,600,50,50);
k = 50;
for(int i=0;i<invasores.length;i++)
{
invasores[i] = new Rectangle();
label[i] = new JLabel();
invasores[i].setBounds(k,20,50,50);
label[i].setBounds(k,20,50,50);
label[i].setIcon(new ImageIcon(getClass().getResource("/Imagens/invader.jpg")));
k = k + 50;
add(label[i]);
}
addKeyListener(this);
}
public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent e)
{
if( e.getKeyCode() == e.VK_ENTER)
{
nave.setBounds(0,300,50,50);
}
}
public void keyReleased(KeyEvent e)
{
}
}
O problema é o seguinte: após apertar o Enter o JLabel da nave deveria se mover para a cordenada 0,300 mas isso não acontece, acredito que isso seja problema em relação ao Focus, até tentei colocar “requestFocus()”, mas não adiantou. Alguem sabe pq ocorre tal problema?
Quanto ao tratamento de eventos, sem problema com o foco, leia isso.
E esteja ciente que este jogo pode (e é provável que) funcione, mas essa não é a maneira correta de se fazer. Uma ótima leitura para começar aqui. Um SpaceInvaders aqui. Um leitura mais completa aqui.
Ahh… e só para constar: você está carregando a mesma imagem (a dos invasores) invasores.length vezes. Se o vetor for muito grande levará muito tempo antes de iniciar. Carregue apenas uma vez e depois use-a.
...
private ImageIcon img;
img = (new ImageIcon(getClass().getResource("/Imagens/invader.jpg")));
for(int i=0;i<invasores.length;i++)
{
invasores[i] = new Rectangle();
label[i] = new JLabel();
invasores[i].setBounds(k,20,50,50);
label[i].setBounds(k,20,50,50);
label[i].setIcon(img);
k = k + 50;
add(label[i]);
}
...
Então agora desta forma estou sobrecarregando menos o processamento ?
Vlw.
[quote=dudu_sps]Bom… primeiramente… não duplique topicos
depois tente apertar ALT + ENTER e responda se funcionou[/quote]
Não dupliquei o tópico, o outro é problema em relação a focus/thread e não se encaixa no mesmo contexto.
Então, tentei aqui Alt + Enter e não funcionou.
[quote=marcobiscaro2112]Quanto ao tratamento de eventos, sem problema com o foco, leia isso.
E esteja ciente que este jogo pode (e é provável que) funcione, mas essa não é a maneira correta de se fazer. Uma ótima leitura para começar aqui. Um SpaceInvaders aqui. Um leitura mais completa aqui.[/quote]
Vlw brother, vou ler isso e depois posto se consegui.
Agora, o ideal não é você trabalhar com Labels e Panels, e sim com Java2D diretamente. Dá uma olhada nos links colocados pelo marco ali em cima. Vão te facilitar muito a vida.
Ok ViniGodoy, agradeço novamente a sua dica e irei estudar os tópicos/livros e implementar em Java2D diretamente.
ViniGodoy ou alguém que possa responder.
sobre o seguinte Fragmento.
private class JLabelEvento extends AbstractAction
{
private JLabel label;
// private KeyStroke keyStroke; // tentei usar com e.getSource().
private int pixelsX = 0;
public JLabelEvento(JLabel label)
{
this.label = label;
}
public void actionPerformed(ActionEvent e)
{
String s;
s = e.getActionCommand();
if (s.equals("RIGHT"))
{
pixelsX+=15;
label.setBounds(pixelsX,600,50,50);
}
}
No método ActionPerformed tentei estabelecer aquela comparação para saber se o usuário precionou RIGHT e consequentemente mover para a direita. No entanto, não é possível estabelecer a comparação desta forma, tentei também usando o cast (KeyStroke) no e.getSource(). para obter o getKeyStroke(“String”). Mas, não obtive sucesso.
Qual seria a maneira correta de estabelecer esta relação?
ViniGodoy, primeiramente fiz com o KeyListener, mas ele não respondia ao comando (não mudava o label de posição) duvidei que isso seria problema em relação ao Focus (tentei “painel.requestFocus()” mas falhou), postei aqui daí você sujeriu o esquema do implements AbstractAction da calculadora pra resolver esse problema do focus, até resolveu mas, tal como eu disse acima não consigo “manipular(tratar)” e saber qual tecla foi precionada.
Se isso não for possível, irei voltar ao KeyListener. Obrigado pela atenção!
Olá ViniGodoy.
Fiz somente com um action pq a única coisa que deve ser alterada é o setBounds do JLabel “nave” (entendi o teu exemplo da calculadora, mas a lógica não irá ser análoga neste caso). No entanto, pensei , repensei e não consegui pensar na lógica para “tratar” estes eventos.
Até pensei em fazer os actions da seguinte forma:
Um (Action) para mover a nave para direita, outro para esquerda, outro para cima e o outro para baixo. No entanto, da forma que eu pensei isso iria precisar de 4 JLabels, até iria funcionar (o tratamento do evento) mas, como cada JLabel teria a imagem, após alguns movimentos iria ficar a imagem de 4 naves na tela e isso seria um problema não tão agradável de se tratar, pois as colisões que irei fazer no jogo será através da intersecção dos retangulos das imagens.
Preciso de um esboço de como ficaria esse tratamento que você sugeriu.
[quote=ViniGodoy]Por que você teria que criar 4 JLabels?
Você cria 4 classes Action, uma cada direção. Faz como a que vc fez ali atrás.
Essa classe recebe um JLabel como parâmetro.
Passe o mesmo JLabel para as 4 actions.[/quote]
Ola ViniGodoy, agora que intendi o raciocinio dessa forma de trabalhar com evento.
Agradeço ae por tudo, consegui fazer o que eu queria.
[b]ViniGodoy, ultima pergunta:
Sempre que eu tiver um programa e se em um certo ponto ele ter que trocar o painel e trabalhar com evento do teclado seria então mais prático trabalhar do modo que você ensinou por AbstractAction, InputMap e ActionMap? (para evitar o possível problema de focus)[/b]