Friday, April 1, 2011

Moving Objects and Sprite Manager - Part 2

If you didn't read Part 1, it is better to read it first.

Part 1 is an example of a simple bouncing ball in a black background. Erasing the ball is simple, just use the black color to draw the ball.

If we have a nice jpeg photo to be used as the background, the above method doesn't work, because it would leave a "black hole" to the background.

The solution is simple, instead of erasing the ball, just redraw the background photo. Let's have a look at the background photo first :

This nice background is copied from the following link, special thanks to Jessica Crabtree for adding the photo to the public domain.
http://www.jessicacrabtree.com/journal1/public-domain-nature-photos

Save the above photo as background.jpg and put it to the same folder as BgBouncingBall.java

BgBouncingBall.java is a modified version of BouncingBall.java in the previous article.

/******************************************************************************
* File : BgBouncingBall.java
* Author : http://java.macteki.com/
* Description :
*   Display a bouncing ball with a jpeg background.
*   Required "background.jpg" in the running folder.
* Tested with : JDK 1.6
******************************************************************************/


import java.awt.image.BufferedImage;

class BgBouncingBall extends javax.swing.JPanel implements Runnable
{
  // image object for double buffering
  BufferedImage drawingBoard=new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);

  // image object for holding the background JPEG
  BufferedImage backgroundImage;

  int xBall=100, yBall=100;   // initial coordinates of the moving ball
  int xVelocity=3;            // moving 3 pixels per frame (to the right)

  public BgBouncingBall() throws Exception
  {
    int w=drawingBoard.getWidth(this);
    int h=drawingBoard.getHeight(this);
    this.setPreferredSize(new java.awt.Dimension(w,h));

    // read background image 
    String jpeg_file="background.jpg";
    backgroundImage = javax.imageio.ImageIO.read(new java.io.File(jpeg_file));

    // Note : the background image is bigger than the drawing board,
    //        it will be clipped automatically
    
  }
 
  // override the paint() method, we don't count on the system.
  // We draw our own panel.
  public void paintComponent(java.awt.Graphics gr)
  {
    // Redraw the whole image instead of redrawing every object in the screen.
    // This technique is commonly known as "double buffering"
    gr.drawImage(drawingBoard,0,0,this);
  }  


  // start the bouncing thread
  public void start()  
  {
    new Thread(this).start();
  }

  // thread entry point
  public void run()
  {
    try
    {
      while (true)
      {
        moveBall();       // move the ball to a new position
        repaint();        // redraw the panel.
        Thread.sleep(30); // delay and let the user see the ball.
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  
  public void moveBall()
  { 
    // Double Buffering Technique :
    // Erase and redraw everything in a image object 
    // instead of directly drawing to the screen.
    java.awt.Graphics2D gr=(java.awt.Graphics2D) drawingBoard.getGraphics();


    // redraw the background image.
    // this effectively erase all sprites.

    gr.drawImage(backgroundImage,0,0,this);

    // update ball position
    int diameter=10;  // diameter of the ball
    xBall+=xVelocity;
    if (xBall>=300-diameter || xBall<0) // hit border
    {
      xBall-=xVelocity;        // undo movement
      xVelocity=-xVelocity;    // change direction of velocity
    }

    // draw ball at new position
    gr.setColor(java.awt.Color.RED);  // this is the ball color
    java.awt.geom.Ellipse2D newCircle=
      new java.awt.geom.Ellipse2D.Double(xBall,yBall,diameter,diameter);

    gr.fill(newCircle);
  }

  public static void main(String[] args) throws Exception
  {
    javax.swing.JFrame window = new javax.swing.JFrame();
    window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    window.setTitle("Macteki bouncing ball");

    BgBouncingBall ball=new BgBouncingBall();
    window.add(ball);

    window.pack();
    window.setVisible(true);
    
    ball.start();
  }
}

Part 2 completed. To be continued...

No comments:

Post a Comment