Adding an event queue in the GameScene.

Events are processed only in the 'update' method.
We hope this will solve a number of null pointer errors. See #194
This commit is contained in:
David Négrier 2020-06-19 18:18:43 +02:00
parent 8467712737
commit 2b820c7d56
3 changed files with 131 additions and 10 deletions

View file

@ -22,6 +22,7 @@
"@types/simple-peer": "^9.6.0",
"@types/socket.io-client": "^1.4.32",
"phaser": "^3.22.0",
"queue-typescript": "^1.0.1",
"simple-peer": "^9.6.2",
"socket.io-client": "^2.3.0"
},

View file

@ -22,6 +22,8 @@ import {PlayerMovement} from "./PlayerMovement";
import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
import {RemotePlayer} from "../Entity/RemotePlayer";
import GameObject = Phaser.GameObjects.GameObject;
import { Queue } from 'queue-typescript';
export enum Textures {
Player = "male1"
@ -32,6 +34,36 @@ export interface GameSceneInitInterface {
startLayerName: string|undefined
}
interface InitUserPositionEventInterface {
type: 'InitUserPositionEvent'
event: MessageUserPositionInterface[]
}
interface AddPlayerEventInterface {
type: 'AddPlayerEvent'
event: AddPlayerInterface
}
interface RemovePlayerEventInterface {
type: 'RemovePlayerEvent'
userId: string
}
interface UserMovedEventInterface {
type: 'UserMovedEvent'
event: MessageUserMovedInterface
}
interface GroupCreatedUpdatedEventInterface {
type: 'GroupCreatedUpdatedEvent'
event: GroupCreatedUpdatedMessageInterface
}
interface DeleteGroupEventInterface {
type: 'DeleteGroupEvent'
groupId: string
}
export class GameScene extends Phaser.Scene {
GameManager : GameManager;
Terrains : Array<Phaser.Tilemaps.Tileset>;
@ -46,6 +78,7 @@ export class GameScene extends Phaser.Scene {
startX: number;
startY: number;
circleTexture: CanvasTexture;
pendingEvents: Queue<InitUserPositionEventInterface|AddPlayerEventInterface|RemovePlayerEventInterface|UserMovedEventInterface|GroupCreatedUpdatedEventInterface|DeleteGroupEventInterface> = new Queue<InitUserPositionEventInterface|AddPlayerEventInterface|RemovePlayerEventInterface|UserMovedEventInterface|GroupCreatedUpdatedEventInterface|DeleteGroupEventInterface>();
private initPosition: PositionInterface|null = null;
private playersPositionInterpolator = new PlayersPositionInterpolator();
@ -437,13 +470,13 @@ export class GameScene extends Phaser.Scene {
EventToClickOnTile(){
// debug code to get a tile properties by clicking on it
this.input.on("pointerdown", (pointer: Phaser.Input.Pointer)=>{
/*this.input.on("pointerdown", (pointer: Phaser.Input.Pointer)=>{
//pixel position toz tile position
const tile = this.Map.getTileAt(this.Map.worldToTileX(pointer.worldX), this.Map.worldToTileY(pointer.worldY));
if(tile){
this.CurrentPlayer.say("Your touch " + tile.layer.name);
}
});
});*/
}
/**
@ -454,6 +487,31 @@ export class GameScene extends Phaser.Scene {
this.currentTick = time;
this.CurrentPlayer.moveUser(delta);
// Let's handle all events
let event = null;
while (event = this.pendingEvents.dequeue()) {
switch (event.type) {
case "InitUserPositionEvent":
this.doInitUsersPosition(event.event);
break;
case "AddPlayerEvent":
this.doAddPlayer(event.event);
break;
case "RemovePlayerEvent":
this.doRemovePlayer(event.userId);
break;
case "UserMovedEvent":
this.doUpdatePlayerPosition(event.event);
break;
case "GroupCreatedUpdatedEvent":
this.doShareGroupPosition(event.event);
break;
case "DeleteGroupEvent":
this.doDeleteGroup(event.groupId);
break;
}
}
// Let's move all users
const updatedPlayersPositions = this.playersPositionInterpolator.getUpdatedPositions(time);
updatedPlayersPositions.forEach((moveEvent: HasMovedEvent, userId: string) => {
@ -488,12 +546,21 @@ export class GameScene extends Phaser.Scene {
}
}
/**
* Called by the connexion when the full list of user position is received.
*/
public initUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
if(!this.CurrentPlayer){
console.error('Cannot initiate users list because map is not loaded yet')
return;
}
this.pendingEvents.enqueue({
type: "InitUserPositionEvent",
event: usersPosition
});
}
/**
* Put all the players on the map on map load.
*/
private doInitUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
const currentPlayerId = this.GameManager.getPlayerId();
// clean map
@ -512,10 +579,20 @@ export class GameScene extends Phaser.Scene {
});
}
/**
* Called by the connexion when a new player arrives on a map
*/
public addPlayer(addPlayerData : AddPlayerInterface) : void {
this.pendingEvents.enqueue({
type: "AddPlayerEvent",
event: addPlayerData
});
}
/**
* Create new player
*/
public addPlayer(addPlayerData : AddPlayerInterface) : void{
private doAddPlayer(addPlayerData : AddPlayerInterface) : void {
//check if exist player, if exist, move position
if(this.MapPlayersByKey.has(addPlayerData.userId)){
this.updatePlayerPosition({
@ -545,8 +622,18 @@ export class GameScene extends Phaser.Scene {
});*/
}
/**
* Called by the connexion when a player is removed from the map
*/
public removePlayer(userId: string) {
console.log('Removing player ', userId)
this.pendingEvents.enqueue({
type: "RemovePlayerEvent",
userId
});
}
private doRemovePlayer(userId: string) {
//console.log('Removing player ', userId)
const player = this.MapPlayersByKey.get(userId);
if (player === undefined) {
console.error('Cannot find user with id ', userId);
@ -558,7 +645,14 @@ export class GameScene extends Phaser.Scene {
this.playersPositionInterpolator.removePlayer(userId);
}
updatePlayerPosition(message: MessageUserMovedInterface): void {
public updatePlayerPosition(message: MessageUserMovedInterface): void {
this.pendingEvents.enqueue({
type: "UserMovedEvent",
event: message
});
}
private doUpdatePlayerPosition(message: MessageUserMovedInterface): void {
const player : RemotePlayer | undefined = this.MapPlayersByKey.get(message.userId);
if (player === undefined) {
throw new Error('Cannot find player with ID "' + message.userId +'"');
@ -570,7 +664,14 @@ export class GameScene extends Phaser.Scene {
this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement);
}
shareGroupPosition(groupPositionMessage: GroupCreatedUpdatedMessageInterface) {
public shareGroupPosition(groupPositionMessage: GroupCreatedUpdatedMessageInterface) {
this.pendingEvents.enqueue({
type: "GroupCreatedUpdatedEvent",
event: groupPositionMessage
});
}
private doShareGroupPosition(groupPositionMessage: GroupCreatedUpdatedMessageInterface) {
const groupId = groupPositionMessage.groupId;
const group = this.groups.get(groupId);
@ -590,6 +691,13 @@ export class GameScene extends Phaser.Scene {
}
deleteGroup(groupId: string): void {
this.pendingEvents.enqueue({
type: "DeleteGroupEvent",
groupId
});
}
doDeleteGroup(groupId: string): void {
const group = this.groups.get(groupId);
if(!group){
return;

View file

@ -2602,6 +2602,11 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
linked-list-typescript@^1.0.11:
version "1.0.15"
resolved "https://registry.yarnpkg.com/linked-list-typescript/-/linked-list-typescript-1.0.15.tgz#faeed93cf9203f102e2158c29edcddda320abe82"
integrity sha512-RIyUu9lnJIyIaMe63O7/aFv/T2v3KsMFuXMBbUQCHX+cgtGro86ETDj5ed0a8gQL2+DFjzYYsgVG4I36/cUwgw==
loader-runner@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
@ -3400,6 +3405,13 @@ queue-microtask@^1.1.0:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.1.2.tgz#139bf8186db0c545017ec66c2664ac646d5c571e"
integrity sha512-F9wwNePtXrzZenAB3ax0Y8TSKGvuB7Qw16J30hspEUTbfUM+H827XyN3rlpwhVmtm5wuZtbKIHjOnwDn7MUxWQ==
queue-typescript@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/queue-typescript/-/queue-typescript-1.0.1.tgz#2d7842fc3b3e0e3f33d077887a8f2a5bb0baf460"
integrity sha512-tkK08uPfmpPl0cX1WRSU3EoNb/T5zSoZPGkkpfGX4E8QayWvEmLS2cI3pFngNPkNTCU5pCDQ1IwlzN0L5gdFPg==
dependencies:
linked-list-typescript "^1.0.11"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.3, randombytes@^2.0.5:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"