1. Trang chủ
  2. » Công Nghệ Thông Tin

Creating Mobile Games Using Java phần 10 pot

35 180 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Adding A Professional Look And Feel
Tác giả Carol Hamer
Trường học Standard University
Chuyên ngành Mobile Game Development
Thể loại Luận văn
Năm xuất bản 2023
Thành phố Hanoi
Định dạng
Số trang 35
Dung lượng 654,04 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The menu item sprite images are words written on a transparent background so the game screen is visible between and around the letters and the letters appear in black or blue depending o

Trang 1

Figure 10-5. The image that gives the three frames of the sparkling animation as horizontal strips

If you want an animated menu without drawing the entire thing from scratch, it is possible

to add animated CustomItems to an lcdui Form However, in that case you have to implement

the CustomItem yourself, so it’s really no easier than painting the whole menu as in the Dungeon

example Another possibility in MIDP 3 is to associate an animated image with each item in

a list But again the platform decides how to display the list and will insist on displaying the

corresponding strings in one of the platform’s fonts and without giving you the option of

plac-ing a background image behind it So the built-in lcdui widgets simply don’t give you control

over the look of the menu When you write the code yourself to draw the whole menu onto

a Canvas, you can give it whatever look you want Figure 10-6 shows the result for the improved

Dungeon example

Figure 10-6. The Dungeon game in menu mode on a small-screen emulator

The menu works by having a menu softkey switch the DungeonCanvas in and out of menumode (just toggling a boolean field myMenuMode in the class) When in menu mode, the current

game canvas is painted on the screen as usual, but then the menu items are painted on top as

sprites The menu item sprite images are words written on a transparent background (so the

game screen is visible between and around the letters) and the letters appear in black or blue

depending on whether the item is currently the focused item (as discussed in the section

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 2

“Modifying Image Colors and Transparency” earlier in this chapter) and the animated sparklingsprite is painted behind the focused item The focus can be moved from one menu item toanother using the arrow keys, and the focused item is the item that will be selected when theplayer clicks Select In menu mode the game thread continues advancing as usual and query-ing for keystrokes, but the keystroke information is interpreted by the menu command codeand the game loop advances the sparkling animation of the star sprite instead of advancingthe game ticks and game animation All of this is seen in Listing 10-8

// (constant after initialization)/**

* the top corner x coordinate according to this

* object's coordinate system:

*/

static int CORNER_X = 0;

/**

* the top corner y coordinate according to this

* object's coordinate system:

*/

static int CORNER_Y = 0;

/**

* the width of the portion of the screen that this

* canvas can use

*/

static int DISP_WIDTH;

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 3

* the height of the portion of the screen that this

* canvas can use

Trang 4

* The number of ticks on the clock the last time the

* time display was updated

* This is saved to determine if the time string needs

* to be recomputed

*/

int myDisplayGameTicks = 0;

/**

* the number of game ticks that have passed since the

* beginning of the game

*/

int myGameTicks = myDisplayGameTicks;

/**

* An array of number sprites to hold the digit images

* for the time display

* The button to go to the next board

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 5

Command myOkCommand;

// menu-related fields

Trang 6

* This is called when the game ends

*/

void setGameOver() {myGameOver = true;

myDungeon.pauseApp();

}/**

* Get the DungeonManager

*/

DungeonManager getManager() {return myManager;

}/**

* Find out if the game has ended

*/

static boolean getGameOver() {

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 7

}/**

* Get the Customizer

*/

public Customizer getCustomizer() {return myCustomizer;

}// -// initialization and game state changes

/**

* Constructor sets the data, performs dimension calculations,

* and creates the graphical objects

}if((DISP_WIDTH < 150) || (DISP_HEIGHT < 170)) {throw(new Exception("Screen too small"));

}if((DISP_WIDTH > 375) || (DISP_HEIGHT > 375)) {throw(new Exception("Screen too large"));

}// create the class that handles the differences among// the various platforms

myCustomizer = new Customizer(DISP_WIDTH, DISP_HEIGHT);

// create the LayerManager (where all of the interesting // graphics go!) and give it the dimensions of the // region it is supposed to paint:

if(myManager == null) {myManager = new DungeonManager(CORNER_X, CORNER_Y, DISP_WIDTH, DISP_HEIGHT, myCustomizer, this);

} }

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 8

* Once the customizer has been initialized, this

* method loads and initializes the graphical objects

* for the timer and the menu

*/

void start() throws IOException {myGameOver = false;

// initialize the graphics for the timeclock:

Image numberImage = myManager.getNumberImage();

int width = numberImage.getWidth() / 11;

int height = numberImage.getHeight();

for(int i = 0; i < 5; i++) {myNumberSprites[i] = new Sprite(numberImage, width, height);

myNumberSprites[i].setPosition(width*i, 0);

}// frame 10 is the colon:

myNumberSprites[2].setFrame(10);

// if the customizer identifies the platform as // one we have keycode data for, we can implement// the softkeys with images

if(myCustomizer.useSoftkeys()) {setFullScreenMode(true);

myDisplay.setCurrent(this);

// initialize the menu graphics:

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 9

int width = tempImage.getWidth();

int height = tempImage.getHeight();

Sprite retObj = new Sprite(ColorChanger.createFocused(tempImage, OPAQUE_BLACK, OPAQUE_BLUE), width, height);

retObj.defineReferencePixel(width/2, height/2);

return(retObj);

}/**

* sets all variables back to their initial positions

*/

void reset() throws Exception {// most of the variables that need to be reset // are held by the LayerManager:

Trang 10

* sets all variables back to the positions

* from a previously saved game

*/

void revertToSaved() throws Exception {// most of the variables that need to be reset // are held by the LayerManager, so we

// prompt the LayerManager to get the // saved data:

myGameOver = false;

myDisplayGameTicks = myManager.revertToSaved();

}/**

* save the current game in progress

*/

void saveGame() throws Exception {myManager.saveGame(myDisplayGameTicks);

}/**

* clears the key states

*/

void flushKeys() {getKeyStates();

}/**

* Switch to showing the game action menu

*/

void setMenuMode() {myMenuMode = !myMenuMode;

}/**

* If the game is hidden by another app (or a menu)

* ignore it since not much happens in this game

* when the user is not actively interacting with it

Trang 11

// graphics methods

try {myManager.paint(g);

} catch(Exception e) {myDungeon.errorMsg(e);

return;

}// the timer is painted on top of // the game graphics:

for(int i = 0; i < 5; i++) {myNumberSprites[i].paint(g);

}// paint the menu on if in menu mode:

if(myMenuMode) {int y = MENU_BUFFER;

for(int i = 0; i < myMenuVector.size(); i++) {Sprite item = (Sprite)(myMenuVector.elementAt(i));

if(i == myFocusedIndex) {myStars.setRefPixelPosition(DISP_WIDTH / 2, y);

myStars.paint(g);

item.setFrame(FOCUSED);

} else {item.setFrame(UNFOCUSED);

y += myStars.getHeight()/2;

y += MENU_BUFFER;

}}if(myCustomizer.useSoftkeys()) {g.drawImage(myExit, 2, DISP_HEIGHT - 2, Graphics.BOTTOM|Graphics.LEFT);

if(myGameOver) {g.drawImage(myOk, DISP_WIDTH - 2, DISP_HEIGHT - 2, Graphics.BOTTOM|Graphics.RIGHT);

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 12

} else {g.drawImage(myMenu, DISP_WIDTH - 2, DISP_HEIGHT - 2, Graphics.BOTTOM|Graphics.RIGHT);

}}// write "Next Board" when the user finishes a board:

if(myGameOver) {myNext.setFrame(UNFOCUSED);

myNext.setRefPixelPosition(DISP_WIDTH / 2, DISP_HEIGHT / 2);

myNext.paint(g);

}}/**

* a simple utility to make the number of ticks look

* like a time

*/

public void setTimeSprites() {// we advance the display ticks once // for every twenty game ticks because// there are twenty frames per second:

if(myGameTicks % 20 == 0) {// the number sprite is designed so that // the frame number corresponds to the // actual digit:

/**

* update the display

*/

void updateScreen() {if(! myMenuMode) {myGameTicks++;

setTimeSprites();

} else {// in menu mode the game doesn't advance

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 13

// but the sparking animation behind the // selected item must advance:

myStars.nextFrame();

}// paint the display:

try {paint(getGraphics());

flushGraphics(CORNER_X, CORNER_Y, DISP_WIDTH, DISP_HEIGHT);

} catch(Exception e) {myDungeon.errorMsg(e);

}}/**

* Respond to keystrokes

*/

public void checkKeys() { if(! myGameOver) {// determine which moves the user would like to make:

int keyState = getKeyStates();

if(myMenuMode) {menuAction(keyState);

} else {int vertical = 0;

int horizontal = 0;

if((keyState & LEFT_PRESSED) != 0) {horizontal = -1;

} if((keyState & RIGHT_PRESSED) != 0) {horizontal = 1;

}if((keyState & UP_PRESSED) != 0) {vertical = -1;

} if((keyState & DOWN_PRESSED) != 0) {// if the user presses the down key, // we put down or pick up a key object// or pick up the crown:

myManager.putDownPickUp();

} // tell the manager to move the player // accordingly if possible:

myManager.requestMove(horizontal, vertical);

}}}

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 14

}// change which item is selected in // response to up and down:

if((keyState & UP_PRESSED) != 0) {if(myFocusedIndex > 0) {

myFocusedIndex ;

}} if((keyState & DOWN_PRESSED) != 0) {if((myFocusedIndex + 1) < myMenuVector.size()) {myFocusedIndex++;

}}} catch(Exception e) {myDungeon.errorMsg(e);

}}/**

* Respond to softkeys

* The keystates value won't give information

* about softkeys, so the keypressed method

* must be implemented separately:

*/

public void keyPressed(int keyCode) {int softkey = myCustomizer.whichSoftkey(keyCode);

if(softkey == Customizer.SOFT_LEFT) {// left is exit:

Trang 15

// or advances to the next board if a board// is done:

try {if(myGameOver) {reset();

flushKeys();

myDungeon.resumeGame();

} else {setMenuMode();

}} catch(Exception e) {myDungeon.errorMsg(e);

}}}/**

* Respond to softkeys in the case where

* lcdui commands are used instead of custom

} else if(c == myOkCommand) {removeCommand(myOkCommand);

}}}

You can see that another advantage of this version over the version in Chapter 5 is that thetimer is also drawn with a set of five sprites (all using the same image) instead of being drawn

with one of the platform’s built-in fonts onto an ugly black bar drawn across the bottom of the

screen Figure 10-7 shows the difference

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 16

Figure 10-7. The difference in how the timer number appears in the two versions

The trickiest part of the menu code in Listing 10-8 is the implementation of the softkeys,explained in the next section

Implementing Softkeys

Nearly every MIDP device uses a system of softkeys to drive its built-in GUI A softkey is

a physical button on the device whose function changes depending on the context The buttoncorresponding to the softkey is generally placed right next to the screen so that the programcan display the current label for it such as Exit, Options, or OK A typical platform has twosoftkeys—a right softkey and a left softkey—at the base of the screen

When writing your own custom GUI, naturally you want to be able to implement the softkeyfunctionality so that you can be sure that the softkey labels match the look of the rest of thegraphical components Unfortunately, the designers of MIDP decided that they didn’t want tomake it easy for you to do this The philosophy seems to be that the softkeys are a platform-specific implementation detail that you don’t need to know about, and if you start fiddlingwith them, you can mess up the platform’s consistent user experience by perhaps putting yourExit key on the left when the platform normally puts it on the right, or you might assume thesoftkeys are at the bottom of the screen when for a particular platform they’re at the top SoMIDP encapsulates softkeys (and possibly other related input features) in Command objects andsays in essence “We’ll handle them—you don’t touch them.”

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 17

However, since so many devices use this same consistent design of placing the softkeys atthe bottom left and bottom right of the screen, it’s natural to want to try to implement them

yourself to create a consistent, attractive look for your game It would have been nice if the

designers of MIDP had at least thrown in some minimal support such as a system property

you can query to determine whether the platform uses standard (bottom left and bottom

right) softkeys, and then provide the corresponding key constants in the GameCanvas class As it

is, it’s possible to receive and interpret the softkey events, but you have to do some additional

work, and the resulting code isn’t terribly portable Essentially you have to customize the JAR

file for every target device (or at least every manufacturer) that you’d like to use custom

soft-keys on

Here’s how to do it If you look at Listing 10-8, you’ll see that in addition to querying for keystates (as in the corresponding class in Chapter 5), the keyPressed() method is also implemented

This is because the return value of the getKeyStates() method only returns information about

the standard Java key constants However, the AMS calls the keyPressed() method with the

platform’s raw keycode integer corresponding to the key that was pressed Since these keycodes

vary from one device to the next, you usually follow with the getGameAction class to translate

the platform-specific keycode into a recognizable Java constant (as explained in the section

“Using the Graphics and Canvas Classes” from Chapter 2) But if you happen to know the

cur-rent device’s codes for the left and right softkeys, this is where you use that information

Figuring out what keycodes your game should be using at any given moment is a two-stepprocess: (1) identify the platform, and (2) load and use the correct keycode values for the current

platform Identifying the platform is a challenge all its own, discussed in the “Identifying the

Platform” sidebar earlier Then figuring out the keycodes for all of your target devices is a

sep-arate challenge Some manufacturers (Sony Ericsson, for example) publish developer guides

that contain the keycodes Additionally, there are online databases listing the keycodes for many

popular devices, such as the device database on the J2ME Polish web site (see the “Using J2ME

Polish” sidebar)

Many devices follow the WTK’s example for their keycode mapping: -6 for the left softkeyand -7 for the right softkey (These are the values used by Sony Ericsson, for example.) But many

don’t My Sagem my700x, for example, uses exactly the reverse

Once you know the keycodes for the current device, implementing the softkeys is a snap

As you can see in Listing 10-8, you set your canvas to full-screen mode, then paint on the

soft-key labels in the lower right and left corners of the screen, and handle the softsoft-key actions in

the keyPressed() method

However, it’s good to provide a fallback for the case where the game is running on a devicethat you can’t identify and/or don’t have the keycodes for In this case, we can still use the cus-

tom menu code, but the menu screen is put up and down using standard lcdui Command objects,

implemented in the commandAction() method of Listing 10-8 It’s not quite as pretty, but it’s not

the end of the world Figure 10-8 shows what that looks like

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Ngày đăng: 12/08/2014, 11:20

TỪ KHÓA LIÊN QUAN