Anatomy of a Game Engine by Richard Baldwin - HTML preview

PLEASE NOTE: This is an HTML preview only and some elements such as links or page numbers may be incorrect.
Download the book in PDF, ePub, Kindle for a complete version.

following links to easily find and view the images and listings while you are reading about them.

Images

Image 1 . Background image in Windows Paint.

Image 2 . Ladybug image in Windows Paint.

Image 3 . Ladybug image in Windows Picture and Fax Viewer.

Image 4 . Ladybug image in Gimp.

Image 5 . Output from program Slick0140a.

Listings

Listing 1 . Beginning of the class named Slick0140a.

Listing 2 . The main method.

Listing 3 . The overridden init method.

Listing 4 . The overridden render method.

Listing 5 . Source code for the program named Slick0140a.

5.3. Preview

What you have learned

In the previous module, you learned about a property of the GameContainer class named

running , and how it is used by the start method to keep the game loop running.

You learned about the salient features of the gameLoop method of the AppGameContainer class.

You learned about the updateAndRender method of the GameContainer class and how it

decides when and if to call the update and render methods of the object of the Game class that is

wrapped by the container.

You touched on the difference between normal delta and smoothed delta .

You learned about minimumLogicInterval and maximumLogicInterval and how the contents of

those two variables are used to determine if, when, and how many times to call the update method

during each iteration of the game loop. You also learned how the contents of these two variables

are used to determine the value that is passed as delta each time the update method is called.

You learned that the render method is normally called once and only once during each iteration of

the game loop.

You saw a simple example of how you can use the value of delta that is received by the update

method to control the behavior of a game program.

You learned that you can set the size of the game window when you instantiate an object of the

AppGameContainer class by passing dimension parameters to the constructor.

You learned that you can set the target frame rate by calling the setTargetFrameRate method on

the GameContainer object.

You learned how to display text in the game window.

What you will learn

In this module, you will learn that while there are many classes, interfaces, and methods in the

Slick2D library with names that match classes, interfaces, and methods in the standard edition

Java library, they are not the same.

You will learn how to set the drawing mode so that bitmap images drawn in the game window will

either honor or not honor transparent pixels.

You will learn how to draw bitmap images in the game window using both the draw methods of

the Image class and the drawImage methods of the Graphics class.

5.4. General background information

Bitmaps and shapes

Many game programs communicate primarily with the player using interactive graphics.

Sometimes those graphics involve drawing bitmap images. Both the Slick2D Image class and the

Slick2D Graphics class provide methods for drawing bitmap images.

Sometimes game programs involve drawing shapes such as circles, rectangles, polygons, arcs, etc.

The Slick2D Graphics class and other classes such as the Slick2D Shape class provide methods

for creating and drawing such shapes and filling closed shapes with color.

And of course, some game programs involve a combination of the two.

This module concentrates on drawing bitmap images both honoring and not honoring transparent

pixels.

Common class names

The Slick2D library contains numerous classes, interfaces, and methods with names that match

the names in the Java standard edition library, such as Color , Graphics , Image , Line ,

Rectangle , Shape , Transform , TextField , etc.

You need to be aware, however, that even though the names are the same, and the behaviors may

be similar, these are not standard Java classes. Their behaviors will often be different from

standard Java classes. Therefore, ready access to the documentation at

http://slick.cokeandcode.com/javadoc/ while you are programming in Slick2D is very important even if you are a seasoned Java programmer.

Illustrate major differences

The program that I will present in this module will illustrate some of the major differences

between the two libraries insofar as graphics programming is concerned. For example, both

libraries have a class named Image , which has generally the same purpose in both libraries.

However, the Image class in the Slick2D library provides about ten different overloaded draw

methods that you can call to draw images in the game window.

The Image class in the Java standard library doesn't have any draw methods. Instead, it is

necessary to get a graphics context on the image and then call the drawImage method on that

context to draw the image.

Draw bitmap images two different ways

The Slick2D render method receives an incoming parameter of type Graphics , which also

provides a drawImage method that can be used to draw an image in the game window.

I will show you how to draw bitmap images using the draw methods of the Image class and also

show you how to draw bitmap images using the drawImage methods of the Graphics class.

5.5. Discussion and sample code

Beginning of the class named Slick0140a

The main method

The overridden init method

An empty update method

The overridden render method

Listing 5 provides a complete listing of a Slick2D program named Slick0140a . Before getting into the details of the code, however, I will show you the input and output images.

Input images

index-80_1.jpg

This program uses two input images. An image file named background.jpg is used to create a

background in the game window. Image 1 shows what that image looks like when viewed in the Windows Paint program.

Figure 5.1. Image 1. Background image in Windows Paint.

Image 1. Background image in Windows Paint.

The ladybug image

The second input image is a file named ladybug.png , which is a picture of a red and black

ladybug on a transparent black background. Image 2 shows this image when viewed in the Windows Paint program.

index-81_1.jpg

index-81_2.jpg

Figure 5.2. Image 2. Ladybug image in Windows Paint.

Image 2. Ladybug image in Windows Paint.

Image 3 shows the same ladybug image when viewed in the Windows Picture and Fax Viewer program. Note that the black background from Image 2 is transparent in Image 3 .

Figure 5.3. Image 3. Ladybug image in Windows Picture and Fax Viewer.

Image 3. Ladybug image in Windows Picture and Fax Viewer.

Image 4 shows the same ladybug image when viewed in the Gimp image editor program. This program provides even a different treatment for the transparent pixels.

index-82_1.jpg

index-82_2.jpg

Figure 5.4. Image 4. Ladybug image in Gimp.

Image 4. Ladybug image in Gimp.

The output image

Image 5 shows a screen shot of the game window while the program is running

Figure 5.5. Image 5. Output from program Slick0140a.

Image 5. Output from program Slick0140a.

Different drawing parameters

The same ladybug image is drawn three times in Image 5 with different drawing parameters.

The leftmost image of the ladybug in Image 5 is drawn with a scale factor of 0.75 and a drawing mode that honors transparency: MODE_NORMAL.

The center image of the ladybug in Image 5 is drawn using a different approach with a scale factor of 1.0 and a drawing mode that honors transparency: MODE_NORMAL.

The rightmost image of the ladybug in Image 4 is drawn using the same approach as the leftmost image, a scale factor of 1.25, and a drawing mode that does not honor transparency:

MODE_ALPHA_BLEND.

Are the mode names reversed?

As mentioned above, the two images of the ladybug with transparency were drawn using a

Slick2D constant named MODE_NORMAL .

The image of the ladybug on the right without transparency was drawn using a Slick2D constant

named MODE_ALPHA_BLEND .

These names seem to have been reversed. I would expect the constant with a name that includes

the words alpha and blend to honor transparency but that doesn't seem to be the case.

Beginning of the class named Slick0140a

Listing 1 shows the beginning of the class named Slick0140a including some instance variable declarations and the constructor.

public class Slick0140a extends BasicGame{

Image ladybug = null;

Image background = null;

float leftX = 100;//leftmost position of ladybug

float leftY = 100;

float middleX = 200;//middle position of ladybug

float middleY = 50;

float rightX = 300;//rightmost position of ladybug

float rightY = 100;

float leftScale = 0.75f;//drawing scale factors

float rightScale = 1.25f;

//----------------------------------------------------//

public Slick0140a(){//constructor

//Set the title

super("Slick0140a, baldwin");

}//end constructor

Figure 5.6. Listing 1. Beginning of the class named Slick0140a.

Listing 1. Beginning of the class named Slick0140a.

The instance variables shown in Listing 1 and the values that they contain will be used later to display the three ladybug images shown in Image 5 .

There is nothing new in the constructor in Listing 1 .

The main method

There is also nothing new in the main method in Listing 2 .

public static void main(String[] args)

throws SlickException{

AppGameContainer app = new AppGameContainer(

new Slick0140a(),414,307,false);

app.start();

}//end main

Figure 5.7. Listing 2. The main method.

Listing 2. The main method.

The overridden init method

The overridden init method is shown in Listing 3 . There is quite a bit of new material in Listing

3 .

public void init(GameContainer gc)

throws SlickException {

ladybug = new Image("ladybug.png");

background = new Image("background.jpg");

gc.setShowFPS(false);//disable FPS display

gc.setTargetFrameRate(60);//set frame rate

}//end init

Figure 5.8. Listing 3. The overridden init method.

Listing 3. The overridden init method.

Two new Image objects

Listing 3 begins by instantiating two new Slick2D Image objects from the image files discussed earlier and saving those object's references in two of the instance variables that were declared in

Listing 1 .

(Note that in this case, the image files were located in the same folder as the source code for the

program. Therefore, a path specification to the image files was not needed.)

I will remind you again that the Slick2D Image class is different from the Image class in the

standard edition Java library.

Don't display FPS

You may have noticed that the FPS display is missing from the upper-left corner of Image 5 .

That is because it was disabled by the call to the setShowFPS method in Listing 3 , passing false as a parameter to the method.

Set the target frame rate

The last statement in Listing 3 sets the target frame rate to 60 frames per second.

An empty update method

The update method in Listing 5 is empty so there is no point in showing it here.

The overridden render method

The overridden render method is shown in Listing 4 .

public void render(GameContainer gc, Graphics g)

throws SlickException{

//Note that the names of the drawMode constants seem

// to be backwards.

//Draw the background and two versions of the

// ladybug by calling a draw method of the Image

// class.

g.setDrawMode(g.MODE_NORMAL);//honors transparency

background.draw(0,0);

ladybug.draw(leftX,leftY,leftScale);

g.setDrawMode(g.MODE_ALPHA_BLEND);//no transparency

ladybug.draw(rightX,rightY,rightScale);

//Draw a third version of the ladybug by calling

// a drawImage method of the Graphics class.

g.setDrawMode(g.MODE_NORMAL);

g.drawImage(ladybug,middleX,middleY);

}//end render

Figure 5.9. Listing 4. The overridden render method.

Listing 4. The overridden render method.

Draw the background and the leftmost ladybug

Listing 4 begins by calling the setDrawMode method on the incoming Graphics parameter to set the drawing mode to MODE_NORMAL as described earlier. Then it calls one of the overloaded

draw methods of the background Image object and the ladybug Image object to draw the

background and the leftmost ladybug in Image 5 .

Note that the drawing coordinates and the scale factor are passed to the draw method.

Also note that this drawing of the ladybug image honors transparent pixels.

Draw the rightmost ladybug

After that, Listing 4 calls the setDrawMode method on the incoming Graphics parameter to set the drawing mode to MODE_ALPHA_BLEND and calls the same draw method of the ladybug

Image object to draw the rightmost ladybug in Image 5 .

Note that this drawing of the ladybug image does not honor transparent pixels.

Call the drawImage method of the Graphics class

Finally, Listing 4 calls the setDrawMode method on the incoming Graphics parameter to set the drawing mode back to MODE_NORMAL and then calls the drawImage method on the incoming

Graphics parameter to draw the middle ladybug in Image 5 . (This approach is similar to the approach that would be used to draw an image using the standard edition Java library.)

Note that the reference to the ladybug Image object and the drawing coordinates are passed as

parameters to the drawImage method. Some of the overloaded drawImage methods provide

scaling. However, there is no scale parameter for this version of the drawImage method so the

ladybug was drawn at actual size.

Many overloaded drawing methods

There are many overloaded versions of the draw and the drawImage methods.

That completes the discussion of the program named Slick0140a .

5.6. Run the program

I encourage you to copy the code from Listing 5 Compile the code and execute it, making changes, and observing the results of your changes. Make certain that you can explain why your

changes behave as they do.

5.7. Summary

You learned that while there are many classes, interfaces, and methods in the Slick2D library with

names that match classes, interfaces, and methods in the standard edition Java library, they are not

the same.

You learned that you can access the Slick2D documentation at

http://slick.cokeandcode.com/javadoc/ . (A copy of the documentation is also included in the distribution zip file.)

You learned how to set the drawing mode so that bitmap images drawn in the game window will

either honor or not honor transparent pixels.

You learned how to draw bitmap images in the game window using both the draw methods of the

Image class and the drawImage methods of the Graphics class.

5.8. What's next?

In the next module, you will learn how to make sprites move at a constant speed in front of an

image in the face of a widely varying frame rate. You will also learn about a rudimentary form of

collision detection.

5.9. Miscellaneous

This section contains a variety of miscellaneous information.

Housekeeping material

Module name: Slick0140: A first look at Slick2D bitmap graphics

File: Slick0140.htm

Published: 02/04/13

Disclaimers:

Financial : Although the Connexions site makes it possible for you to download a PDF file for

this module at no charge, and also makes it possible for you to purchase a pre-printed version

of the PDF file, you should be aware that some of the HTML elements in this module may not

translate well into PDF.

I also want you to know that, I receive no financial compensation from the Connexions

website even if you purchase the PDF version of the module.

In the past, unknown individuals have copied my modules from cnx.org, converted them to

Kindle books, and placed them for sale on Amazon.com showing me as the author. I neither

receive compensation for those sales nor do I know who does receive compensation. If you

purchase such a book, please be aware that it is a copy of a module that is freely available on

cnx.org and that it was made and published without my prior knowledge.

Affiliation :: I am a professor of Computer Information Technology at Austin Community

College in Austin, TX.

5.10. Complete program listing

Listing 5 contains a complete listing of the program named Slick0140a .

/*Slick0140a.java

Copyright 2012, R.G.Baldwin

Illustrates drawing a sprite image with transparent

parts on a background image using two different

approaches.

Tested using JDK 1.7 under WinXP

*********************************************************/

import org.newdawn.slick.AppGameContainer;

import org.newdawn.slick.BasicGame;

import org.newdawn.slick.GameContainer;

import org.newdawn.slick.Graphics;

import org.newdawn.slick.Image;

import org.newdawn.slick.SlickException;

public class Slick0140a extends BasicGame{

Image ladybug = null;

Image background = null;

float leftX = 100;//leftmost position of ladybug

float leftY = 100;

float middleX = 200;//middle position of ladybug

float middleY = 50;

float rightX = 300;//rightmost position of ladybug

float rightY = 100;

float leftScale = 0.75f;//drawing scale factors

float rightScale = 1.25f;

//----------------------------------------------------//

public Slick0140a(){//constructor

//Set the title

super("Slick0140a, baldwin");

}//end constructor

//----------------------------------------------------//

public static void main(String[] args)

throws SlickException{

AppGameContainer app = new AppGameContainer(

new Slick0140a(),414,307,false);

app.start();

}//end main

//----------------------------------------------------//

@Override

public void init(GameContainer gc)

throws SlickException {

ladybug = new Image("ladybug.png");

background = new Image("background.jpg");

gc.setShowFPS(false);//disable FPS display

gc.setTargetFrameRate(60);//set frame rate

}//end init

//----------------------------------------------------//

@Override

public void update(GameContainer gc, int delta)

throws SlickException{

//No updates required in this program.

}//end update

//----------------------------------------------------//

public void render(GameContainer gc, Graphics g)

throws SlickException{

//Note that the names of the drawMode constants seem

// to be backwards.

//Draw the background and two versions of the

// ladybug by calling a draw method of the Image

// class.

g.setDrawMode(g.MODE_NORMAL);//honors transparency