Home arrow Java arrow Page 4 - Storing and Retrieving Data
JAVA

Storing and Retrieving Data


Storing bytes of data locally on a device equipped for the Mobile Internet Device Profile (MIDP) is easy. MIDP allows you to store arrays of bytes. But what if the data you need to store isn't in the form of bytes? And how can you make the data small enough so that storing it on a device with a relatively small amount of memory is not a problem? That's where this article comes in. It is excerpted from the book J2ME Games with MIDP2, written by Carol Hamer (Apress, 2004; ISBN: 1590593820).

Author Info:
By: Apress Publishing
Rating: 4 stars4 stars4 stars4 stars4 stars / 24
May 12, 2005
TABLE OF CONTENTS:
  1. · Storing and Retrieving Data
  2. · Serializing More Complex Data Using Streams
  3. · Using Data Types and Byte Arithmetic
  4. · Applying Data Storage to a Game
  5. · Converting an array of bytes into a dungeon
  6. · Creating the Complete Example Game
  7. · DungeonManager.java
  8. · Doors and keys

print this article
SEARCH DEVARTICLES

Storing and Retrieving Data - Applying Data Storage to a Game
(Page 4 of 8 )

In this section, youíll see how the example game works. As I mentioned previously, the game involves a character (in fact, a princess) exploring a dungeon thatís made up of a 16x16 grid (see Figure 5-1). To make it more interesting, the maze is a vertical cross-section of the dungeon, so the princess gets around by jumping up and falling down in addition to running around. Also, to add to the challenge, four keys on each board open eight locked doors. Each key is a different color and opens doors of the corresponding color. Each board has two doors of each color. The player can hold only one key at a time. The goal is to find a crown thatís locked away somewhere in the maze.


Figure 5-1.  The game in action 

In this version, data storage comes into play because the user can save a game thatís currently in progress and start again later from that point. All the saved game information is serialized and deserialized by the GameInfo class (see Listing 5-4). As youíll see in the code, the GameInfo class stores the number of the board that the player is currently on, the current location of the player, the current locations of the keys, the key (if any) thatís currently in the playerís hand, the doors that are already open, and the time on the clock. All the locations are in terms of their coordinates on a 16x16 grid, so theyíre integers from 0 to 15 (inclusive). Therefore, to save memory, Iíve stocked the coordinates two to a byte using the DataConverter class in Listing 5-3. The time on the clock, however, may be a very large number, so I use all 4 bytes to store it. Listing 5-4 shows the code for GameInfo.java.

Listing 5-4. GameInfo.java

  package net.frog_parrot.dungeon;
 
import javax.microedition.lcdui.*;
  import javax.microedition.lcdui.game.*;
  import javax.microedition.rms.*;
  import net.frog_parrot.util.DataConverter;
 
/**
    * This class contains the data for a game currently in progress.
    * used to store a game and to resume a stored game.
    *
   
* @author Carol Hamer
    */
  public class GameInfo {
    //-----------------------------------------------------    // fields
   
/**
   
* The name of the datastore.
   
*/
  public static final String STORE = "GameInfo";
  /**
   
* This is set to true if an attempt is made to
   
* read agame when no game has been saved.
    */
  private boolean myNoDataSaved;
 
/**
   
* The number that indicates which board the player
   
* is currently on.
   
*/
  private int myBoardNum;
 
/**
   
* The amount of time that has passed.
   
*/
  private int myTime;
 
/**
    * The coordinates of where the player is on the board.
   
* coordinate values must be between 0 and 15.
   
*/
  private int[] myPlayerSquare;
  /**
   
* The coordinates of where the keys are currently found.
   
* MUST BE four sets of two integer coordinates.
   
* coordinate values must be between 0 and 15.
   
*/
  private int[][] myKeyCoords;
 
/**
   
* The list of which doors are currently open.
   
* 0 = open
   
* 1 = closed
   
* WARNING: this array MUST have length 8.
   
*/
  private int[] myDoorsOpen;
 
/**
   
* The number of the key that is currently being held
   
* by the player. if no key is held, then the value is -1.
   
*/
  private int myHeldKey;
 
//-------------------------------------------------------  // data gets/sets
 
/**
    * @return true if no saved game records were found.
    */
  boolean getIsEmpty() {
   
return(myNoDataSaved);
  }
 
/**
   
* @return The number that indicates which board the player
   
* is currently on.
    */
  int getBoardNum() {
   
return(myBoardNum);
  }
 
/**
   
* @return The number of the key that is currently being held
   
* by the player. if no key is held, then the value is -1.
    */
   int getHeldKey() {
   
return(myHeldKey);
   }
 
/**
   
* @return The amount of time that has passed.
    */
  int getTime() {
    return(myTime);
  }
  /**
   
*@return The coordinates of where the player is on the board.
   
*coordinate values must be between 0 and 15.
    */
  int[] getPlayerSquare() {
   
return(myPlayerSquare);
  }
  /**
   
*@return The coordinates of where the keys are currently found.
   
*MUST BE four sets of two integer coordinates.
   
*coordinate values must be between 0 and 15.
    */
  int[][] getKeyCoords() {
    return(myKeyCoords);
  }
 
/**
   
*@return The list of which doors are currently open.
   
* 0 = open
   
* 1 = closed
   
* WARNING: this array MUST have length 8.
    */
  int[] getDoorsOpen() {
    return(myDoorsOpen);
  }
 
//-------------------------------------------------------  // constructors
 
/**
   
* This constructor records the game info of agame currently
   
* in progress.
    */
  GameInfo(int boardNum, int time, int[] playerSquare, int[][] keyCoords,
           int[] doorsOpen, int heldKey) throws Exception {
    myBoardNum = boardNum;
   
myTime = time;
    myPlayerSquare = playerSquare;
    myKeyCoords = keyCoords;
    myDoorsOpen = doorsOpen;
    myHeldKey = heldKey;
    encodeInfo();
 
}
 
/**
    * This constructor reads the game configuration from memory.
   
* This is used to reconstruct a saved game.
    */
  GameInfo() {
    RecordStore store = null;
  try {
   
// if the record store does not yet exist, don't
    // create it
    store = RecordStore.openRecordStore(STORE, false);
    if((store != null) && (store.getNumRecords() > 0)) {
      
// the first record has id number 1
      // it should also be the only record since this
      // particular game stores only one game.
      byte[] data = store.getRecord(1);
      myBoardNum = data[0];
      myPlayerSquare = DataConverter.decodeCoords(data[1]);
      myKeyCoords = new int[4][];
      myKeyCoords[0] = DataConverter.decodeCoords(data[2]);
      myKeyCoords[1] = DataConverter.decodeCoords(data[3]);
      myKeyCoords[2] = DataConverter.decodeCoords(data[4]);
      myKeyCoords[3] = DataConverter.decodeCoords(data[5]);
      myDoorsOpen = DataConverter.decode8(data[6]);  
      myHeldKey = data[7];
      byte[] fourBytes = new byte[4];
      System.arraycopy(data, 8, fourBytes, 0, 4);
      myTime = DataConverter.parseInt(fourBytes);
   
} else {
      myNoDataSaved = true;
    }
  } catch(Exception e) {
    // this throws when the record store doesn't exist.
    // for that or any error, you assume no data is saved:      myNoDataSaved = true;
  } finally {
    try {
       if(store != null) {
         store.closeRecordStore();
       }
    } catch(Exception e) {
      // if the record store is open this shouldn't throw.
    }
  }
}
//------------------------------------------------------- // encoding method
/**
 
* Turn the data into abyte array and save it.
  */
private void encodeInfo() throws Exception {
  RecordStore store = null;
  try {
    byte[] data = new byte[12];
    data[0] = (new Integer(myBoardNum)).byteValue();
    data[1] = DataConverter.encodeCoords(myPlayerSquare); 
    data[2] = DataConverter.encodeCoords(myKeyCoords[0]); 
    data[3] = DataConverter.encodeCoords(myKeyCoords[1]); 
    data[4] = DataConverter.encodeCoords(myKeyCoords[2]); 
    data[5] = DataConverter.encodeCoords(myKeyCoords[3]);
    data[6] = DataConverter.encode8(myDoorsOpen, 0);
    data[7] = (new Integer(myHeldKey)).byteValue();
    byte[] timeBytes = DataConverter.intToFourBytes(myTime);
    System.arraycopy(timeBytes, 0, data, 8, 4);
    // if the record store does not yet exist, the second
    // arg "true" tells it to create.
    store = RecordStore.openRecordStore(STORE, true);
    int numRecords = store.getNumRecords();
    if(numRecords > 0) {
      store.setRecord(1, data, 0, data.length);
    } else {
      store.addRecord(data, 0, data.length);
    }
  } catch(Exception e) {
    throw(e);
  } finally {
    try {
      if(store != null) {
        store.closeRecordStore();
        }
      } catch(Exception e) {
        // if the record store is open this shouldn't throw.
      }
    }
  }
}

In this version of the game, Iím not storing the floor plan of each board in memory records on the device. Thatís because the dungeons themselves arenít created by the userís interaction with the game; theyíre created in advance. In the next chapter, youíll use the same basic game, but youíll store the various boards in memory as the user downloads them from a game site. In this version, Iíve compacted all the information for the boards into bytes in anticipation of the next version in which the boards themselves will be downloaded and stored locally. Listing 5-5 shows the class that converts an array of bytes to a dungeon (BoardDecoder.java).


blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials