Multiplayer - Handle player join and player leave event
Preparation
First of all create a new global variable called isGameRunning with default value 0 (zero). This variable is set to 1 whenever a round begins. Players start moving, stopping, shooting and then the round is over. During this time new players that join the game shall not create objects and interrupt the game.
Create player objects on one authoritative player locally (Master Client)
To achieve this behavior we gonna make use of the On actor join event. It is important to say that this event is triggered for every player in the room INCLUDING the one who's joining it. So first add the event from Photon. The next step is to check if the actual local player receiving this event is the Master Client. If this is true the Master Client is gonna collect information about all the players actually playing and put their goto (x, y), shoot (x, y) positions and the spawn status (1 or 0) in this case 1 into our JoinDataDictionary object with their unique id. The new player gets a new random position in the world and we check if our global variable isGameRunning is set to 0 (zero) with the expression isGameRunning = 0. The spawn status is important to tell the new client that the game is actually running and he is not allowed to spawn his own player object as well as for the others not to spawn the new player while the round is running. We encode our JoinDataDictionary into a JSON String and send it to all players by adding a Raise event action after setting up the dictionary.
The Raise event explained
The Raise event action is the main method to be used to communicate between the players. You can define a Code number to identify which event should be trigger on the peoples game when they receive a raised event. The Data row is important to define which data should be send to the other players. What we do here is sending a JSON encoded string. You can also leave this at 0 to only send the event and trigger it on other (could be including you) clients. The InterestGroup is not from interest (haha) here. This can be used for example if you create an MMORPG and have different zones where only a certain amount of people should receive this event that fall into the area of interest of this event (eg: is the event visible in my viewport? gimme data! not? well then i don't care). The Cache can be used to cache events for players who join the game. I rarely use this event since it leads to problems often if you don't care much about what is cached here. What could be useful is for example the latest statistics that we sent to players to be cached so new players will directly be informed about the actual state of the game. Receivers is another important option. You can choose between Others which includes all players except you, All which includes you and all the others, and Master Client which will send the event to Blizzard Entertainment... kidding. Like the name says it is send to the actual Master Client. Only the option TargetActors can overwrite this option by defining a comma separated string with the id's of the players who should receive the event. WebFoward is to forward the set properties to a WebHook, defined for you APP id (i copied this from the API docs since i don't have a clue what it really means, me shall be forgiven).
Finally in case if the local player is NOT the joining player we just put a message into our log that someone joined (This messages includes the Master Client since he is just a usual player too). Your event sheet should look like this:
Destroy player data and objects of the leaving player
This event is a bit simpler but very important for us. Whenever a player leaves the game this event is triggered for all players in the room. Once for each player staying in the room and X-times for the player leaving the room. That's because for the leaving player the other players are disconnecting as well. The leaving player will be ignored for this event by checking if the meIsExiting variable is set to 1. This variable will only be set to 1 when the player presses the key button: 2. When leaving the website or refreshing the page this event is trivial for the leaving player since the whole game restarts for him anyway.
Go ahead and add the On actor leave event. Add another condition checking that meIsExiting is set to 0. First let's display a message telling that someone left the game. Now we gonna clear the WalkShootDictionary and the JoinDataDictionary because we do no longer need the information about this player. We try to find the leaving players object to destroy it as well. All this is done by gathering the Photon.ActorNr coming from the events data. As a last step we add a Wait 0 action to wait until the players object is destroyed. After that we count the amount of players and call the ResetRound function (will be created later) if only one player is left. This is in case of Player 1 sets his two positions for goto and shoot. Player 2 and 3 now decide to leave the game so Player 1 is alone. In the ResetRound function we gonna remove the markers for Player 1 to give him another chance to set a position when new players join again. This one of the "damn i really need to think about every single s* in multiplayer, man :(" things.