JavaReference.com AllDevNet.com"
Welcome Guest     Login     Register    
 [ Home > Articles > Java Game Programming, Part VI ]  Submit Article   
Java Game Programming, Part VI
[ 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 bat

This time we will get into adding some motion to the bat. Now need to introduce the control for the user to move the bat. Thus we will be covering another area of Java i.e. how to handle actions and events. In Java any external event is captured using a Listener for that action. And then using the appropriate method, which will handle that event, we put the movement logic in that method.

First of all, any class who wants to listen to any keyboard events must implement the appropriate listener interface. For our purposes we will have to use KeyListener interface. We are interested in capturing the pressing and releasing of a key on the keyboard, especially the arrow keys. So we can move the bat accordingly in the left or right direction. So to listen for the keystrokes on the frame area of our game we need the Frame class to implement this interface. Thus our changed class definition will look like:

public class  BricksGame extends Frame implements Runnable ,KeyListener

Now we need to add this KeyListener capability to our game object. As we have to handle the events on the keyboard ourselves so we attach the listener to our Frame code as follows:

addListener(this);



Thus any key event occurring on the frame area would be pumped through the keyevent handler method. Lets add this handler:

public void keypressed(KeyEvent e)

    // e.getKeycode() will give us the code of which key was pressed.
{}

We need to add the logic to move the bat in this method.

All keystrokes have a standard equivalent value, for example.

VK_A, VK_B, VK_ESCAPE for 'a','b' and Esc respectively. Etc. So we will trap the left and right arrow keys..

As KeyListener is an interface, we need to implement all the methods in this interface even though we don't use them. Lets add the logic for the bat movement now :

/*
A simple brick game in Java.
Program Name: Bricks a simple a Java Game.
File Name : BricksGame
Author: Vijay Kukreja
Date: 19-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;
//new import in this article for keyboard handling
import java.awt.event.KeyEvent;


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

public class  BricksGame extends Frame implements Runnable , KeyListener

    //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();

        //adding the Key Listening capability to our program
        this.addKeyListener(this);
        
    {}
    
    //this is the method we want for our arrow keys
    public void keyPressed(KeyEvent e) 
        //lets take out the code of which key was pressed.
        int keyCode = e.getKeyCode();
        
        //now lets switch for our arrow keys
        int tempMove=mBat.getLeft();
        
        switch(keyCode)
        {
        case java.awt.event.KeyEvent.VK_LEFT:    //left arrow key
            tempMove-=15;
            break;
        case java.awt.event.KeyEvent.VK_RIGHT:    //right arrow key
            tempMove+=15;
            break;
        {}
        //lets move it
        mBat.setLeft(tempMove);
        //lets refresh the screen
        this.repaint();
    }
    
    // we don't have to do anything here
    public void keyTyped(KeyEvent e)  {}
    // we have nothing to do here also.
    public void keyReleased(KeyEvent e) {}
    
    
    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.
        {}
    }
}

Here is the output of our game when the bat can be moved left and right.

Moving the Bat 1

Moving the Bat 2

As you can see the bat can easily be dragged out of the screen and there are no checks made to see if the bat stays within the screen or not. So we need to add logic for detecting the wall limits and not allowing the bat to go through it.

We need to update our BrickEntity so we can add one more variable which will tell us whether the brick is enabled or disabled.

Here is the new code of the BricksEntity class. We will use it in our next article.

/*
A simple brick game in Java.
Program Name: Basic entity Ball defined here.
File Name : BallEntity
Author: Vijay Kukreja
Version : 1.0
*/

package JavaGames;

//Lets keep all our files under one package
//there is nothing to import for creating the ball entity

//our ball entity class
public class  BricksEntity 

    //Some attributes of Ball
    private int top=0;
    private int left=0;
    private int height=0;
    private int width=0;
    //value for enabling or disabling the display of a brick
    private boolean enabled=true;
    
    public BricksEntity()
    {

    {}

    
    //some get/set methods for brick
    public boolean getEnable()
    
        return enabled;
    {}
    
    public void setEnable(boolean b)
    
        enabled=b;
    {}
    
    public int getTop()
    
        return top;
    {}
    public int getLeft()
    
        return left;
    {}
    public int getHeight()
    
        return height;
    {}
    public int getWidth()
    
        return width;
    {}
    //setter methods
    public void setTop(int t)
    
        top=t;
    {}
    public void setLeft(int l)
    
        left=l;
    {}
    public void setHeight(int h)
    
        height=h;
    {}
    public void setWidth(int w)
    
        width=w;
    {}

//end of BricksEntity

In the next section of the code with the boundary collision you will see that I have added the bricks.

The ball will blast these bricks as it hits a brick. Lets see the code for adding the bricks and boundary collision for the bat.

/*
A simple brick game in Java.
Program Name: Bricks a simple a Java Game.
File Name : BricksGame
Author: Vijay Kukreja
Date: 19-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;
//new import in this article for keyboard handling
import java.awt.event.KeyEvent;


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

public class  BricksGame extends Frame implements Runnable , KeyListener

    //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");
        //The bricks need to be in an array as there are more than one bricks and
        //it's easier logically to handle these bricks.
        mBrick=new BricksEntity[10];
        //initialize the bricks before the paint is called.
        initBrick();
        //Let us create live objects out of our entity classes.
        mBall=new BallEntity();
        mBat=new BatEntity();
        //initialize the sizes of the bricks and ball and bat
        initBall();
        initBat();
        //call paint so it refreshes the whole scene.
        this.setVisible(true);
        //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();

        //adding the Key Listening capability to our program
        this.addKeyListener(this);
        
    {}
    
    //this is the method we want for our arrow keys
    public void keyPressed(KeyEvent e) 
        //lets take out the code of which key was pressed.
        int keyCode = e.getKeyCode();
        
        //now lets switch for our arrow keys
        int tempMove=mBat.getLeft();
        
        switch(keyCode)
        {
        case java.awt.event.KeyEvent.VK_LEFT:    //left arrow key
            tempMove-=15;
            break;
        case java.awt.event.KeyEvent.VK_RIGHT:    //right arrow key
            tempMove+=15;
            break;
        {}
        //lets move it
        mBat.setLeft(tempMove);
        //lets refresh the screen
        this.repaint();
    }
    
    // we don't have to do anything here
    public void keyTyped(KeyEvent e)  {}
    // we have nothing to do here also.
    public void keyReleased(KeyEvent e) {}
    
    
    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);
        for(int i=0;i<10;i++)
        {
            g.fillRect(mBrick[i].getLeft(),mBrick[i].getTop(),mBrick[i].getWidth(),mBrick[i].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()
    
        int j=0;
        //initialize all the bricks in the list.
        for(int i=0;i<10;i++)
        {
            mBrick[i]=new BricksEntity();
            mBrick[i].setTop(30);
            mBrick[i].setLeft(j);
            mBrick[i].setHeight(30);
            mBrick[i].setWidth(80);
            //next brick left position
            j=j+82;
        {}
        
        
    }
    
    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.
        {}
    }
}

We have a pretty functional game now, with a bouncing ball, a movable bat and bricks that can be blasted away.

Moving the Bat 3

With this, i guess we are coming really close to the end of this article. The will be a concluding part next week. In that I will cover how to test for collision. How to change the direction of the ball and on collision with the bat, how to break the bricks and collect points.


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.