Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
114 views

Midp Game Api: Khanh Le

Uploaded by

huyhoang0020
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
114 views

Midp Game Api: Khanh Le

Uploaded by

huyhoang0020
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 39

Khanh Le

MIDP Game API


Introduction
 Game applications have proven to be one of the most popular uses for Java
2 Micro Edition, so a dedicated Game API is provided in Mobile Information
Device Profile version 2.0 to facilitate game development.
 This API provides several benefits to the game developer.
 First, it simplifies game development and provides an environment that is more
familiar to game developers.
 Second, it reduces application size and complexity by performing operations that
would otherwise be implemented by the application.
 Third, because the API can be implemented using native code, it can also
improve performance of the frequently used game routines.
 As with the low-level user interface APIs, applications that use the Game
API must be written carefully in order to ensure portability. Device
characteristics such as screen size, color depth, and key availability must be
accounted for by the developer if application portability is desired.
The GameCanvas API
 The Canvas class was designed for applications that are
event-driven; that is, the user interface is updated in
response to a user input, such as selecting an option or
pressing a soft key.
 However, game applications are generally time-driven
and continue to run and update the display whether or
not the user provides input.
 To overcome this difference, the GameCanvas class
provides a game-centric model for accessing the display
and checking for key inputs
The GameCanvas API
 Game applications typically employ a
single thread to run the game. This thread
executes a main loop that repeatedly
checks for user input, implements logic to
update the state of the game, and then
updates the user interface to reflect the
new state. Unlike Canvas, the
GameCanvas class provides methods that
directly support this programming model.
Key Polling
 The GameCanvas class also provides the ability to poll the status of
the keys instead of having to implement callback methods to
process each key event.
 Key polling allows all of the application's key handling logic to be
coded together and executed at the appropriate point in the game
loop. It also enables simultaneous key presses to be detected on
devices that support them.
 The getKeyStates method returns the key state in the form of an
integer value in which each bit indicates whether a specific key is
pressed or has been pressed since the last invocation of the
getKeyStates method.
 This latching behavior allows very quick key presses to be detected
even if the game loop is running fairly slowly. If the current state of
the keys is desired without the latching behavior, the getKeyStates
method can be called twice.
Key Polling
 To determine whether or not a specific key is pressed,
the integer value is AND-ed with one of the key polling
constants defined in GameCanvas, as shown in the
following example:
int keyStates = getKeyStates();
if ((keyStates & UP_PRESSED) != 0) yPosition--;
if ((keyStates & DOWN_PRESSED) != 0) yPosition++;
if ((keyStates & FIRE_PRESSED) != 0) fireRocket();
Screen Buffer
 Unlike Canvas (which shares screen resources with other
applications), each GameCanvas object has its own dedicated
screen buffer, which the developer can draw on at any time
using a Graphics object. Graphics objects are obtained by
calling method getGraphics. Multiple Graphics objects can be
created if desired.
 Changes to the screen buffer contents are limited to rendering
calls made by the application, so the buffer can be updated
incrementally instead of being completely rendered for each
frame.
 Synchronous methods are provided for flushing the contents of
the buffer to the physical display, so continuous animations are
much easier to implement than with the asynchronous
repainting model of the Canvas class. The flushGraphics
methods flush the contents of the buffer to the physical display,
either for the entire buffer or for a specific region of the buffer.
These methods do nothing if the GameCanvas is not currently
shown.
Layers
 The Layer class is an abstract class that represents a basic visual entity that
can be rendered on the screen. A Layer has defined rectangular bounds,
and it can be either visible or invisible. A Layer can be rendered using any
Graphics object by calling its paint method.
 The game API defines two Layer subclasses: Sprite and TiledLayer.
Unfortunately, class Layer cannot be directly subclassed by the developers,
since this would compromise the ability to improve performance through the
use of native code in the implementation of the Game API.
 Subclasses of class Layer can be drawn at any time using the paint method.
The Layer will be drawn on the Graphics object according to the current
state information maintained by the Layer object (that is, position, visibility,
and so forth.) The Layer object is drawn at its current position relative to the
current origin of the Graphics object. Erasing the Layer is always the
responsibility of the code outside the Layer class.
Sprites
 A Sprite is a basic visual element whose
appearance is provided by one of several frames
stored in an Image. The developer can control
which frame is used to render the Sprite, thereby
enabling animation effects. Several transforms
such as flipping and rotation can also be applied
to a Sprite to further vary its appearance. As with
all Layer subclasses, a Sprite's location can be
changed, and it can also be made visible or
invisible.
Frames
 The raw frames used to render a Sprite are
provided in a single Image object, which may
be mutable or immutable. If more than one
frame is used, they are packed into the Image
as a series of equally-sized frames. The frames
are defined when the Sprite is instantiated;
they can also be updated by calling the
setImage method.
 The same set of frames may be stored in
several different arrangements depending on
what is most convenient for the game
developer. The implementation automatically
determines how the frames are arranged
based on the dimensions of the frames and
those of the Image. The width of the Image
must be an integer multiple of the frame width,
and the height of the Image must be an integer
multiple of the frame height.
Frames
 The Image is divided into frames whose
dimensions are dictated by the
frameWidth and frameHeight
parameters in the Sprite's constructor.
Each frame within the Image is
assigned a unique index number; the
frame located in the upper-left corner of
the Image is assigned an index of 0.
The remaining frames are then
numbered consecutively in row-major
order (indices are assigned across the
first row, then the second row, and so
on.) The getRawFrameCount method
returns the total number of raw frames.
 In following example, a Sprite is created
by dividing an Image into 8 frames that
are 16 pixels wide and 23 pixels high:
Image carFrames =
Image.createImage("/carframes.png");
Sprite car = new Sprite(carFrames, 16,
23);
Frame Sequence
 The frame sequence of a Sprite defines an ordered list of frames to be
displayed. The default frame sequence mirrors the list of available frames,
so there is a direct mapping between the sequence index and the
corresponding frame index. This also means that the length of the default
frame sequence is equal to the number of raw frames. For example, if a
Sprite has 4 frames, its default frame sequence is {0, 1, 2, 3}.
 The developer must explicitly switch the current frame in the frame
sequence. This may be accomplished by calling the Sprite.setFrame,
Sprite.prevFrame, or Sprite.nextFrame methods. The method
Sprite.setFrame sets the current index in the sequence array. The method
Sprite.prevFrame decrements the current index, wrapping around to the last
sequence element if necessary. The method Sprite.nextFrame increments
the current index, wrapping around to the first sequence element if
necessary. Note that these methods always operate on the sequence index,
not frame indices, although the sequence indices and the frame indices are
interchangeable if the default frame sequence is used.
Frame Sequence
 If desired, an arbitrary frame sequence may be defined for a Sprite. The frame
sequence is defined using an array of integers whereby each element references
a valid frame index. The array must contain at least one element, and each
element must contain a valid frame index. The setFrameSequence method is
used to set the frame sequence; passing this method null as the frame sequence
restores the default frame sequence.
 By defining a new frame sequence, the developer can conveniently display the
Sprite's frames in any order desired; frames may be repeated, omitted, shown in
reverse order, and so forth. This example shows a special frame sequence that is
used when the car explodes. Note that certain frames are repeated so that they
are shown for a longer period of time.
int[] explosionSequence = {1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7};
car.setFrameSequence(explosionSequence);
Reference Pixel
 As a subclass of Layer, class Sprite inherits various methods for
setting and retrieving object location such as the methods
setPosition(x,y), getX(), and getY(). These methods all define
position in terms of the upper-left corner of the Sprite's visual
bounds; however, in some cases, it is more convenient to define the
Sprite's position in terms of an arbitrary pixel within its frame,
especially if transforms are applied to the Sprite.
 Therefore, Sprite includes the concept of a reference pixel. The
reference pixel is defined by specifying its location in the Sprite's
untransformed frame using the defineReferencePixel method. By
default, the reference pixel is defined to be the pixel at (0,0) in the
frame. If desired, the reference pixel may be defined outside of the
frame's bounds.
Reference Pixel
 As shown in this picture, the reference pixel
can be thought of as having a pushpin in its
center. In this example, we define the
reference pixel to be a pixel in the center of
the car's front axle:
car.defineReferencePixel(8, 5);
 Once defined, this pushpin may be used to
set and query the location of the Sprite. The
getRefPixelX and getRefPixelY methods
can be used to query the location of the
pushpin in the painter's coordinate system.
The setRefPixelPosition method can be
used to position the Sprite by specifying
where the pushpin should be located in the
painter's coordinate system.
Transforms
 Various transforms can be applied to a
Sprite. The available transforms include
rotations in multiples of 90 degrees combined
with mirroring about the vertical axis. The
transforms are identical to those provided for
Image rendering. A Sprite's transform is set
by calling its setTransform method.
 When a transform is applied, the Sprite is
automatically positioned so that its reference
pixel appears stationary in the painter's
coordinate system. Thus, the reference
pixel's pushpin effectively becomes the
center of the transform operation. Since the
reference pixel does not move, the values
returned by getRefPixelX and getRefPixelY
remain the same; however, the values
returned by getX and getY may change to
reflect the movement of the Sprite's upper left
corner.
 For the car example shown in previous
picture, the reference pixel is located closer
to the front, which makes the rear of the car
appear to slide as it is rotated by 90 degrees.
TiledLayer
 A TiledLayer is a Layer that is composed of a
grid of cells that can be filled with a set of tile
images. This technique is commonly used in 2D
gaming platforms to create very large scrolling
backgrounds without the need for an extremely
large Image. The use of animated tiles allows
numerous cells of a TiledLayer to be animated
quickly and easily
Tiles
 As with a Sprite's frames, the tiles used to fill the TiledLayer's cells are
provided in a single Image object which may be mutable or immutable.
The Image is broken up into a series of equal-sized tiles whose
dimensions are specified along with the Image.
 Each tile is assigned a unique index number. The tile located in the
upper-left corner of the Image is assigned an index of 1 (unlike Sprite
where the first frame is given an index of 0). The remaining tiles are
then numbered consecutively in row-major order (indices are assigned
across the first row, then the second row, and so on).
 These tiles are regarded as static
tiles because there is a fixed link
between the tile and the image
data associated with it. The static
tile set is created when the TiledLayer
is instantiated; it can also be updated
at any time using
the setStaticTileSet method.
Tiles
 In addition to the static tile set, the developer can also define
several animated tiles. An animated tile's appearance is provided by
the static tile to which it is linked. This link can be updated
dynamically, thereby allowing the developer to change the
appearance of several cells without having to update the contents of
each cell individually. This technique is very useful for animating
large repeating areas without having to explicitly change the
contents of numerous cells.
 Animated tiles are created using the createAnimatedTile method,
which returns the index to be used for the new animated tile. The
animated tile indices are always negative and consecutive,
beginning with –1. The associated static tile that provides the
animated tile's appearance is specified when the animated tile is
created, and can also be dynamically updated using the
setAnimatedTile method.
Cells
 The TiledLayer's grid is made up of equal-sized cells; the number of
rows and columns in the grid are specified in the constructor, and
the physical size of the cells is defined by the size of the tiles. The
contents of each cell is specified by the means of a tile index; a
positive tile index refers to a static tile, and a negative tile index
refers to an animated tile. A tile index of 0 indicates that the cell is
empty, meaning that the cell is fully transparent and nothing is
drawn in that area when the TiledLayer is rendered. By default, all
cells contain tile index 0.
 The contents of cells may be changed individually using the method
setCell and as rectangular groups of cells using the method fillCells.
Several cells may contain the same tile; however, a single cell
cannot contain more than one tile.
Cells
 The following example illustrates how a simple
background can be created using a TiledLayer. The
setCell and fillCells methods are used to set the contents
of the cells as shown in the picture. By default, the
contents of the cells is 0, which makes them transparent.
tiles.fillCells(0, 0, 8, 1, 1);
tiles.fillCells(0, 0, 1, 6, 1);
tiles.setCell(2, 2, -1);
tiles.setCell(7, 3, -1);
tiles.setCell(3, 5, -1);
Cells
 With the cell contents
set, the appearance of
the TiledLayer would be
as shown in following
picture. Note that since
static tile 2 is linked to
animated tile –1, it
appears in each of the
cells that contain –1.
Cells
 To animate the coin, a different
static tile is linked to the
animated tile using the
setAnimatedTile method. In
this example, the animated tile
–1 is linked to static tile 5
instead of static tile 2, and the
resulting appearance is shown
in this picture.
myTileLayer.setAnimatedTile(-
1, 5);
LayerManager
 The LayerManager manages a series of Layers and simplifies the
rendering process by automatically drawing the correct regions of
each Layer in the appropriate order.
 The LayerManager maintains an ordered list to which Layers can be
appended, inserted, and removed. A Layer's index correlates to its
z-order; the layer at index 0 is closest to the user while the Layer
with the highest index is furthest away from the user. The indices
are always contiguous; that is, if a Layer is removed, the indices of
subsequent Layers will be adjusted to maintain continuity.
 The LayerManager class provides several features that control how
the game's Layers are rendered on the screen. The size of the view
window controls how large the user's view will be, and is usually
fixed at a size that is appropriate for the device's screen.
LayerManager

 The position of the view window can also be adjusted relative to


the LayerManager's coordinate system. Changing the position of
the view window enables effects such as scrolling or panning the
user's view. For example, to scroll to the right, simply move the
view window's location to the right.
 In the example shown
in this picture, the view
window is set to a
region that is 120 pixels
wide, 120 pixels high,
and located at (102, 40)
in the LayerManager's
coordinate system.
layerMgr.setViewWindow(102, 40, 120, 120);
LayerManager
 The paint method of LayerManager
class includes an (x,y) location that
controls where the contents of the view
window are rendered relative to the
screen. Changing these parameters
does not ch ange the contents of the
view window; it simply changes the
location where the view window is
drawn on the screen. Note that this
location is relative to the origin of the
Graphics object, and thus it is subject
to the translation attributes of the
Graphics object.
 For example, if a game uses the top of
the screen to display the current score,
the view window may be rendered at
(0, 12) to provide space for the score.
layerMgr.paint(g, 0, 12);
Collision Detection
 Collision detection is a key feature of the Game
API, enabling the developers to quickly and
easily determine whether two elements of a
game have collided or not.
 The collision detection methods are provided in
the Sprite class, and they allow the developer to
detect a collision between a Sprite and either a
TiledLayer, an Image, or another Sprite.
Collision Rectangle
 Sprites have a defined collision rectangle that indicates the region to be included for
collision detection. By default, this region corresponds to the overall bounds of the
Sprite. However, it can be redefined to cover any rectangular region as needed.
 A special collision rectangle allows areas of a Sprite to be excluded from the collision
detection process. For example, a jet fighter Sprite may include a vapor trail coming
from the engines; however, a missile colliding with this part of the Sprite should not
be considered as hitting the aircraft. By defining a collision rectangle that includes
only aircraft and excludes the vapor trail, selective collision detection can be easily
achieved
 The collision rectangle is automatically updated to reflect any transforms that are
applied to the Sprite. Therefore, there is no need to modify the collision rectangle
when a transform operation is performed.
Pixel-Level Detection
 The collision detection methods allow the developer to specify boundary-level or
pixel-level detection. Boundary-level detection checks if the collision rectangles of the
two elements are intersecting or not, and it is the simplest and fastest detection
scheme. However, many elements are likely to be non rectangular in nature, so
boundary-level detection may not be sufficient.
 To overcome this problem, the developer may request pixel-level detection. Used in
conjunction with transparent image data, this detection scheme checks whether an
opaque pixel in the first element is touching an opaque pixel in the second element.
Thus, the transparent area around the opaque area is excluded from the detection
process, and a collision is detected only when the opaque areas appear to be
touching. Any transforms applied to a Sprite are automatically accounted for when
checking for collisions.
 Pixel-level detection is performed only within the collision rectangles of the two
elements. Thus, touching opaque pixels will not result in a collision if either one is
outside of the element's collision rectangle.
 For platforms that support alpha channel blending, any alpha value less than fully
opaque is considered to be transparent for the purposes of collision detection
Pixel-Level Detection
 These two pictures illustrate the differences between pixel-level and boundary-level
collision detection. The gray area around Duke represents transparent pixels.
Boundary-level detection indicates a collision whenever the boundaries of the two
images are touching; pixel-level detection indicates a collision only when opaque
pixels are touching.

false
Sample Code: A Simple
Game
 This example illustrates how the APIs discussed in this chapter can be
used to form a simple game. The user controls a car that is always
moving forward at a constant speed and can be turned 90 degrees
clockwise or counterclockwise. The object of the game is to drive
around the track and collect as many coins as possible without hitting
any of the walls.
 The car is implemented using a Sprite that can be rotated in 90-
degree increments using the appropriate transform. Special frame
sequences are used to show just the first frame or to animate through
the explosion frames.
 The track and the coins are implemented using TiledLayers. Most of
the cells in the tiled layers are left empty so that the dark gray
background is seen. A static tile is used to form the walls of the track,
and an animated tile is used to display the spinning coins.
 Two separate TiledLayers are used to simplify the collision detection
code. Collision detection provides a simple way to determine whether
the car has collided with a non-empty cell in either of the TiledLayers.
If the collision was with the coins, some simple code determines which
cells containing the coins can be removed and the score can be
accurately updated.
Sample Code: A Simple
Game
 Note that this code example is
simplified to demonstrate the
use of the game API; a real
application would require
additional code to
appropriately handle
application starting and
pausing, game restarts,
displaying the score, multiple
levels, and so on.
 See SimpleGame project
Mobile Game Development Process

 There seems to be no one simple solution


to developing a game
 Because the games for mobile devices are
often very simple, the development
process is much like that of the early days
of gaming.
 The average major console or PC title can
have a development time of 18 to 36
months. With a mobile game, it is often
reduced to 1 to 3 months.
Design
 Ideas come from anywhere. The real value in a
design is the implementation.
 Whether your game is fun or not is up for the
players to decide.
 Catering to the Platform

Creating a design for a mobile game is totally unique

The first thing to take into account is length of play.
Because of the nature of the device, chances are the
idle time a player has with her phone is brief.
 You can have a game with long-term goals. However,
the game must still be able to be successfully played
in short bursts and be interrupted at any time. Allow
the user to pause and resume the game at any time
with little or no effect on the game's progress.
Design
 Catering to Your Audience
 The audience for mobile games is not necessarily the
same as that of console or PC games. People do not
buy phones to play games.
 Duplicating what is successful on consoles and PCs
does not necessarily equate to a successful mobile
game.
 Once this market matures, we will be able to see a
pattern in mobile gaming tastes.

It is entirely up to you. Ultimately, the players will
determine if they like it or not.
Development
 The term "game development" encompasses a lot more
than just programming.
 Design and programming are just two of the overall
elements involved in creating a completed game, with
mobile gaming that is about 99% of it.
 But in traditional game development there are
management concerns, work flow, tool creation, and a
host of other issues
 Asset Creation

In the game industry, an asset is defined as any element of the
game that is plugged into the engine for the creation of content

Usually you will hear people refer to "sound assets" or "art
assets”. The creation of these assets involves many different
tools.
Development
 Source Control

A source control system manages changes coming
from different developers to the same code. Often this
means only one programmer can modify a section of
code at a time, and the source control application
makes sure this is so.
 Although primarily a tool used when multiple software
engineers are working on a project, source control
can also serve some use for single developers as
well. This is because most source control applications
keep a log of all changes in each source file over the
course of the entire project.
 The very same source control software can also be
used to manage asset creation.
Development
 Testing

Once you have your game up and running, you have to make
sure it is bug-free.
 In the PC realm, this decision is much easier as patching the
game after release is commonplace. Mobile games are more like
consoles in that patching is really not an option.
 Although you as the programmer can test the game yourself.
Third-party testers can be anyone from a software quality
assurance firm to your little brother. An impartial third party
playing your game may try to use it in ways you never thought
of. This process may reveal bugs you have unnoticed.
 With most carriers, your applet must go through a stringent
testing process before being accepted for sale.
Summary
 The Game API is an entirely new feature in
MIDP 2.0. With the Game API, application
developers can simplify the development of
game applications by using a programming
paradigm that is well suited to game
applications. Since the Game API provides
many operations that would otherwise be
implemented by the application, the API can
significantly reduce the size and complexity of
game applications.

You might also like