⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bluetoothmanager.java

📁 Creat mobile game Creat mobile game Creat mobile game Creat mobile game
💻 JAVA
字号:
package net.frog_parrot.net;import java.io.*;import java.util.Vector;import javax.microedition.io.*;import javax.bluetooth.*;import net.frog_parrot.checkers.MoveManager;/** * This class keeps track of transferring local and  * remote moves from one player to the other.. * * @author Carol Hamer */public class BluetoothManager extends Thread     implements DiscoveryListener {  //--------------------------------------------------------  //  static fields  /**   * The int to signal that the game is to begin.   */  public static final byte START_GAME_FLAG = -4;  /**   * The byte to signal that the game is to end.   */  public static final byte END_GAME_FLAG = -3;  /**   * The byte to signal the end of a turn.   */  public static final byte END_TURN_FLAG = -2;  /**   * The byte to signal the remote connection has    * been closed.   */  public static final byte EOF_FLAG = -1;  /**   * A possible connection mode.   */  public static final byte SERVER_MODE = 0;  /**   * A possible connection mode.   */  public static final byte CLIENT_MODE = 1;  /**   * The protocol string for the bluetooth stream protocol.   */  public static final String BLUETOOTH_PROTOCOL = "btspp://";  /**   * The string that uniquely identifies this Bluetooth service:   */  private static final String CHECKERS_UUID       = "2bbc2d287c8c11dba1500040f45842ef";  /**   * The user-friendly name of the service:   */  private static final String CHECKERS_NAME = "Checkers";  //--------------------------------------------------------  //  game instance fields  /**   * Whether the MIDlet will be acting as a client or as a    * server for this round.   */  private int myMode;  /**   * The results of the client search for available services.   */  private int myDiscoveryType;  /**   * The results of the client search for available devices.   */  private Vector myRemoteDevices = new Vector();  /**   * The results of the client search for available devices.   */  private ServiceRecord myRemoteServiceRecord;  /**   * Whether the to break out of the communications loop and    * end the game.   */  private boolean myShouldStop;  /**   * The class that directs the data from the communications   * module to game logic module and vice versa.   */  private MoveManager myManager;  /**   * The instance of the BlueTooth UUID class that is needed to    * make the connection.   */  private UUID myUUID = new UUID(CHECKERS_UUID, false);  /**   * The network connection.   */  private StreamConnection myStreamConnection;  /**   * The corresponding input stream.   */  private InputStream myInputStream;  /**   * The corresponding output stream.   */  private OutputStream myOutputStream;  //--------------------------------------------------------  //  data exchange instance fields  /**   * The data from the local player that is to    * be sent to the opponent.   */  private byte[] myMove;  //--------------------------------------------------------  //  lifecycle  /**   * Start the processes to send and receive messages.   */  public void setMode(int mode, MoveManager manager) {    myManager = manager;    myMode = mode;    start();  }  /**   * Start the thread that communicates with the remote   * player.   */  public void run() {    try {      if(myMode == SERVER_MODE) {        serverRun();      } else {        clientRun();      }    } catch(Exception e) {      myManager.errorMsg("failed: " + e.getMessage());      debug("run");      e.printStackTrace();    }  }  /**   * Stop the receiver.     * This method is called alone from pauseApp or destroyApp   * since sending one last message is too time-consuming.   */  public synchronized void shutDown() {    myShouldStop = true;    notify();  }  /**   * Close all of the streams.   */  public void cleanUp() {    try {      if(myInputStream == null) {        myInputStream.close();      }      if(myOutputStream == null) {        myOutputStream.close();      }      if(myStreamConnection == null) {        myStreamConnection.close();      }    } catch(Exception e) {    }  }  /**   * This is called when the game is in server mode and has been   * contacted by a remote client player.  This triggers the    * game logic to let the local player make the first move.   */  public void receiveInvitation() {    debug("receiveInvitation");    int state = myManager.getState();    if(state == MoveManager.NOT_STARTED) {      myManager.receiveInvitation();    }  }  //--------------------------------------------------------  //  server methods.  /**   * Perform the initial steps to start up a very simple    * server connection that accepts only one client connection.   */  void serverRun() {    debug("serverRun");    StreamConnectionNotifier notifier;    try {      // get a handle to the local device and set it       // to accept client connections:      LocalDevice localDevice = LocalDevice.getLocalDevice();      // GIAC is the standard general discovery mode:      localDevice.setDiscoverable(DiscoveryAgent.GIAC);      // create the URL and the server connection      StringBuffer buff = new StringBuffer(BLUETOOTH_PROTOCOL);      // setting the host to localhost opens this as a      // server connection.      buff.append("localhost").append(':');      buff.append(myUUID.toString());      buff.append(";name=");      buff.append(CHECKERS_NAME);      buff.append(";authorize=false");            debug("serverRun-->url: " + buff.toString());      // Since this is a server connection, Connector.open      // returns a connection notifier rather than a       // simple connection      notifier           = (StreamConnectionNotifier)Connector.open(buff.toString());      debug("serverRun-->notifier: " + notifier);      // accept exactly one client connection:      myStreamConnection = notifier.acceptAndOpen();      debug("serverRun-->conn: " + myStreamConnection);      myInputStream = myStreamConnection.openInputStream();      debug("serverRun-->is: " + myInputStream);      // the client player starts by sending the start game       // flag, triggering the server player to take a turn:      byte[] oneByte = new byte[1];      myInputStream.read(oneByte);      debug("serverRun-->read: " + oneByte[0]);      myManager.receiveInvitation();      debug("serverRun-->myManager: " + myManager);      // we don't want any more clients to try to connect,       // so we close up the notifier:      notifier.close();      // Even though the stream is closed, it's cleaner to        // set the server to "not discoverable" so further       // clients don't query this service and attempt to connect:      localDevice.setDiscoverable(DiscoveryAgent.NOT_DISCOVERABLE);      myOutputStream = myStreamConnection.openOutputStream();      runGame(myOutputStream, myInputStream);    } catch (IOException e) {      myManager.errorMsg("failed: " + e.getMessage());      e.printStackTrace();    }  }  //--------------------------------------------------------  //  client methods.  /**   * Perform the initial steps to start up a very simple    * client connection.   */  void clientRun() {    debug("clientRun");    try {      // start looking for available Bluetooth services:      LocalDevice localDevice = LocalDevice.getLocalDevice();      DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent();      debug("clientRun-->discoveryAgent: " + discoveryAgent);      // Set this as the discovery listener, then wait for       // the inquiryCompleted call:      discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);      synchronized(this) {        wait();      }      if(myDiscoveryType == INQUIRY_COMPLETED) {        // now for each device, we search for services:        debug("clientRun-->myRemoteDevices: " + myRemoteDevices.size());        for(int i = 0; i < myRemoteDevices.size(); i++) {          RemoteDevice rd = (RemoteDevice)myRemoteDevices.elementAt(i);          // we assume that the user has arranged to have           // exactly one player in range, so we search until           // we find a checkers service and stop:          UUID[] uuids = new UUID[2];          // this indicates socket communications:          uuids[0] = new UUID(0x1101);          // and this is the Checkers service specifically:          uuids[1] = new UUID(CHECKERS_UUID, false);          // The return value of the search call is an id int           // that can be used to cancel the search if           // something goes wrong:          debug("clientRun-->about to search services");          int id = discoveryAgent.searchServices(null, uuids,                        rd, this);          // now wait to see if we found the service:          synchronized(this) {            wait();          }          if(myRemoteServiceRecord != null) {            break;          }        }        debug("clientRun-->myRemoteServiceRecord: " + myRemoteServiceRecord);        if(myRemoteServiceRecord != null) {          // now let's open the connection:          String url = myRemoteServiceRecord.getConnectionURL(              ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);          debug("clientRun-->url: " + url);          myStreamConnection = (StreamConnection)Connector.open(url);          myOutputStream = myStreamConnection.openOutputStream();          debug("clientRun-->os: " + myOutputStream);          byte[] oneByte = new byte[1];          oneByte[0] = (byte)START_GAME_FLAG;          myOutputStream.write(oneByte);          myManager.foundOpponent();          myInputStream = myStreamConnection.openInputStream();          runGame(myOutputStream, myInputStream);        } else {          myManager.errorMsg("failed to find remote player");        }      } else {        myManager.errorMsg("failed to find remote player");      }    } catch (Exception e) {      myManager.errorMsg("failed: " + e.getMessage());      e.printStackTrace();    }  }  /**   * Implementation of DiscoveryListener.   */  public void deviceDiscovered(RemoteDevice device, DeviceClass dc) {    myRemoteDevices.addElement(device);  }  /**   * Implementation of DiscoveryListener.   */  public void inquiryCompleted(int discoveryType) {    myDiscoveryType = discoveryType;    synchronized(this) {      notify();    }  }  /**   * Implementation of DiscoveryListener.   * For a given remote device, find its services.   */  public synchronized void servicesDiscovered(int id,       ServiceRecord[] sr) {    if(myRemoteServiceRecord == null) {      myRemoteServiceRecord = sr[0];      notify();    }  }    /**   * Implementation of DiscoveryListener.   * For a given remote device, find its services.   */  public synchronized void serviceSearchCompleted(int id, int respCode) {    // if none were found, notify that the search for services    // on this device is done.    if(myRemoteServiceRecord == null) {      notify();    }  }    //--------------------------------------------------------  //  main game method  /**   * This is the main loop that controls the game play   * back and forth.   */  void runGame(OutputStream os, InputStream is) throws IOException {    debug("runGame");    byte[] fourBytes = new byte[4];    while(! myShouldStop) {      int state = myManager.getState();      debug("runGame-->state: " + state);      if(state == MoveManager.LOCAL_TURN) {        try {          synchronized(this) {            wait();          }        } catch(InterruptedException e) {        }        debug("runGame-->about to write move");        try {          if(myMove != null) {            os.write(myMove);          }        } catch(IOException e) {          // if we can't write anymore, the remote           // player has probably closed the connection:          myManager.errorMsg("remote player has quit");        }        myMove = null;      } else if(state == MoveManager.REMOTE_TURN) {        debug("runGame-->about to read move");        byte moveData = (byte)is.read();        debug("runGame-->moveData: " + moveData);        if((moveData == END_GAME_FLAG)             || (moveData == EOF_FLAG)) {          debug("runGame-->remote player quit");          myShouldStop = true;          myManager.receiveGameOver();        } else if (moveData == END_TURN_FLAG) {          myManager.endRemoteTurn();        } else {          fourBytes[0] = moveData;          for(int i = 1; i < 4; i++) {            moveData = (byte)is.read();            fourBytes[i] = moveData;          }          myManager.receiveRemoteMove(fourBytes);        }        debug("runGame-->done reading");      } else {        myShouldStop = true;      }    }    debug("runGame-->done");    cleanUp();  }  //--------------------------------------------------------  //  sending methods.  /**   * Send the message to the other   * player that this player has quit.   */  public synchronized void sendGameOver() {    myMove = new byte[1];    myMove[0] = END_GAME_FLAG;    notify();  }  /**   * Records the local move in a byte array to prepare it    * to be sent to the remote player.   */  public void setLocalMove(byte[] move) {    debug("setLocalMove");    if(myMove == null) {      myMove = new byte[5];      System.arraycopy(move, 0, myMove, 0, 4);      myMove[4] = END_TURN_FLAG;    } else {      // here we're dealing with the case of a       // series of jumps.  This isn't the typical case, so       // it shouldn't be too inefficient to just       // create a new, larger array each time       // we enlarge the move payload.      byte[] newMove = new byte[myMove.length + 4];      System.arraycopy(myMove, 0, newMove, 0, myMove.length);      System.arraycopy(move, 0, newMove, myMove.length - 1, 4);      newMove[newMove.length - 1] = END_TURN_FLAG;      myMove = newMove;    }  }  /**   * Sends the current local move to the remote player.   */  public synchronized void sendLocalMove() {    debug("sendLocalMove-->myMove: " + myMove);    if(myMove != null) {      debug("sendLocalMove-->length: " + myMove.length);    }    notify();  }  //--------------------------------------------------------  //  utilities  /**   * print a debug statemeent.   */  public void debug(String message) {    if(myMode == SERVER_MODE) {      System.out.print("SERVER: ");    } else {      System.out.print("CLIENT: ");    }    System.out.println(message);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -