Heya guys, i have been trying to make this very famous ball game using java swing. although the primary code ihave used is from this link [Click Here](http://www.edu4java.com/en/game/game6.html)but been trying to modify it to make it look less complex..But everytime i run it it gives me following error:

Exception in thread "main" java.lang.NullPointerException

Exception in thread "main" java.lang.NullPointerException
    at ballGame.Ball.collision(mainGame.java:209)
    at ballGame.Ball.move(mainGame.java:196)
    at ballGame.mainGame.main(mainGame.java:65)

so, plz can anybody help me with this??

package ballGame;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


class mainGame
{
    private static Graphics2D g;

    public static void main(String args[])
    {
        JFrame mainFrame=new JFrame();
        mainFrame.setLocationByPlatform(true);
        mainFrame.setLocation(500,60);

         Racket rkt = new Racket(mainFrame);
         Ball bl = new Ball(mainFrame);

          addKeyListener(new KeyListener(){

            @Override
            public void keyTyped(KeyEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                rkt.keyReleased(e);
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub
                rkt.keyPressed(e);
            }

          });

          setFocusable(true);


          bl.move();
          rkt.move();

          Graphics2D g2d = (Graphics2D)g;
          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
          bl.paint(g2d);
         rkt.paint(g2d);


        mainFrame.setSize(300, 400);
        mainFrame.setVisible(true);
        mainFrame.setResizable(false);

    }

    private static void setFocusable(boolean b) {
        // TODO Auto-generated method stub

    }

    private static void addKeyListener(KeyListener keyListener) {
        // TODO Auto-generated method stub

    }
}


class Racket
{
    private static final int Y=330, width=60,height=10;
    int x=0, xa=0;

    JFrame jf;

    Racket()
    {

    }

    Racket(JFrame j)
    {
        jf=j;
    }

    public void move()
    {
        if(x+xa>0 && x+xa < jf.getWidth()-width)
        {
            x+=xa;
        }

    }

    public void paint(Graphics2D g)
    {
        g.fillRect(x,Y,width,height);
    }

    public void keyReleased(KeyEvent e)
    {
        xa=0;
    }

    public void keyPressed(KeyEvent e)
    {
        if(e.getKeyCode()==KeyEvent.VK_LEFT)
        {
            xa=-1;
        }
        if(e.getKeyCode()==KeyEvent.VK_RIGHT)
        {
            xa=1;
        }
    }

    public Rectangle getBounds()
    {
        return new Rectangle(x,Y,width,height);
    }

    public int getTopY()
    {
        return Y;
    }

}

class Ball
{
    private static final int diameter=30;

    int x=0;
    int y=0;
    int xa=1;       //velocity for x co-ordinate
    int ya=1;       // velocity for y co-ordinate

    JFrame jf;

    Racket rt;



    Ball(JFrame j)
    {
        jf=j;
    }


    public void move()
    {
        if(x+xa<0)
        {
            xa=1;
        }
        if(x+xa>jf.getWidth()-diameter)
        {
            xa=-1;
        }
        if(y+ya<0)
        {
            ya=1;
        }
        if(y+ya>jf.getWidth()-diameter)
        {
            ya=-1;
    }
        if(y+ya>jf.getHeight()-diameter)
        {
        //  gameover();
        }

        if(collision())
        {
            ya=-1;

            y=rt.getTopY()-diameter;    
        }
        x=x+xa;
        y=y+ya;

    }

    private Boolean collision()
    {
            return rt.getBounds().intersects(getBounds());
    }

    public void paint(Graphics2D g)
    {
        g.fillOval(x, y, diameter, diameter);
    }

    public Rectangle getBounds()
    {

        return new Rectangle(x,y,diameter,diameter);

    }

}

The message tells you the error is on line 200 - y=rt.getTopY()-diameter; - null pointer means uninitialised variable, or a method returned a null that you then tried to use. In that line the only thing that could be null is rt. Now look for that variable - it's declared on line 163, but you never give it a value, so it's null.

You also seem to have lost some essential code. There's no way that your existing code will ever draw anything in the JFrame. You need a JPanel in the JFrame in which to draw, and override its paintComponent method to do the drawing.

Finally, I would be very careful about using that web site as a source of good coding practice. Even in that small example there are (at least) three horrible examples (painting a whole JFrame every time the content changes, and expecting a loop with a thread sleep as a timing mechanism, throwing exceptions from main).

Edited 2 Years Ago by JamesCherrill

hey thanks. Though u r right about the website' code for the game but i had a lot of troubles finding a decent ball game to start with before coming across that..so, can u plz suggest me some good links about the same??

This thread ends with a sample program I wrote to demo the best simple way to animate multiple things moving around the window. It also discusses collisions, which will probably be relevant to a ball game. Have a look at that then come back here with your follow-on questions.

Comments
thanks mate!!

Hey, thanks for the programme u wrote and i've read it. if i want to make the sprite collide with the wall, do i still have to go with the rectangular method or just few changes in velocity and position will work??
i tried to do the latter but it didn't work..

If it can only approach the wall from one side, then a simple test of the sprite's x value (for a vertical wall) is enough. Something like:

if (sprite.x >= wall.x) 
   sprite.xVelocity = - sprite.xVelocity // bounce off the wall

If the wall is a 2D object that can be hit from either side (or on the top) then use a Rectangle.

Here is what i did to your code..but it's gotten worse.can u help me out??

public class mainGame extends JPanel
{


    public static void main(String args[])
    {
        JFrame frame = new JFrame("hello");

        mainGame mainPanel = new mainGame(600, 400);

        SimpleSprite st = new SimpleSprite(mainPanel);

        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }


    private ArrayList<SimpleSprite> sprites = new ArrayList<SimpleSprite>();

    final static int timer_msec=30;

mainGame(int width, int height)
{
    setPreferredSize(new Dimension(width, height));
    sprites.add(new SimpleSprite(Color.blue, 0, 35, 2, 1));

    startTimer();

}

public void startTimer()
{
    java.util.Timer timer = new java.util.Timer();
    TimerTask timerTask = new TimerTask()
    {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            updateSimulation();
        }

    };
    timer.scheduleAtFixedRate(timerTask, 0, timer_msec);

}

public void updateSimulation()
{
    for(SimpleSprite s: sprites)
    {
        s.update();
    }
    repaint();
}

public void paintComponent(Graphics g)
{
    Graphics2D g2d = (Graphics2D) g;
    paintBackground(g2d);
    for (SimpleSprite s : sprites) {
       s.draw(g2d);
}
}

public void paintBackground(Graphics2D g2d)
{
    g2d.setColor(Color.LIGHT_GRAY);
    g2d.fillRect(0, 0, getWidth(), getHeight());
}

}

class SimpleSprite extends JPanel
{
       // basic x,y movement at constant velocity
       float x, y, dx, dy; // position and velocity (pixels/TIMER_MSEC)
       Color color;
       float width=0;
       SimpleSprite(mainGame g)
       {
           width=g.getWidth();
       }

       public SimpleSprite(Color color, float x, float y, float dx, float dy) {
          // initial position and velocity
          this.color = color;
          this.x = x;
          this.y = y;
          this.dx = dx;
          this.dy = dy;
       }
       public void update() { // update position and velocity every n milliSec

            x += dx; // velocity in x direction
            y += dy; // velocity in y direction

            if(x<0)
           {
              dx+=dx;
           }
           if(x>width)
           {
               dx-=dx;
           }
           if(y<0)
           {
               dy+=dy;
           }
           if(y>width)
           {
               dy=-dy;
           }


       }
       public void draw(Graphics2D g2d) {
          g2d.setColor(color);
          g2d.fillOval((int) x, (int) y, 100, 100); // draw this at latest position.
       }
    }

Hey, i made corrections as u suggested but still nothing works..the ball is not colliding off the wall at all.. i am having problem in understanding the concept of collision and relation of velocity while the ball is made to bounce back. and also i have passed the width of the game panel into the class SimpleSprite so am i right over there?.plz, can u help me out in here..

public class mainGame extends JPanel
{


    public static void main(String args[])
    {
        JFrame frame = new JFrame("hello");

        mainGame mainPanel = new mainGame(600, 400);

        SimpleSprite st = new SimpleSprite(mainPanel);

        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }


    private ArrayList<SimpleSprite> sprites = new ArrayList<SimpleSprite>();

    final static int timer_msec=30;

mainGame(int width, int height)
{
    setPreferredSize(new Dimension(width, height));
    sprites.add(new SimpleSprite(Color.blue, 0, 35, 2, 1));

    startTimer();

}

public void startTimer()
{
    java.util.Timer timer = new java.util.Timer();
    TimerTask timerTask = new TimerTask()
    {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            updateSimulation();
        }

    };
    timer.scheduleAtFixedRate(timerTask, 0, timer_msec);

}

public void updateSimulation()
{
    for(SimpleSprite s: sprites)
    {
        s.update();
    }
    repaint();
}

public void paintComponent(Graphics g)
{
    Graphics2D g2d = (Graphics2D) g;
    paintBackground(g2d);
    for (SimpleSprite s : sprites) {
       s.draw(g2d);
}
}

public void paintBackground(Graphics2D g2d)
{
    g2d.setColor(Color.LIGHT_GRAY);
    g2d.fillRect(0, 0, getWidth(), getHeight());
}

}

class SimpleSprite extends JPanel
{
       // basic x,y movement at constant velocity
       float x, y, dx, dy; // position and velocity (pixels/TIMER_MSEC)
       Color color;
      private static float width=600;;
       SimpleSprite(mainGame g)
       {
           width=g.getWidth();
       }

       public SimpleSprite(Color color, float x, float y, float dx, float dy) {
          // initial position and velocity
          this.color = color;
          this.x = x;
          this.y = y;
          this.dx = dx;
          this.dy = dy;
       }
       public void update() { // update position and velocity every n milliSec

           x += dx; // velocity in x direction
           y += dy; // velocity in y direction

            if(x<0)
           {
              dx=+dx;
           }
           if(x>width)
           {
               dx=-dx;
           }





           if(y<0)
           {
               dx=+dx;
           }
           if(y>width)
           {
               dx=-dx;
           }


       }
       public void draw(Graphics2D g2d) {
          g2d.setColor(color);
          g2d.fillOval((int) x, (int) y, 100, 100); // draw this at latest position.
       }
    }

OK, i've struggled for few more days and have find a completely different solution for moving ball game.But the problem is when i try to add keyEvents it doesn't work at all, that is the same problem which was appearing with the previous code but this time the ball is moving and colliding up and against the wall.So, can anybody help me with adding keyEvents to this??

package ballGame;


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.util.*;


public class mainGame extends JPanel
{

int x=0, y=10, width=50,height=50, width_bar1=10, height_bar1=100;
int width_bar2=10, height_bar2=100, x_bar2=575, y_bar2=50, velbar_y2=1;

int x_bar1=0, y_bar1=50, velbar_y1 =1;
int dx=1, dy=1;

java.util.Timer move;
static JFrame frame;

mainGame()
{
    frame = new JFrame("Ball Bounce");
    frame.setLocationByPlatform(true);
    frame.setLocation(450,50);
    frame.setSize(600,600);
    frame.setVisible(true);


    setForeground(Color.red);

    move=new java.util.Timer();

    move.scheduleAtFixedRate(new TimerTask()
    {
        public void run()
        {
            if(x<0)
            {
                dx=1;
            }
            if(x>=getWidth()-45)
            {
                dx=-1;
            }
            if(y<0)
            {
                dy=1;
            }
            if(y>=getHeight()-45)
            {
                dy=-1;
            }
            x+=dx;
            y+=dy;
    /*  
            if(y_bar1<0)
                velbar_y1=1;

            y_bar1+=velbar_y1;

            if(y_bar1>getWidth()-height_bar1)
                velbar_y1=-1;
            if(y_bar2<0)
                velbar_y2=1;
            if(y_bar2>getWidth()-height_bar2)
                velbar_y2=-1;

            y_bar2+=velbar_y2;
        */
            repaint();
        }
    },0,10);



    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



}

public void paint(Graphics g)
{
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.fillOval(x,y,width,height);
    g2d.fillRect(x_bar1, y_bar1, width_bar1, height_bar1);
    g2d.fillRect(x_bar2, y_bar2, width_bar2, height_bar2);
}
    public static void main(String[] args)
    {
        mainGame ball= new mainGame();
        frame.add(ball);
    }

    }
This article has been dead for over six months. Start a new discussion instead.