Wednesday, June 2, 2010

Java Useful base classes for Java Game Programming Tutorial

To make the job of game making easier, I wrote three useful classes, GameApplet, GamePanel and Game. You will only

need to extend Game (that is, write a succesor class that will handle game information), while the classes I wrote

handle input (by listening to it, and informing your class whenever an input event happens) and output (by asking

your game class for what to paint on the screen). Apart from writing your own game class, change the line

game=new TryGame();

in GameApplet- write the name of your class instead of TryGame.

Here is some explanation about the classes and how they work.
GameApplet.java: an applet class, that starts GamePanel and the current game class.
GamePanel.java: a Panel class. It has an animation thread that causes the screen to
update itself many times a second. GamePanel calls the current game class to ask it what to paint on the screen.
GamePanel also listens for mouse and keyboard input, and whenever it gets one, it calls the relevant method of the current game class.
Game.java: this is an abstract class. The game class you write will extend Game.java, and
override it’s methods to display the screen and handle output.

Initiation of GamePanel and the game.

Code from GameApplet.java:

private GamePanel gp;

private Game game;

public void init()

{

game=new TryGame();

gp=new GamePanel(game);

game.setup(this, gp);

add(gp);

gp.requestFocus();

gp.start();

}

GameApplet initiates an instance of the game class that you will write (TryGame is a simple test class I wrote),

and an instance of GamePanel, which gets ‘game’ as a parameter. Then it calls game.setup(), which should do all things

to be done before the game starts (it calls the method init(). By overriding init(), you will be able to specify what should

be done before the game starts). add(gp) will display the game panel, gp.requestFocus()

asks that keyboard input will be sent to GamePanel, and gp.start() starts the animation thread of GamePanel.

The animation thread

Code from GamePanel.java:

AnimationThread thread;

private int sleeptime=40;

. . .

public void start(){

thread= new AnimationThread(this);

thread.start();

}

public void setSleepTime(int ms){

sleeptime=ms;

}

. . .

public void paint(Graphics g){

//Fills everything with background color.

//You might want to skip this part if you do not need to clear the panel every frame

//To do this, add an abstract method to Game, called “public boolean clearPanel()” that

//will tell whether the panel should be cleared.

Color c=game.getBackgroundColor();

if(c!=null){

g.setColor(c);

g.fillRect(0,0,getWidth(), getHeight());

}

game.paint(g);

}

. . .

class AnimationThread extends Thread {

private GamePanel gp;

AnimationThread(GamePanel g) {

gp=g;

}

public void run() {

while(true){

try{

sleep(sleeptime);

} catch (Exception e){

e.printStackTrace(System.err);

}

if(!gp.isPaused())

gp.repaint();

}

}

GamePanel starts a thread (that is, a paralel process), that does nothing but runs a loop of waiting a certain

period of time, and then call the “repaint()” method, which causes the Panel to call the paint method. Paint()

asks Game (or, more correctly, your class that extends Game), what is the background color, and fills the

background. Then it calls Game’s paint, giving it the Graphics to be used for painting. You will override paint,

and use the Graphics to draw whatever should be drawn in this screen.

Note that the time that passes between each repaint is stored in ‘sleeptime’. You can use setSleepTime() method to

make the game run faster or slower. Remeber that this parameter is in milliseconds.

Handling input

GamePanel handles keyboard and mouse input. Here I will explain about mouse input. Keyboard input works similarly.

Code from GamePanel.java:

public GamePanel(Game g){

game=g;

addMouseListener( new MouseAdapter() {

public void mousePressed(MouseEvent e){

game.mousePressed(e);

}

public void mouseClicked(MouseEvent e){

game.mouseClicked(e);

}

public void mouseReleased(MouseEvent e){

game.mouseReleased(e);

}

public void mouseEntered(MouseEvent e){

game.mouseEntered(e);

}

public void mouseExited(MouseEvent e){

game.mouseExited(e);

}

});

As you can see, right in the beggining GamePanel gets a mouse listener. It watches for events that can happen with the mouse.

If a mouse will be clicked on the panel, the method “mouseClicked()” will be called, with an Event object that describes the

click (e.getX(), for example, will tell you the X coordinate of where the mouse was clicked). GamePanel does nothing with the

input information- it passes it to the class you made, game. If you want to do something whenever the mouse is clicked,

override Game’s method mouseClicked(MouseEvent e).

Tools in Game class

As I told before, Game is an abstract class that you should override with your game class. It has “transparent” input and paint

methods that will be called by GamePanel, and which you should override. It also has some useful methods that you can call from

your game (there is explanation on how to use them in comments in the code.):
setSleepTime: use this method to change the time period between each repaint.
resize: a very important method that sets the size of the GamePanel (in pixels).
readBufferedImage: a method that imports images into the game. Its argument is the name of the image file.
getMousePosition: returns a Point object that gives the coordinates of the mouse.
setCursor: a method that enables you to change how your cursor looks like.
setTransparentCursor: makes the cursor to become transparent.

To demonstrate the features of my three classes, I wrote a “game” that uses almost all the tools I created:

You can read it’s code to understand how things should work.

TryGame has a variable called ‘i’, that is incremented with each call to repaint. getBackground color is used

to have the background change as ‘i’ changes:

public Color getBackgroundColor() {

return new Color(i%255,0,0);

}

. Additionaly, in each call to paint, the mouse position is read, and the white ball coordinates are moved closer to it:

Point p=gp.getMousePosition();

if(p!=null){

ballX=(int)(0.95*ballX+0.05*p.getX());

ballY=(int)(0.95*ballY+0.05*p.getY());

}

And here the ball is drawn:

g.setColor(Color.white);

g.fillOval(ballX-10,ballY-10,20,20);

An another variable, “char c”, stores one character it reads from the keyboard (to make the applet get input from the keyboard)

click on it once):

public void keyTyped(KeyEvent e){

if(e.getKeyChar()!=KeyEvent.CHAR_UNDEFINED)

c=e.getKeyChar();

}

keyTyped overrides Game’s keyTypes, and is thus called whenver GamePanel sees that a key was typed.

No comments:

Post a Comment