Sunteți pe pagina 1din 9

IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation

_____________________________________________________________________________________________________

Chapter 11 – J2ME Mobile Game Animation


_______________________________________________________________

1. Topics

• Loading Images with Associated Text Captions


• Sprite Animation
• Depth with Z-Order
• Collision Detection
• Layer Class and Sprite Class
• GameCanvas Class

2. Loading Images with Associated Text Captions

J2ME Mobile SlideShow

The J2ME Slideshow MIDlet program isn't


exactly a game, but it is starting to demonstrate
basic game programming tasks such as
combining images and text and altering them in
response to user input. The user can flip through
the "slides" by using the left and right arrow
keys on a mobile phone.

The majority of the code appears in the


SSCanvas class, which is derived from Canvas
and serves as the canvas for displaying a slide.

The real work in the SSCanvas class takes place in the paint () method, which draws
the current slide image and caption on the display.

import javax.microedition.lcdui.*;
import java.io.*;

public class SSCanvas extends Canvas {


private Display display;
private Image[] slides;
private String[] captions = { "2008 Olympic - Circle Bowl", "2008 Olympic - Wide Spine",
"2008 Olympic - Over-vert Works", "2008 Olympic - Beijing Sac Bowl",
"2008 Olympic - Northern Sport's Ledge" };
private int curSlide = 0;

public SSCanvas(Display d) {
super();
display = d;

// Load the slide images


try {
slides = new Image[5];

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 1
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

slides[0] = Image.createImage("/LoveCircle.jpg");
slides[1] = Image.createImage("/DoubleWide.jpg");
slides[2] = Image.createImage("/FlumeZoom.jpg");
slides[3] = Image.createImage("/KulpDeSac.jpg");
slides[4] = Image.createImage("/LouiesLedge.jpg");
}
catch (IOException e) {
System.err.println("Failed loading images!");
}
}

void start() {
display.setCurrent(this);
repaint();
}

public void keyPressed(int keyCode) {


// Get the game action from the key code
int action = getGameAction(keyCode);

// Process the left and right buttons


switch (action) {
case LEFT:
if (--curSlide < 0)
curSlide = slides.length - 1;
repaint();
break;

case RIGHT:
if (++curSlide >= slides.length)
curSlide = 0;
repaint();
break;
}
}

public void paint(Graphics g) {


// Clear the display
g.setColor(255, 255, 255); // White
g.fillRect(0, 0, getWidth(), getHeight());

// Draw the current image


g.drawImage(slides[curSlide], getWidth() / 2, getHeight() / 2,
Graphics.HCENTER | Graphics.VCENTER);

// Set the font for the caption


Font f = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
g.setFont(f);

// Draw the current caption


g.setColor(0, 0, 0); // Black
g.drawString(captions[curSlide], getWidth() / 2, 0,
Graphics.HCENTER | Graphics.TOP);
}
}

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 2
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

MIDlet Program (SlideshowMIDlet.java)

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class SlideshowMIDlet extends MIDlet implements CommandListener {


private SSCanvas canvas;

public void startApp() {


if (canvas == null) {
canvas = new SSCanvas(Display.getDisplay(this));
Command exitCommand = new Command("Exit", Command.EXIT, 0);
canvas.addCommand(exitCommand);
canvas.setCommandListener(this);
}

// Start up the canvas


canvas.start();
}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command c, Displayable s) {


if (c.getCommandType() == Command.EXIT) {
destroyApp(true);
notifyDestroyed();
}
}
}

3. Sprite Animation

In the case of television, the illusion of movement is created when a rapid succes-
sion of images is displayed with slight changes in their appearance. More
specifically, the human eye can be tricked into perceiving animated movement
with as low as 12 frames of movement per second (12fps). Most professional
animations use a higher frame rate. Television, for example, uses 30fps. When
you go to the movies, you see motion pictures at about 24fps. It's pretty apparent
that these frame rates are more than enough to captivate your attention and
successfully create the illusion of movement. The fact that film and television
frame rates are different means that films have to be converted to be shown on
television.

The heart of graphics in almost all computer games is animation. When


programming animation in mobile games, you typically can manipulate the frame
rate a reasonable amount. When determining the frame rate for a game, you
usually have some give and take in establishing a low enough frame rate to yield
a smooth animation, while not bogging down the processor and overloading the
system. But don't worry too much about this right now.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 3
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

The classic approach to handling traditional animation is to draw a background


image separately from the animated objects that will be moving in the foreground.
The animated objects are then drawn on clear celluloid sheets so that they can be
overlaid on the background and moved independently. This type of animation is
referred to as cel animation. The technique of overlaying objects with
transparency is a fundamental form of computer game animation

3.1 2D Versus 3D Animation

2D animation involves objects moving or being manipulated within two


dimensions. Objects in a 2D animation can still have a 3D look to them-they just
can't physically move in three dimensions. Many 2D animation techniques
simulate 3D animation by altering the look of objects to simulate depth, but they
aren't truly 3D. As an example, an animation of a car driving off into the distance
would involve the car getting smaller as it gets farther away. However, this isn't
necessarily a 3D animation because you can achieve the 3D effect by making the
car image get smaller as it moves away. Although the end result is three-
dimensional, the car is very much a 2D object.

Unlike 2D animation, 3D animation involves placing and manipulating objects in


a three-dimensional virtual world. A 3D object is defined by a model rather than
an image because an image is inherently two-dimensional. A 3D model specifies
the shape of an object by a series of points, or vertices, in 3D space. In other
words, a 3D model is a mathematical representation of a physical object. For this
reason, 3D graphics and animation can get extremely complicated because they
often rely on heavy-duty mathematical processing.

The good news is that you can still do some pretty powerful things with 2D
animation.

3.2 2D Sprite Animation

For the purposes of implementing animation in mobile games, Animation has


broken down into two basic types: frame-based and cast-based animation. Technically
speaking, there is also a third animation type known as palette animation, which
involves animating the colors in a graphic object, but you can think of it as more
of a graphics effect rather than a fundamental type of animation.

3.3 Frame-Based Animation

Frame-based animation has no concept of a graphical object distinguishable from


the background; everything appearing in a frame is part of that frame as a Whole.
The result is that each frame image contains all the information necessary for that
frame in a static form. In frame-based animation, the entire frame changes to achieve
the effect of animation. This type of animation is of limited use in games because
games typically require the ability to move objects around independently of the
background.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 4
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

3.4 Cast-Based Animation

Cast-based animation involves graphical objects that move independently of a


background. The term "cast-based animation" comes from the fact that sprites can be
thought of as cast members moving around on a stage.

Each graphical object in a cast-based animation is referred to as a sprite, and has a


position that can vary over time. In other words, a sprite can have a velocity
associated with it that determines how its position changes over time. The
weatherperson is acting exactly like a sprite! The news station uses a technique
known as blue-screening or green-screening, which enables them to overlay the
weatherperson on top of the weather map in real time.

The weatherperson example brings up a very important point regarding sprites:


Transparency. We define a certain color in an image as unused, or transparent. When
drawing routines encounter pixels of this color, they simply skip them, leaving the
original background showing through. Transparent colors in images act exactly like
the weatherperson's colored screen in the earlier example.

4. Depth with Z-Order

Z-order is the relative depth of sprites on the screen. If a plane sprite happens to fly
over a tank sprite, you obviously want the plane to appear above the tank and,
therefore, hide the tank as it passes over. You handle this problem by assigning each
sprite a screen depth, which is also referred to as Z-order. The depth of sprites is called
Z-order because it works sort of like another dimension-like a z axis.

You can think of sprites moving around on the screen in the XY axis. Similarly, the z
axis can be thought of as another axis projected into the screen that determines how
the sprites overlap each other. To put it another way, Z-order determines a sprite's
depth within the screen. Because they make use of a z axis, you might think that Z-
ordered sprites are 3D. The truth is that Z-ordered sprites can't be considered 3D
because the z axis is a hypothetical axis only used to determine how sprite objects
hide each other.

The easiest way to control Z-order in a game is to pay close attention to the order in
which you draw the game graphics. Fortunately, the MIDP API provides a class
called LayerManager that simplifies the task of managing multiple graphics
objects (layers) and their respective Z-orders.

Cel animation is an early version of sprite animation. Each cel sheet corresponds
to a unique Z-order value, determined by where in the pile of sheets the sheet is
located. If a sprite near the top of the pile happens to be in the same location on
the cel sheet as any lower sprites, it conceals them. The location of each sprite in
the stack of cel sheets is its Z-order, which determines its visibility precedence.
The same thing applies to sprites in cast-based animations, except that the Z-order
is determined by the order in which the sprites are drawn, rather than the cel sheet
location.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 5
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

5. Collision Detection between Objects

Collision detection is used to determine when sprites physically interact with each
other.

There are many approaches to handling collision detection. The simplest


approach is to compare the bounding rectangles of each sprite with the bounding
rectangles of all the other sprites. This method is efficient, but if you have objects
that are not rectangular, a certain degree of error occurs when the objects brush
by each other.

Collision detection using rectangle collision as below simply involves checking to see
whether the bounding rectangles of two objects overlap.

Collision detection using shrunken rectangle collision as below involves checking to


see whether shrunken versions of the bounding rectangles of two objects overlap.

Collision detection that uses image data collision as below involves checking the
specific pixels of the images for two objects to see whether they overlap.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 6
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

Unfortunately, the last technique requires more processing overhead than


rectangle collision detection and can be a bottleneck in game performance. You'll
find that shrunken rectangle collision detection is sufficient in a lot of games.

6. Layer Class and Sprite Class

The Layer class models a general graphical object known as a layer, which serves as
the foundation for sprites and other graphical game objects. You can think of any
discrete visual element in a game as being a distinct layer. From a programming
perspective, the Layer class keeps track of information such as the position, width,
height, and visibility of a visual element.

** It's important to note that the Layer class is an abstract class, which means you can
never directly create an instance of a Layer object. Following are the methods
defined in the Layer class, all of which are important when it comes to working with
layers and sprites:

ƒ getX ( ) -Gets the X position of the layer's upper-left corner


ƒ getY ( )-Gets the Y position of the layer's upper-left corner
ƒ getWidth( )-Gets the layer's width
ƒ getHeight ( ) -Gets the layer's height
ƒ setPosition ()-Sets the XY position of the layer's upper-left corner
ƒ move ( ) -Moves the layer by a specified XY amount
ƒ isVisible ()-Gets the layer's visibility
ƒ setVisible ()-Sets the layer's visibility
ƒ paint ()-Overridden in derived layer subclasses

** The Sprite class builds on the Layer class by providing additional


functionality required of animated two-dimensional graphical objects.

The primary functional additions in the Sprite class are as follows:


ƒ Sprites are based on images, and support multiple frame images.
ƒ The image(s) for a sprite can be transformed (rotated, mirrored, and so on).
ƒ You can define a reference pixel, which serves as the basis for sprite transformations
and positioning.
ƒ For sprites with multiple frame images, the sequence in which the images are
displayed can be set precisely.
ƒ Collisions can be detected between sprites through the use of rectangle, shrunken
rectangle, or image data collision detection.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 7
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

To create a sprite based on a single image, just pass a newly created Image object
into the Sprite constructor, like this:

Sprite monsterSprite = new Sprite(Image.createlmage("/Monster.png");

This exception can be thrown by the createlmage() method in response to a


failure loading an image. Here's how to package the code in a try-catch clause to get it
running smoothly:

try{
monsterSprite = new Sprite(Image.createlmage("/Monster.png");
monsterSprite.setPosition(0, 0);
}
catch (IOException e) {
System.err.println("Failed loading image!");
}

1. Following is an example of using the setPosition() method to center a


sprite on the screen:

monsterSprite.setPosition((getWidth() - monsterSprite.getWidth() )/2,


(getHeight() - monsterSprite.getHeight() )/2);

This code uses the canvas width and height in conjunction with the sprite's width and
height to center the sprite on the screen.

2. Moving a sprite works a little differently in that you simply provide the amount
you'd like to move the sprite in each direction:

monsterSprite.move(-5,10);

In this example, the sprite is moved 5 pixels to the left and 10 pixels down. Negative
offset values indicate left (x-axis) or up (y-axis) directions, whereas positive values
indicate right (x-axis) or down (y-axis).

3. Because every Sprite object has an image associated with it, a paint()
method is provided that paints the sprite at its current position. All you have to do is
pass the paint() method a Graphics object, like this:

monsterSprite.paint(g);

This code assumes that you have a Graphics object named g, but you always have
a Graphics object handy in game painting code.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 8
IVE(TY) Mobile Computing Chapter 11 – J2ME Game Animation
_____________________________________________________________________________________________________

7. Smooth Animation with GameCanvas Class

If you were to use everything you've learned thus far to build an animated MIDlet
using the regular MIDP Canvas class, you would find that the resulting animation has
an annoying flicker. This flicker occurs because the game screen is cleared before the
animated graphics are painted. In other words, animated graphics objects are erased
and repainted each time they are moved. Because the erase and repaint process takes
place directly on the game screen, the animation appears to flicker.

You can solve the flicker problem associated with sprite animation by using a
technique known as double buffering. In double buffering, you perform all your
erasing and drawing on an offscreen drawing surface that isn't visible to the user.
After all the drawing is finished, the end result is painted straight to the game screen
in one pass. Because no visible erasing is taking place, the end result is flicker-free
animation.

Figure below reveals how an offscreen memory buffer is used to perform all the
incremental animation drawing, with only the finished image being drawn to the
game screen.

In addition to the standard Canvas class, the


MIDP API offers the GameCanvas class,
which supports double-buffered graphics. To
take advantage of this feature in the
GameCanvas class, you simply derive your
game-specific canvas from the
GameCanvas class and paint the graphics
just as you would in a normal MIDlet.
However, all the painting you perform is
actually being done to an offscreen buffer.

To commit the offscreen painting to the


actual screen, you must call the
flushGraphics() method.

When you first create a GameCanvas object,


the offscreen buffer is initially filled with all
white pixels.

The GameCanvas class includes a few other interesting features that come in handy
for mobile games, such as efficient key input processing.

__________________________________________________________________________________
File: MCOMP:\CHAP11.DOC Page: 9

S-ar putea să vă placă și