Reputation: 67
I want to move the white box up and down using 'w''s''a''d' keys. This is my code :
static int matrix[][] = { { 1, 1, 1, 1,1,1 }, { 1, 0, 0, 0,0,0 }, { 1, 3, 1, 1,0,0 }, {1,0,1,0,0,0}, {1,0,1,2,2,1}, {1,1,1,1,1,1} };
JPanel easyPanel(){
JPanel panel = new JPanel(new GridLayout(6, 6, 0, 0));
int rowNumber = 0;
int colNumber = 0;
for (int i = 0; i < 36; i++) {
if(colNumber == 6){
colNumber = 0;
rowNumber++;
}
JLabel l = new JLabel();
if(matrix[rowNumber][colNumber] == 0){
l.setBackground(Color.pink);
}
else if(matrix[rowNumber][colNumber]==2){
l.setIcon(new ImageIcon(new ImageIcon("cross.png").getImage().getScaledInstance(70, 70, Image.SCALE_DEFAULT)));
}
else if(matrix[rowNumber][colNumber]==3){
l.setIcon(new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(70, 70, Image.SCALE_DEFAULT)));
int row = rowNumber;
int col = colNumber;
addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent ke) {
//move();
}
@Override
public void keyReleased(KeyEvent ke) {
//move();.
}
@Override
public void keyTyped(KeyEvent ke) {
panel.setVisible(false);
matrix[row][col] = 0;
move(ke,row,col);
}
});
}
private void move(KeyEvent ke,int row,int col){
if(ke.getKeyChar() == 'w'){
System.out.println("Pressed up");
matrix[row-1][col] = 3;
JPanel newGame = easyPanel();
newGame.setVisible(true);
add(newGame);
}
else if(ke.getKeyChar() =='s'){
System.out.println("Pressed down");
matrix[row+1][col] = 3;
JPanel newGame = easyPanel();
newGame.setVisible(true);
add(newGame);
}
else if(ke.getKeyChar() == 'a'){
System.out.println("Pressed left");
matrix[row][col-1] = 3;
JPanel newGame = easyPanel();
newGame.setVisible(true);
add(newGame);
}
else if(ke.getKeyChar() == 'd'){
System.out.println("Pressed right");
matrix[row][col+1] = 3;
JPanel newGame = easyPanel();
newGame.setVisible(true);
add(newGame);
}
else
System.out.println("Invalid Input");
}
But i am getting output something like this :
Default :
Next move 'd' - insted of moving a block, it moves makes two blocks white:
Where am I going wrong? Any help will be appreciated.
Upvotes: 1
Views: 76
Reputation: 347294
So based on this...
} else if (matrix[rowNumber][colNumber] == 3) {
l.setIcon(new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(70, 70, Image.SCALE_DEFAULT)));
int row = rowNumber;
int col = colNumber;
addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent ke) {
//move();
}
@Override
public void keyReleased(KeyEvent ke) {
//move();.
}
@Override
public void keyTyped(KeyEvent ke) {
panel.setVisible(false);
matrix[row][col] = 0;
move(ke, row, col);
}
});
}
Each time easyPanel
is called and it finds a 3
in the matrix, it adds a new KeyListener
, assuming you're updating the matrix correctly, this means that the first time it's called, you register one KeyListener
, then the next time you call easyPanel
, you add another and so and so forth.
The KeyListener
should be registered separately and done so only once. In fact, I'd highly recommend using the key bindings API over KeyListener
, as it will solve the focus related issues
I'd also consider a different update model. Instead of re-creating the UI each time, simply have another matrix of JLabel
s, which is first created based on the matrix
values.
You can then update the matrix
matrix[row][col] = 0;
Then update the label
updateUI(row, col);
which could do something like...
switch (matrix[row][col]) {
case 0: labels[row][col].setIcon(null);
break;
case 2: labels[row][col].setIcon(crossIcon);
break;
case 3: labels[row][col].setIcon(playerIcon);
break;
}
repaint();
This will reduce the amount of overhead and reduce the risk of flickering.
You should also pre-cache and re-use your icons
Upvotes: 2