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

Creating Mobile Games Using Java phần 5 pps

43 141 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

Định dạng
Số trang 43
Dung lượng 527,67 KB

Nội dung

/** * the top-corner Y coordinate according to this * object's coordinate system: */ static final int CORNER_Y = 0; /** * the width of the portion of the screen that this * canvas can use. */ static int DISP_WIDTH; /** * the height of the portion of the screen that this * canvas can use. */ static int DISP_HEIGHT; /** * the height of the font used for this game. */ static int FONT_HEIGHT; /** * the font used for this game. */ static Font FONT; /** * color constant */ public static final int BLACK = 0; /** * color constant */ public static final int WHITE = 0xffffff; // // game object fields /** * a handle to the display. */ private Display myDisplay; /** * a handle to the MIDlet object (to keep track of buttons). CHAPTER 5 ■ STORING AND RETRIEVING DATA 165 8806ch05.qxd 7/17/07 3:54 PM Page 165 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com */ private Dungeon myDungeon; /** * the LayerManager that handles the game graphics. */ private DungeonManager myManager; /** * whether the game has ended. */ private static boolean myGameOver; /** * 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. */ private int myOldGameTicks = 0; /** * the number of game ticks that have passed since the * beginning of the game. */ private int myGameTicks = myOldGameTicks; /** * you save the time string to avoid re-creating it * unnecessarily. */ private static String myInitialString = "0:00"; /** * you save the time string to avoid re-creating it * unnecessarily. */ private String myTimeString = myInitialString; // // gets/sets /** * This is called when the game ends. */ void setGameOver() { myGameOver = true; CHAPTER 5 ■ STORING AND RETRIEVING DATA 166 8806ch05.qxd 7/17/07 3:54 PM Page 166 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com myDungeon.pauseApp(); } /** * Find out if the game has ended. */ static boolean getGameOver() { return(myGameOver); } /** * Tell the layer manager that it needs to repaint. */ public void setNeedsRepaint() { myManager.setNeedsRepaint(); } // // initialization and game state changes /** * Constructor sets the data, performs dimension calculations, * and creates the graphical objects. */ public DungeonCanvas(Dungeon midlet) throws Exception { super(false); myDisplay = Display.getDisplay(midlet); myDungeon = midlet; // calculate the dimensions DISP_WIDTH = getWidth(); DISP_HEIGHT = getHeight(); if((!myDisplay.isColor()) || (myDisplay.numColors() < 256)) { throw(new Exception("game requires full-color screen")); } if((DISP_WIDTH < 150) || (DISP_HEIGHT < 170)) { throw(new Exception("Screen too small")); } if((DISP_WIDTH > 250) || (DISP_HEIGHT > 320)) { throw(new Exception("Screen too large")); } // since the time is painted in white on black, // it shows up better if the font is bold: FONT = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM); // calculate the height of the black region that the // timer is painted on: FONT_HEIGHT = FONT.getHeight(); TIMER_HEIGHT = FONT_HEIGHT + 8; CHAPTER 5 ■ STORING AND RETRIEVING DATA 167 8806ch05.qxd 7/17/07 3:54 PM Page 167 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com // create the LayerManager (where all 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 - TIMER_HEIGHT, this); } } /** * This is called as soon as the application begins. */ void start() { myGameOver = false; myDisplay.setCurrent(this); setNeedsRepaint(); } /** * 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: myManager.reset(); myGameOver = false; setNeedsRepaint(); } /** * 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: myGameTicks = myManager.revertToSaved(); myGameOver = false; myOldGameTicks = myGameTicks; myTimeString = formatTime(); setNeedsRepaint(); } /** * save the current game in progress. */ CHAPTER 5 ■ STORING AND RETRIEVING DATA 168 8806ch05.qxd 7/17/07 3:54 PM Page 168 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com void saveGame() throws Exception { myManager.saveGame(myGameTicks); } /** * clears the key states. */ void flushKeys() { getKeyStates(); } /** * 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. * (you could pause the timer, but it's not important * enough to bother with when the user is just pulling * up a menu for a few seconds) */ protected void hideNotify() { } /** * When it comes back into view, just make sure the * manager knows that it needs to repaint. */ protected void showNotify() { setNeedsRepaint(); } // // graphics methods /** * paint the game graphics on the screen. */ public void paint(Graphics g) { // color the bottom segment of the screen black g.setColor(BLACK); g.fillRect(CORNER_X, CORNER_Y + DISP_HEIGHT - TIMER_HEIGHT, DISP_WIDTH, TIMER_HEIGHT); // paint the LayerManager (which paints // all the interesting graphics): try { myManager.paint(g); } catch(Exception e) { myDungeon.errorMsg(e); } CHAPTER 5 ■ STORING AND RETRIEVING DATA 169 8806ch05.qxd 7/17/07 3:54 PM Page 169 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com // draw the time g.setColor(WHITE); g.setFont(FONT); g.drawString("Time: " + formatTime(), DISP_WIDTH/2, CORNER_Y + DISP_HEIGHT - 4, g.BOTTOM|g.HCENTER); // write "Dungeon Completed" when the user finishes a board: if(myGameOver) { myDungeon.setNewCommand(); // clear the top region: g.setColor(WHITE); g.fillRect(CORNER_X, CORNER_Y, DISP_WIDTH, FONT_HEIGHT*2 + 1); int goWidth = FONT.stringWidth("Dungeon Completed"); g.setColor(BLACK); g.setFont(FONT); g.drawString("Dungeon Completed", (DISP_WIDTH - goWidth)/2, CORNER_Y + FONT_HEIGHT, g.TOP|g.LEFT); } } /** * a simple utility to make the number of ticks look like a time */ public String formatTime() { if((myGameTicks / 16) != myOldGameTicks) { myTimeString = ""; myOldGameTicks = (myGameTicks / 16) + 1; int smallPart = myOldGameTicks % 60; int bigPart = myOldGameTicks / 60; myTimeString += bigPart + ":"; if(smallPart / 10 < 1) { myTimeString += "0"; } myTimeString += smallPart; } return(myTimeString); } // // game movements /** * update the display. */ void updateScreen() { myGameTicks++; // paint the display try { CHAPTER 5 ■ STORING AND RETRIEVING DATA 170 8806ch05.qxd 7/17/07 3:54 PM Page 170 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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) { int vertical = 0; int horizontal = 0; // determine which moves the user would like to make: int keyState = getKeyStates(); 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); } } } Listing 5-9 shows the code for the LayerManager subclass DungeonManager.java. Listing 5-9. DungeonManager.java package net.frog_parrot.dungeon; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*; CHAPTER 5 ■ STORING AND RETRIEVING DATA 171 8806ch05.qxd 7/17/07 3:54 PM Page 171 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com /** * This class handles the graphics objects. * * @author Carol Hamer */ public class DungeonManager extends LayerManager { // // dimension fields // (constant after initialization) /** * The X coordinate of the place on the game canvas where * the LayerManager window should appear, in terms of the * coordinates of the game canvas. */ static int CANVAS_X; /** * The Y coordinate of the place on the game canvas where * the LayerManager window should appear, in terms of the * coordinates of the game canvas. */ static int CANVAS_Y; /** * The width of the display window. */ static int DISP_WIDTH; /** * The height of this object's visible region. */ static int DISP_HEIGHT; /** * the (right or left) distance the player * goes in a single keystroke. */ static final int MOVE_LENGTH = 8; /** * The width of the square tiles that this game is divided into. * This is the width of the stone walls as well as the princess and * the ghost. */ static final int SQUARE_WIDTH = 24; CHAPTER 5 ■ STORING AND RETRIEVING DATA 172 8806ch05.qxd 7/17/07 3:54 PM Page 172 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com /** * The jump index that indicates that no jump is * currently in progress. */ static final int NO_JUMP = -6; /** * The maximum speed for the player's fall. */ static final int MAX_FREE_FALL = 3; // // game object fields /** * the handle back to the canvas. */ private DungeonCanvas myCanvas; /** * the background dungeon. */ private TiledLayer myBackground; /** * the player. */ private Sprite myPrincess; /** * the goal. */ private Sprite myCrown; /** * the doors. */ private DoorKey[] myDoors; /** * the keys. */ private DoorKey[] myKeys; /** * the key currently held by the player. */ private DoorKey myHeldKey; CHAPTER 5 ■ STORING AND RETRIEVING DATA 173 8806ch05.qxd 7/17/07 3:54 PM Page 173 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com /** * The leftmost X coordinate that should be visible on the * screen in terms of this object's internal coordinates. */ private int myViewWindowX; /** * The top Y coordinate that should be visible on the * screen in terms of this object's internal coordinates. */ private int myViewWindowY; /** * Where the princess is in the jump sequence. */ private int myIsJumping = NO_JUMP; /** * Whether the screen needs to be repainted. */ private boolean myModifiedSinceLastPaint = true; /** * Which board we're playing on. */ private int myCurrentBoardNum = 0; // // gets/sets /** * Tell the layer manager that it needs to repaint. */ public void setNeedsRepaint() { myModifiedSinceLastPaint = true; } // // initialization // set up or save game data. /** * Constructor merely sets the data. * @param x The X coordinate of the place on the game canvas where * the LayerManager window should appear, in terms of the * coordinates of the game canvas. * @param y The Y coordinate of the place on the game canvas where CHAPTER 5 ■ STORING AND RETRIEVING DATA 174 8806ch05.qxd 7/17/07 3:54 PM Page 174 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... Thread objects that won’t be used 199 200 CHAPTER 6 ■ USING NETWORK COMMUNICATIONS Listing 6-2 shows the code for BoardReader .java Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Listing 6-2 BoardReader .java package net.frog_parrot.dungeon; import import import import java. io.*; javax.microedition.io.*; javax.microedition.lcdui.*; javax.microedition.rms.*; import net.frog_parrot.util.DataConverter;... background this time) But for the doors and keys, I wanted to store their colors in the Sprite object itself, so I created a subclass, DoorKey .java (see Listing 5- 10) Listing 5- 10 DoorKey .java package net.frog_parrot.dungeon; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*; /** * This class represents doors and keys * * @author Carol Hamer */ public class DoorKey extends Sprite... DungeonManager.SQUARE_WIDTH); } } And, of course, you don’t want to forget about the Thread subclass GameThread .java (see Listing 5- 11) Listing 5- 11 GameThread .java package net.frog_parrot.dungeon; /** * This class contains the loop that keeps the game running * * @author Carol Hamer */ public class GameThread extends Thread { 189 190 CHAPTER 5 ■ STORING AND RETRIEVING DATA // // fields Simpo PDF Merge... communications you often code only one side or the other Using HTTP Using the interface javax.microedition.io.HttpConnection is probably the easiest way to use the MIDP API to communicate with a server Listing 6-1 is a code segment that will create an instance of HttpConnection and use it to send a message to a server and read a response Listing 6-1 Creating an Instance of HttpConnection /** * Makes a... always allowed by the operator’s network But other options are sometimes useful depending on the circumstances Using the Micro Edition IO API Network communications in Java ME use a suite of InputStream and OutputStream classes that should be familiar to anyone who has done network programming in Java And once you’ve gotten the hang of programming for one type of connection, it’s easy to learn to use another... attempt * to show more than 20 frames per second */ private long getWaitTime() { long retVal = 1; CHAPTER 5 ■ STORING AND RETRIEVING DATA Simpo PDF long difference = System.currentTimeMillis() - myLastRefreshTime; if(difference < 50 ) { Merge and Split Unregistered Version - http://www.simpopdf.com retVal = 50 - difference; } return(retVal); } // -// actions /** * pause the game... available() method of the java. io DataInputStream to determine how many bytes of data are available before reading them in That way, you can call readFully() with no danger of blocking The only problem with using available() is that in my tests I’ve found it has an annoying tendency to return zero even when there are bytes available to read, so I generally don’t use it CHAPTER 6 ■ USING NETWORK COMMUNICATIONS... changing it to match the profile used by the WAP browser Mobile operators don't generally permit independent game design studios to send out SMS messages to configure the HTTP 193 194 Simpo CHAPTER 6 ■ USING NETWORK COMMUNICATIONS profiles of handsets out in nature, so you have to leave it up to the operators and your users to get their HTTP-from -Java configurations working correctly—and most of them... a service and also needs to find a way to receive and handle client requests In MIDP this is often done through the Push Registry (see the section Using the Push Registry” later in this chapter), but that’s not always the case Some protocols CHAPTER 6 ■ USING NETWORK COMMUNICATIONS Simpo define their own separate registry services—for example, the Bluetooth API (JSR 82) and the Content Handler API... the operator’s network to the open Internet This data (regarding proxies and such) is called a profile It is not to be confused with Java profiles such as MIDP—it is a completely different thing—the naming overlap is just a coincidence The HTTP profile available to the Java Virtual Machine (JVM) should normally be configured correctly by default, but unfortunately it is not always the case The profile . vertical); } } } Listing 5- 9 shows the code for the LayerManager subclass DungeonManager .java. Listing 5- 9. DungeonManager .java package net.frog_parrot.dungeon; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*; CHAPTER. handle to the MIDlet object (to keep track of buttons). CHAPTER 5 ■ STORING AND RETRIEVING DATA 1 65 8806ch 05. qxd 7/17/07 3 :54 PM Page 1 65 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com */ private. placed. int[] goalCoords = decoder.getGoalSquare(); CHAPTER 5 ■ STORING AND RETRIEVING DATA 1 75 8806ch 05. qxd 7/17/07 3 :54 PM Page 1 75 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com myCrown

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

TỪ KHÓA LIÊN QUAN