Morgan Blem Morgan Blem - 7 months ago 29
Java Question

How to draw from an array on click?

I've been playing around with the JPanel below. At the moment, I've created a couple circles, one of which you can move around with the WASD keys.

The problem I am facing lies in the mouse listener. I would like to be able to click, and upon doing so, have a player created (from the "towers" array) and drawn on the location of the mouseclick, to a maximum of 30 players (it's for a tower defense game).

The code below compiles without errors, but I get a runtime error as soon as I click on the screen. I know what my mistake is, but I don't know how I can get around it.. Using this.draw(g); in the paint method returns a cannot find symbol error for draw. How can I correct my code such that I will be able to create and draw a player at the location of my mouse? If you want more info on my objects etc, I've pasted all 3 of the classes in the project over here: http://pastebin.com/cLHsRU4y

public class game extends javax.swing.JPanel implements KeyListener{
private int x = 20;
private int y = 20;
private int cnt = 0;
private player Player;
private player maximus;
private player[] towers;

public game() {
setFocusable(true);
addKeyListener(this);

addMouseListener(new MouseAdapter(){
@Override
public void mousePressed(MouseEvent m)
{
if(cnt==0)
{
setArray();
}
int mx=m.getX();
int my=m.getY();
towers[cnt].setX(mx); //NULL POINTER EXCEPTION ON THIS LINE
towers[cnt].setY(my);
// towers[cnt].draw(z);
cnt++;


//repaint();
cnt++;
}
});
Player = new player(100,100);
maximus = new player(490,300);
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

setBackground(new java.awt.Color(200, 22, 0));

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 907, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 521, Short.MAX_VALUE)
);
}// </editor-fold>
public void setArray()
{
player towers[] = new player[30];
for(int i=0; i<30; i++)
{
towers[i] = new player(5,5);
}
}

public void paint(Graphics g)
{
g.setColor(Color.gray);
g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(Color.ORANGE);
g.fillOval(x, y, 20,20);
Player.draw(g);
maximus.draw(g);
if(cnt>0)
{
towers[cnt].draw(g);
}


repaint();
}


@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {
int c = e.getKeyCode();
if(c==KeyEvent.VK_W)
{
y-=1;
Player.setYDir(-1);
}
if(c==KeyEvent.VK_S)
{
y+=1;
Player.setYDir(1);
}
if(c==KeyEvent.VK_A)
{
x-=1;
Player.setXDir(-1);
}
if(c==KeyEvent.VK_D)
{
x+=1;
Player.setXDir(1);
}


}
@Override
public void keyReleased(KeyEvent e) {
Player.setXDir(0);
Player.setYDir(0);
}

// Variables declaration - do not modify
// End of variables declaration


}

Answer

You are not setting the proper array... in the setArray() method, you should be using this.towers [the global variable you declared and are trying to use when you get your NPE] to set instead of creating a local variable that is just going to be garbage collected at the end of the method. (How you have it right now, no elements currently exist in your array to work with).

public void setArray()
{
    //Use the global variable and don't create a local one
    this.towers = new player[30];
    for(int i = 0; i < 30; i++)
    {
        towers[i] = new player(5,5);
    }
}
Comments