2017-06-13 135 views
2

我正在使用「Google Play遊戲服務」構建實時多人遊戲。我的問題是,當同伴連接到一個房間並玩遊戲時,其中一個人將他們的應用置於後臺,使得對等體與房間斷開連接,而其他對等體接收到該對等體離開房間的回叫,這是他們防止這發生了。實時多人遊戲Google Play遊戲服務同行在應用程序進入後臺時斷開連接

爲了測試目的,片段不要求在其任何生命週期方法中離開該房間。

我已經添加了代碼片段以提供更好的理解。

@Override 
    public void onStop() { 
     super.onStop(); 
//  if (mRoomId!=null && !mRoomId.isEmpty()) { 
//   Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId); 
//  } 
//  getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
//  mPlaying = false; 
    } 

     @Override 
      public void onActivityResult(int request, int response, Intent data) { 
       if (request == RC_SELECT_PLAYERS) { 
        if (response != Activity.RESULT_OK) { 
         // user canceled 
         return; 
        } 

        // get the invitee list 
        Bundle extras = data.getExtras(); 
        final ArrayList<String> invitees = 
          data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS); 

        // get auto-match criteria 
        Bundle autoMatchCriteria = null; 
        int minAutoMatchPlayers = 
          data.getIntExtra(Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0); 
        int maxAutoMatchPlayers = 
          data.getIntExtra(Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0); 

        if (minAutoMatchPlayers > 0) { 
         autoMatchCriteria = RoomConfig.createAutoMatchCriteria(
           minAutoMatchPlayers, maxAutoMatchPlayers, 0); 
        } else { 
         autoMatchCriteria = null; 
        } 

        // create the room and specify a variant if appropriate 
        RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder(); 
        roomConfigBuilder.addPlayersToInvite(invitees); 
        if (autoMatchCriteria != null) { 
         roomConfigBuilder.setAutoMatchCriteria(autoMatchCriteria); 
        } 
        RoomConfig roomConfig = roomConfigBuilder.build(); 
        Games.RealTimeMultiplayer.create(((MainActivity) getActivity()).getGoogleApiClient(), roomConfig); 

        // prevent screen from sleeping during handshake 
        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
       } 

       if (request == RC_WAITING_ROOM) { 
        if (mWaitingRoomFinishedFromCode) return; 

        if (response == Activity.RESULT_OK) { 
         // (start game) 
         new Handler().postDelayed(new Runnable() { 
          @Override 
          public void run() { 
           if (getContext()!=null) { 
            Player[] players = getParticipantPlayers(); 
            if (players!=null && players.length>0) { 
             startGame(players); 
            } 
           } 
          } 
         }, 1000); 
        } 
        else if (response == Activity.RESULT_CANCELED) { 
         // Waiting room was dismissed with the back button. The meaning of this 
         // action is up to the game. You may choose to leave the room and cancel the 
         // match, or do something else like minimize the waiting room and 
         // continue to connect in the background. 

         // in this example, we take the simple approach and just leave the room: 
         Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId); 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
        } 
        else if (response == GamesActivityResultCodes.RESULT_LEFT_ROOM) { 
         // player wants to leave the room. 
         Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId); 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
        } 
       } 
      } 

    private RoomUpdateListener roomUpdateListener = new RoomUpdateListener() { 

      @Override 
      public void onJoinedRoom(int statusCode, Room room) { 
       if (getContext()!=null) { 
        roomCreatorId = room.getCreatorId(); 
        mRoomId = room.getRoomId(); 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
    //   setCurrentPlayerParticipantId(); 
        if (statusCode != GamesStatusCodes.STATUS_OK) { 
         // let screen go to sleep 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

         // show error message, return to main screen. 
         Toast.makeText(getContext(), "Error while joining room.", Toast.LENGTH_SHORT).show(); 
         showRoomUi(); 
        } 

        // get waiting room intent 
        Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(((MainActivity) getActivity()).getGoogleApiClient(), room, MIN_PLAYERS); 
        startActivityForResult(i, RC_WAITING_ROOM); 
       } 
      } 

      @Override 
      public void onRoomCreated(int statusCode, Room room) { 
       if (getContext()!=null) { 
        roomCreatorId = room.getCreatorId(); 
        mRoomId = room.getRoomId(); 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
    //   setCurrentPlayerParticipantId(); 
        if (statusCode != GamesStatusCodes.STATUS_OK) { 
         // let screen go to sleep 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

         // show error message, return to main screen. 
         Toast.makeText(getContext(), "Error creating room.", Toast.LENGTH_SHORT).show(); 
         showRoomUi(); 
        } 

        // get waiting room intent 
        Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(((MainActivity) getActivity()).getGoogleApiClient(), room, MIN_PLAYERS); 
        startActivityForResult(i, RC_WAITING_ROOM); 
       } 
      } 


      @Override 
      public void onLeftRoom(int i, String s) { 
       if (getContext()!=null) { 
    // remove the flag that keeps the screen on 
        mRoomId = null; 
       } 
      } 

      @Override 
      public void onRoomConnected(int statusCode, Room room) { 
       if (getContext()!=null) { 
        roomCreatorId = room.getCreatorId(); 
        mRoomId = room.getRoomId(); 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
    //   setCurrentPlayerParticipantId(); 
        if (statusCode != GamesStatusCodes.STATUS_OK) { 
         // let screen go to sleep 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

         // show error message, return to main screen. 
         Toast.makeText(getContext(), "Error connecting to room.", Toast.LENGTH_SHORT).show(); 
         showRoomUi(); 
        } 
       } 
      } 

     }; 


     private RoomStatusUpdateListener roomStatusUpdateListener = new RoomStatusUpdateListener() { 

      @Override 
      public void onRoomConnecting(Room room) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
       } 
      } 

      @Override 
      public void onRoomAutoMatching(Room room) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
       } 
      } 

      @Override 
      public void onPeerInvitedToRoom(Room room, List<String> list) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
       } 
      } 

      @Override 
      public void onPeerJoined(Room room, List<String> list) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
       } 
      } 

      @Override 
      public void onConnectedToRoom(Room room) { 
       if (getContext()!=null) { 
        mMyId = room.getParticipantId(Games.Players.getCurrentPlayerId(((MainActivity) getActivity()).getGoogleApiClient())); 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
       } 
      } 

      @Override 
      public void onDisconnectedFromRoom(Room room) { 

       if (getContext()!=null) { 
    // leave the room 
        Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId()); 

        // clear the flag that keeps the screen on 
        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

        // show error message and return to main screen 
        Toast.makeText(getContext(), "Network error.", Toast.LENGTH_SHORT).show(); 

        showRoomUi(); 
       } 

      } 

      @Override 
      public void onP2PConnected(String s) { 
      } 

      @Override 
      public void onP2PDisconnected(String s) { 
      } 

      @Override 
      public void onPeersConnected(Room room, List<String> peers) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
        if (mPlaying) { 
         // add new player to an ongoing game 
        } else if (shouldStartGame(room)) { 
         // start game! 
        } 
       } 
      } 

      @Override 
      public void onPeersDisconnected(Room room, List<String> peers) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
        if (mPlaying) { 
         // do game-specific handling of this -- remove player's avatar 
         // from the screen, etc. If not enough players are left for 
         // the game to go on, end the game and leave the room. 
        } 
        else if (shouldCancelGame(room)) { 
         // cancel the game 
         Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId()); 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
         showRoomUi(); 
        } 
       } 
      } 

      @Override 
      public void onPeerLeft(Room room, List<String> peers) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
        // peer left -- see if game should be canceled 
        if (!mPlaying && shouldCancelGame(room)) { 
         Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId()); 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
         showRoomUi(); 
        } 
       } 
      } 

      @Override 
      public void onPeerDeclined(Room room, List<String> peers) { 
       if (getContext()!=null) { 
        mParticipants.clear(); 
        mParticipants.addAll(room.getParticipants()); 
        // peer declined invitation -- see if game should be canceled 
        if (!mPlaying && shouldCancelGame(room)) { 
         Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId()); 
         getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
         showRoomUi(); 
        } 
       } 
      } 

     }; 

     private RealTimeMessageReceivedListener realTimeMessageReceivedListener = new RealTimeMessageReceivedListener() { 
      @Override 
      public void onRealTimeMessageReceived(RealTimeMessage realTimeMessage) { 
       if (getContext()!=null) { 
        if (realTimeMessage.isReliable()) { 
         handleReliableMessages(realTimeMessage.getMessageData()); 
        } 
       } 
      } 
     }; 

任何幫助表示讚賞。謝謝。

回答

0

AFAIK,這就是API的設計和工作原理。

正如在documentation中所提到的,每當遊戲進入後臺時,您都應該離開活動房間。

對於額外的見解(從Bruno Oliveira),您可能希望看到這些相關的SO職位:

雖然,你也可以選擇嘗試這種suggested solution。嘗試編輯BaseGameActivity.onStop()並刪除gamehelper.onStop()。有了這個,gamesclient將只在onDestroy停止。這可能是一個不錯的選擇,但我沒有真正嘗試過。

+0

移動gameHelper.onStop to on destroy爲我工作。 –

相關問題