Boa tarde,
sei que tem vários posts falando sobre MouseEvent, mas não consegui sanar a minha dúvida em nenhum deles.
Estou fazendo um jogo (player x pc) de batalha naval. Ele pega o nome do jogador, cria o tabuleiro com JButtons e na hora de pedir para o usuário posicionar os navios que eu não consigo.
Como faço para pedir que o usuário selecione, por exemplo, 5 botões para posicionar o porta-aviões?
Já usei o MouseEvent em outros joguinhos que eu desenvolvi, mas nada precisava pedir ao usuário para selecionar vários ao mesmo tempo.
Agradeço desde já a ajuda de todos!
Bom, eu nunca fiz algo parecido com isso, mas, creio que isso talvez funcione.
- Crie uma lista de pontos, que representa os locais (JButton) onde o usuário posicionou um item.
- Crie uma action para o evento click, adicione o mesmo a todos os botões (lembre-se, todos os botões aceita mais de um evento)
- Nesta action, cada clique vai incrementar um contador e vai adicionando a referência do botão selecionado na lista criada no primeiro item
- Quando chegar a 5, aí bloqueia a adição e informa a mensagem que todas as posições foram selecionadas.
Ficou mais claro?
Boa tarde Darlan, agradeço a força.
Já criei a lista de pontos e todos os botões estão com action para o evento adicionado.
A minha dúvida é como esperar o usuário selecionar um (ou mais) botão.
public void posicionaNaviosPlayer() {
Navio navio;
//entra no for para posicionar cada um dos 5 navios disponíveis.
for(int i = 1; i <= 5; i++) {
navio = constroiNavio(i, player);
JOptionPane.showMessageDialog(
null, "Posicione o " + navio.getNome() + "."
+ "\nVocê precisa selecionar " + navio.getTamanho() + " espaços."
+ "\nPara isso, bastar clicar aonde deseja posicionar."
+ "\nLembre-se, todas as partes devem estar juntas.");
//Guarda os botões selecionados
Botao [] botoes = new Botao [navio.getTamanho()];
//AQUI ESTÁ A DÚVIDA.
for(int j = 0; j < navio.getTamanho(); j++) {
}
}
}
No segundo “for” ele pega o tamanho do navio. Ai é que eu não sei como esperar o usuário selecionar os botões.
Recomendo usar JLabel que é mais fácil, depois crie um tabuleiro com os labels já instanciados:
label.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
if (estado == EDICAO) {
int xi = label.obterX();
int yi = label.obterY(); // índices relativo ao tabuleiro
int xf = xi, yf = yi; // i de inicio, f de fim
if (navio é horizontal) {
xf += navio.tamanho;
}
if (navio é vertical) {
yf += navio.tamanho;
}
if (xf e yf estão dentro do tabuleiro) {
atribuiBordaVerde(labels de xi a xf e yi a yf);
} else {
atribuiBordaVemelha(labels de xi a xf e yi a yf);
}
}
}
public void mouseExited(MouseEvent me) {
removeBordaDosLabel();
}
public void mouseClicked(MouseEvent me) {
if (estado == EDICAO) {
int xi = label.obterX();
int yi = label.obterY(); // índices relativo ao tabuleiro
int xf = xi, yf = yi; // i de inicio, f de fim
if (navio é horizontal) {
xf += navio.tamanho;
}
if (navio é vertical) {
yf += navio.tamanho;
}
if (xf e yf estão dentro do tabuleiro) {
atribuiNavioAsoLabels(labels de xi a xf e yi a yf);
} else {
imprimeErro;
}
}
}
});
void atribuiNavioAosLabels(xi, yi, xf, yf, navio) {
int i = 0;
for (yi até yf) {
for (xi até xf) {
label[yi][xi].atribuirParte(navio.obterParte(i));// supondo que o navio é dividido em partes
i += 1;
}
}
}
Obrigado Diego, acho que consegui entender.
Quando implementar eu coloco aqui se deu certo ou não.
Eu achei que tinha entendido, mas não sei se estou colocando o código no lugar errado ou se não entendi como usar.
Troquei para JLabel como você sugeriu, diego12.
Mas ainda assim, quando peço para o usuário posicionar o navio, ainda não consegui esperar pelos ‘cliques’ do usuário, continua passando direto pro ‘próximo navio’ e ficando tudo vazio.
@IghorSantiago eu acredito que para sua solução seria melhor criar duas matrizes uma para o tabuleiro e outra que vai ser de JButtons ou JLabels como vc quiser acho que com isso vai ajudar muito a vc a realizar
esse foi um jogo de guerra naval onde os navios são posicionados no tabuleiro de forma randômica ver se isso pode te ajuda
Obrigado Manasses_Eugenio pela ajuda.
A parte randômica eu vou usar pra fazer o tabuleiro do computador, assim que eu terminar o do usuário.
No momento eu estou tentando pedir para o usuário escolher os labels em que vão ficar os navios e isso é armazenado em um vetor, para depois jogar na matriz.
A única coisa que falta é conseguir esperar a ação do usuário.
Mesmo com 2 matrizes eu vou cair no mesmo problema, vou ter que pegar o clique para posicionar os navios.
A vantagem de usar Labels são os eventos como enter, click e exited, que funcionam melhor que nos Buttons.
import javax.swing.*;
import java.awt.*;
import javax.swing.border.Border;
public class Botao extends JLabel
{
static final Border BORDA_PADRAO = BorderFactory.createLineBorder(Color.BLACK, 3);
static final Border BORDA_VERDE = BorderFactory.createLineBorder(Color.GREEN, 3);
static final Border BORDA_VERMELHA = BorderFactory.createLineBorder(Color.RED, 3);
Point posicao;
public Botao(int x, int y) {
super();
posicao = new Point(x, y);
setOpaque(true);
setBorder(BORDA_PADRAO);
setBackground(Color.BLUE);
}
}
import javax.swing.*;
import java.awt.*;
import javax.swing.border.Border;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Janela extends JFrame
{
Botao[][] botoes;
public Janela() {
super();
botoes = new Botao[8][12]; // (y,x)
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 12; x++) {
botoes[y][x] = new Botao(x,y);
getContentPane().add(botoes[y][x]);
adicionarEvento(botoes[y][x]);
}
}
setSize(600,400);
getContentPane().setLayout(new GridLayout(8, 12));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// variaveis de teste
boolean horizontal = true;
int tamanho = 3;
void adicionarEvento(Botao b) {
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
if (true) { // somente para teste, deve ser trocado para verificar se está "editando"
int xi = b.posicao.x;
int yi = b.posicao.y; // índices relativo ao tabuleiro
int xf = xi, yf = yi; // i de inicio, f de fim
if (horizontal) {
xf += tamanho - 1; // -1 inclusivo
} else { // senão é vertical
yf += tamanho - 1;
}
if (xf >= 0 && xf < 12 && yf >= 0 && yf < 8) {
atribuiBordaVerde(xi, yi, xf, yf);
} else {
atribuiBordaVemelha(xi, yi, xf, yf);
}
}
}
public void mouseExited(MouseEvent me) {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 12; x++) {
botoes[y][x].setBorder(Botao.BORDA_PADRAO);
}
}
}
});
}
void atribuiBordaVerde(int xi,int yi, int xf, int yf) {
atribuiBorda(xi, yi, xf, yf, Botao.BORDA_VERDE);
}
void atribuiBordaVemelha(int xi,int yi,int xf,int yf) {
atribuiBorda(xi, yi, xf, yf, Botao.BORDA_VERMELHA);
}
void atribuiBorda(int xi,int yi,int xf,int yf, Border border) {
while (yi <= yf) {
while (xi <= xf) {
if (xi >= 0 && xi < 12 && yi >= 0 && yi < 8) {
botoes[yi][xi].setBorder(border);
}
xi += 1;
}
yi += 1;
}
}
public static void main(String[] args) {
new Janela().setVisible(true);
}
}
1 curtida
Já tinha trocado para JLabel o tabuleiro.
Obrigado mais uma vez diego12.
Vou tentar aqui com o código que você colocou.