JavaReference.com AllDevNet.com"
Welcome Guest     Login     Register    
 [ Home > Articles > Java Game Programming, Part V ]  Submit Article   
Java Game Programming, Part V
[ by Vijay Kukreja ]
Print   E-Mail 
About the Author
Vijay is an Information Systems Architect at CVS Pharmacy in Rhode Island. His primary focus is J2EE technology based solution Design and Development. Along with a combination of other enterprise technologies he believes that J2EE will become a primary driving force in the delivery of enterprise level systems. Vijay has participated in numerous consulting projects over the past six years. He has a Masters in Computer Science and a Sun Certified Java Programmer and Architect. His projects involve UML, Java, JSP/Servlets, EJB's, CORBA, XML, JMS, MQSeries & various tools. He has provided onsite J2EE and/or XML development at high-tech companies located in and around Massachusetts, CT and RI. He has also published articles on Java Programming, C++ and other technologies, in various online magazines and with other consultants and is a frequent writer on Java and related technologies. He can be reached at vijay (at) javareference (dot) com
More articles by Vijay Kukreja 
Advertisement

Moving the ball

This time we will get into the basics of motion. Like we used to learn in physics class, anything that goes up, must come down. You could leave out the concept of gravity and create an interesting variant, but we are going to introduce motion in accordance with laws of gravity and bounce the ball from one end of the screen to the other and from top to bottom.

When the ball collides with a brick, the user earns some points. When the ball collides with the bat, it bounces back in the opposite direction. Also if you miss to get the bat in contact with the ball you would lose the game. So how do we introduce motion for the ball?

Well there are two ways. One by putting a big loop that says

While(game does not end)
(
        Move the ball in a direction
        If collision then change direction
        Delay for sometime
        Continue loop
}

Having a loop has a basic problem. It will make the whole program dependent on the loop. Since this kind of program will run everything inside of this loop, it is not possible to make the ball bounce around and actually see it happen. This is because, writing such a loop (called a tight loop), does not leave the system enough time to paint the picture (call the paint method). This means that although the coordinates for the ball and bat entities may change in memory, it may not be reflected in the actual picture of the game being painted, thus leading to one ineffective game.

The solution is to give the system enough time to paint the window. This can be done by not overloading the main thread, or the thread in which the paint happens. This thread will only be responsible for painting the window. All other logic should be moved to other threads of execution, making the game more responsive to user control.

“Threads” are small units of work that are independent processes. Some main thread starts these threads and then they execute in parallel until their condition to exit is satisfied. So we have to now understand the concept of threads in Java. Java provides us with a class called Thread and an interface called Runnable. Any program can create an instance of thread and start or stop that thread. Any program implementing the Runnable interface must provide for the method run() which is an integral part of the thread concept. Threads basically execute as a separate piece of code inside the Java Virtual machine. Each java program actually is a thread. So how does one create a thread ?

Thread bounceBall=new Thread();

Now that was easy wasn't it. But there is more than just creating a thread. We need to tell it who owns it and who has started it.

Thread bounceBall=new Thread(this);

Just creating the thread does not mean it will start execution. We have to specify when the thread should start execution. So we need to specify bounceBall.start(); when we want the ball bouncing thread to start execution. When threads start execution, internally the method run () of the thread is executed. We will need to provide a run method for the bouncing thread to achieve the desired effect. Here it is...

/*
* A simple brick game in Java.
*Program Name: Bricks a simple a Java Game.
*File Name : BricksGame
*Author: Vijay Kukreja
*Date: 13-June-2001
*Version : 1.0
*/

package JavaGames;

//Lets keep all our files under one package
//lets import the necessary classes to which will create the GUI

import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
// Let us import our other entities like bricks and ball and bat into the wall.


//our main class for the application now implements runnable interface indicating
//that there are threads in the system then the run method would be executed.

public class  BricksGame extends Frame implements Runnable 
{
    //Some variable declarations
    //Let us declare those here and use them in our wall.
    BricksEntity mBrick;
    BallEntity mBall;
    BatEntity mBat;
    int iFramex=0;
    int iFramey=0;
    int iFrameh=500;
    int iFramew=800;
    
    //declare a thread variable which will be taking care of animation of ball
    Thread bounceBall=null;

    //the constructor where we'll initialize our environment and create the frame
    public BricksGame()
    {
        this.setBounds(iFramex,iFramey,iFramew,iFrameh);
        this.setTitle("Welcome to Bricks Game");
        //Let us create live objects out of our entity classes.
        mBrick=new BricksEntity();
        mBall=new BallEntity();
        mBat=new BatEntity();
        this.setVisible(true);
        //initialize the sizes of the bricks and ball and bat
        initBrick();
        initBall();
        initBat();
        //create the instance of the thread which will be taking care
        //of the balls motion
        bounceBall = new Thread(this);
        //start the execution of this thread now
        bounceBall.start();

    }

    public void run()
    {
        //variables for storing direction of the ball and its amount of distance
        //by which we move it in the next movement
        int direction=1;
        int distance=10;
        //continue till the program ends
        while(true)
        {
            //just a temporary variable for storing intermediate ball position
            int tempTop=0;
            //check and see which direction the ball is going
            //if direction is set to go up i.e. 2 then subtract distance
            //if direction is set to go down then add distance
            switch(direction)
            {
            case 1:
                tempTop=mBall.getTop()+distance;
                break;
            case 2 : 
                tempTop=mBall.getTop()-distance;
                break;
            }
            
            //update the balls position in the datastructure
            mBall.setTop(tempTop);
            //if you have reached bottom change directions
            if(mBall.getTop()>=350)            direction=2;
            //if you have reached the top change directions
            if(mBall.getTop()<=50)            direction=1;
            //redraw the ball at new locations
            this.repaint();
            
            //putting the thread to sleep so we can create some delay
            //so the ball's motion looks natural.
            try
            {
                Thread.sleep(300);
                // as thread.sleep needs that it be inside try and catch block.
                // when a thread is put to sleep it can throw and exception.
                // read article for details on try catch blocks.
            }
            catch(Exception e)
            {
                System.out.println("Error in running thread " + e);
            }
        }
    }

    public void paint(Graphics g)
    {
        //setCOlor() method is used to set the color by which you will be filling the object
        g.setColor(Color.red);
        g.fillRect(mBrick.getLeft(),mBrick.getTop(),mBrick.getWidth(),mBrick.getHeight());
        g.setColor(Color.blue);
        g.fillRect(mBat.getLeft(),mBat.getTop(),mBat.getWidth(),mBat.getHeight());
        g.setColor(Color.green);
        g.fillOval(mBall.getLeft(),mBall.getTop(),mBall.getHeight(),mBall.getWidth());
    }

    public void initBrick()
    {
        mBrick.setTop(50);
        mBrick.setLeft(10);
        mBrick.setHeight(20);
        mBrick.setWidth(50);
    }
    
    public void initBall()
    {
        mBall.setTop(150);
        mBall.setLeft(100);
        mBall.setHeight(40);
        mBall.setWidth(40);
    }
    
    public void initBat()
    {
        mBat.setTop(400);
        mBat.setLeft(100);
        mBat.setHeight(20);
        mBat.setWidth(100);
    }

    //the main method the entry point into our game program.
    public static void main(String[] args) 
    {
        System.out.println("Welcome to the Bricks Game!");
        BricksGame m_bricksGame=new BricksGame();
    }


    //In case someone wants to close the program from the Frame we need to
    //process the window closing event and handle it appropriately

    protected void processWindowEvent(WindowEvent e)
    {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING)
        {
            System.exit(0);
            //close the window and exit out of the program.
        }
    }
}

The new program implements the Runnable interface. Also there are colors in the various objects. The output of this program is as follows :

Bouncing ball 1

Bouncing ball 2

The ball has started to bounce. We will need to add more directions, take care of conditions when it hits the sidewalls and much more. The more you can think of, the more fun it becomes. Click here for the source code in .zip format.

In the next article I'll be covering the details of how to control the bat and move it around with the help of arrow keys. In java we will use the various techniques to control keyboard input and drive the game a step further...


Print   E-Mail 
  Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. and its subsidiaries in the U.S. and other countries.