I have implemented the multi player feature in my game. when I click the "Invite friends" button, I am redirected the the screen to invite my friends. The invitation goes and by the time my friends respond, if I navigate away from the screen that shows the list of friends, then which override is called when the invitation that I sent is accepted.
I wanted to go to that override and start my game. Else the person who accepted the game starts the game, but i am not able to start my game.
The RoomUpdateListener interface defines the callbacks for client state changes.
You might want to look at the ButtonClicker sample which is a real-time multiplayer game.
The basic flow is:
1. Build the room including the invited players and call Games.RealTimeMultiplayer.create(mGoogleApiClient, rtmConfigBuilder.build());
Once the room is created, [onRoomCreated](https://developers.google.com/android/reference/com/google/android/gms/games/multiplayer/realtime/RoomUpdateListener.html#onRoomCreated(int, com.google.android.gms.games.multiplayer.realtime.Room)) is called, indicating if the room was created successfully. In this method is a good time to show the waiting room UI until all the players are connected. The waiting room is shown by getting the intent and starting it. See [getWaitingRoomIntent](https://developers.google.com/android/reference/com/google/android/gms/games/multiplayer/realtime/RealTimeMultiplayer.html#getWaitingRoomIntent(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.games.multiplayer.realtime.Room, int))
Once all the players are connected, the waiting room activity will finish, and onActivityResult will be called. From there you can start your gameplay.
If you don't want to use the waiting room, you can implement the [RoomStatusUpdateListener.onPeersConnected](https://developers.google.com/android/reference/com/google/android/gms/games/multiplayer/realtime/RoomStatusUpdateListener.html#onPeersConnected(com.google.android.gms.games.multiplayer.realtime.Room, java.util.List)) and related methods to determine when to start playing.
Related
Since lengthly operations can't be done inside onBindSlice(), I am fetching data from server from onSlicePinned() method and then showing it in slices. But I can't understand when is this function called.
I thought it would be called every time we fresh start Assistant (i.e. starting Assistant after killing it). It is working while testing on Slice-Viewer app, every time i kill slice viewer and start again then onSlicePinned() is called along with onSliceBind(), but not in case of Google Assistant. So is this a bug or should be the way it is?
And if this is how onSlicePinned() should work, then is there any way i can fetch data every time onBindSlice() is called after starting app.
To load content from a server into a Slice you should follow the delayed content best practices here:
https://developer.android.com/guide/slices/templates#delayed_content
The tl;dr is, you should return something immediately, then go off and load/process your content, once the content is ready, call notifyChange() which will result in onBindSlice() being called again where you can return the Slice with the new content.
The question might seem quite odd, but I couldn't quite find an answer perusing the API documentation.
What is the purpose of the participant's status?
Is it possible to manually set the status to finished, so that the active games list would show said game for participant to be finished, rather than calling finishMatch()?
The scenario in mind would involve a game with more than two players. Say player A finishes the game, his status should be set to "FINISHED", while player B and C would still play, until either one of them finishes, which would trigger the end of the game.
Usually Participant status could be shown in UI. Have you found any API which allows you to change Participant status directly? I think to change it to FINISHED you need to call finishMatch().
I'm creating a multiplayer tic tac toe game and it works for the most part, but when it's time to rematch I'm getting less than desirable functionality.
So originally I used the same implementation of Games.TurnBasedMultiplayer.rematch as the TBMPSkeleton sample project. Basically after calling Games.TurnBasedMultiplayer.finish, I check whether or not the match can be rematched by calling match.canRematch() during the subsequent callback. If match.canRematch() returns true, then I call Games.TurnBasedMultiplayer.rematch. Both, when I call finish and when I call rematch, the onTurnBasedMatchReceived callback gets called on the opposing client device and from there I check the match object for the rematchId. If it's not null, then I reset the game.
The problem I'm having is that, after the winning player has requested a rematch and then takes his/her turn, the opposing player receives an invite to the new match, but the onTurnBasedMatchReceived callback doesn't get called. I don't want the losing player to have to leave my game in order to accept or dismiss the invitation.
So is there a way to have my app handle the invitation notification without forcing the player to have to open the system's notification gui? Should I scrap the turn based multiplayer API in favor of it's real-time counterpart?
I realized that I didn't have a listener registered for invitations. After registering one, I was able to achieve my desired functionality. I'm relieved that it's working, but it would have been nice to notice that much sooner...
When I call takeTurn(), I will get a call to onTurnBasedMatchUpdated() on the same device that called takeTurn(). But I will not get the call to onTurnBasedMatchUpdated() on the other device that is waiting for its turn. Instead, Game Services will alert the device that it is their turn to play in the notification bar. I was hoping that, if the device remained in-game, that the game would continue to catch onTurnBasedMatchUpdated() when the other player calls takeTurn(). So how do I prevent the notification and simply handle the call?
As Mannan pointed out, it is onTurnBasedMatchReceived() that is called when an opponent takes their turn. It is also called when an opponent connects to your match for the first time. While this function is required to be defined for an "OnTurnBasedMatchUpdatedListener" it is not actually called for that listener. You must ALSO implement "OnTurnBasedMatchUpdateReceivedListener". Further, after implementing it, you must then REGISTER it (I do so after signing in) with getGamesClient().registerMatchUpdateListener(this). Seriously though, where is all the documentation for this? Am I missing something?
When a player's turn is arrived, following callback is called,
onTurnBasedMatchReceived(TurnBasedMatch match)
and in this callback, you can get info about the turn and its data from match parameter.
I still dont know why onTurnBasedMatchUpdated() is not called.
I'm testing my multiplayer implementation using Google Play Game Services with 4 distinct devices. Everything is working fine but two things:
onInvitationReceived sometimes not firing (only sometimes ¿?)
Only in one device (Galaxy Ace), and only when is it who receives the invitation, then both players (inviter and invited) keeps waiting in the waiting room, so onActivity result is never fired. In waiting room I read "Invitation accepted" for both players, but it never closes...
Any advices?
Usually, when listeners are not firing, it's because they are getting garbage-collected. This happens if you use an anonymous listener (new Listener() { .... }). To avoid this, make your Activity implement the desired listener interface, and pass in this as the listener to GamesClient methods.
For more info, take a look at our troubleshooting guide, in the "Listeners not Called" section.
As for onActivityResult, if you are overring BaseGameActivity, make sure you are keeping the super.onActivityResult(...) line on your implementation of onActivityResult.