Changing the "Point" notion to add a notion of "moving" in addition to the notion...
authorDavid Négrier <d.negrier@thecodingmachine.com>
Fri, 22 May 2020 20:59:43 +0000 (22:59 +0200)
committerDavid Négrier <d.negrier@thecodingmachine.com>
Fri, 22 May 2020 21:04:45 +0000 (23:04 +0200)
Also, refactoring JOIN_ROOM event to add complete position.

back/src/Controller/IoSocketController.ts
back/src/Model/Websocket/MessageUserJoined.ts
back/src/Model/Websocket/MessageUserPosition.ts
front/src/Connexion.ts
front/src/Phaser/Entity/PlayableCaracter.ts
front/src/Phaser/Game/GameManager.ts
front/src/Phaser/Game/GameScene.ts
front/src/Phaser/Player/Animation.ts
front/src/Phaser/Player/Player.ts

index 292db31ff8dc6940dccfa5422ef897b7e88d2d12..8332d7826fdc59f9c0eac6424c3a448ac9f4aaa7 100644 (file)
@@ -89,12 +89,19 @@ export class IoSocketController {
                         x: user x position on map
                         y: user y position on map
             */
-            socket.on(SockerIoEvent.JOIN_ROOM, (roomId: any, answerFn): void => {
+            socket.on(SockerIoEvent.JOIN_ROOM, (message: any, answerFn): void => {
                 try {
+                    let roomId = message.roomId;
+
                     if (typeof(roomId) !== 'string') {
                         socket.emit(SockerIoEvent.MESSAGE_ERROR, {message: 'Expected roomId as a string.'});
                         return;
                     }
+                    let position = this.hydratePositionReceive(message.position);
+                    if (position instanceof Error) {
+                        socket.emit(SockerIoEvent.MESSAGE_ERROR, {message: position.message});
+                        return;
+                    }
 
                     let Client = (socket as ExSocketInterface);
 
@@ -106,12 +113,12 @@ export class IoSocketController {
                     this.leaveRoom(Client);
 
                     //join new previous room
-                    let world = this.joinRoom(Client, roomId);
+                    let world = this.joinRoom(Client, roomId, position);
 
                     //add function to refresh position user in real time.
                     //this.refreshUserPosition(Client);
 
-                    let messageUserJoined = new MessageUserJoined(Client.id, Client.name, Client.character);
+                    let messageUserJoined = new MessageUserJoined(Client.id, Client.name, Client.character, Client.position);
 
                     socket.to(roomId).emit(SockerIoEvent.JOIN_ROOM, messageUserJoined);
 
@@ -140,16 +147,13 @@ export class IoSocketController {
                     // sending to all clients in room except sender
                     Client.position = position;
 
-                    //refresh position of all user in all rooms in real time
-                    //this.refreshUserPosition(Client);
-
                     // update position in the world
                     let world = this.Worlds.get(Client.roomId);
                     if (!world) {
                         console.error("Could not find world with id '", Client.roomId, "'");
                         return;
                     }
-                    world.updatePosition(Client, Client.position);
+                    world.updatePosition(Client, position);
 
                     socket.to(Client.roomId).emit(SockerIoEvent.USER_MOVED, new MessageUserMoved(Client.id, Client.position));
                 } catch (e) {
@@ -182,10 +186,6 @@ export class IoSocketController {
                 try {
                     let Client = (socket as ExSocketInterface);
 
-                    if (Client.roomId) {
-                        socket.to(Client.roomId).emit(SockerIoEvent.USER_LEFT, socket.id);
-                    }
-
                     //leave room
                     this.leaveRoom(Client);
 
@@ -238,11 +238,11 @@ export class IoSocketController {
         }
     }
 
-    private joinRoom(Client : ExSocketInterface, roomId: string): World {
+    private joinRoom(Client : ExSocketInterface, roomId: string, position: Point): World {
         //join user in room
         Client.join(roomId);
         Client.roomId = roomId;
-        Client.position = new Point(-1000, -1000);
+        Client.position = position;
 
         //check and create new world for a room
         let world = this.Worlds.get(roomId)
@@ -311,10 +311,10 @@ export class IoSocketController {
     //Hydrate and manage error
     hydratePositionReceive(message: any): Point | Error {
         try {
-            if (!message.x || !message.y || !message.direction) {
+            if (!message.x || !message.y || !message.direction || message.moving === undefined) {
                 return new Error("invalid point message sent");
             }
-            return new Point(message.x, message.y, message.direction);
+            return new Point(message.x, message.y, message.direction, message.moving);
         } catch (err) {
             //TODO log error
             return new Error(err);
index e12f5dc3a3ef5f504b97135564c70fe020efc107..fff9db5d1f1cd09e01bf714c8cc34cae7b59e672 100644 (file)
@@ -1,5 +1,7 @@
+import {Point} from "./MessageUserPosition";
+import {PointInterface} from "_Model/Websocket/PointInterface";
 
 export class MessageUserJoined {
-    constructor(public userId: string, public name: string, public character: string) {
+    constructor(public userId: string, public name: string, public character: string, public position: PointInterface) {
     }
 }
index 613e47e69783de07822e98c9dfbbd2fd3a55c75c..ed604940745e00eb351aec173b4659c31d691060 100644 (file)
@@ -1,7 +1,7 @@
 import {PointInterface} from "./PointInterface";
 
 export class Point implements PointInterface{
-    constructor(public x : number, public y : number, public direction : string = "none") {
+    constructor(public x : number, public y : number, public direction : string = "none", public moving : boolean = false) {
     }
 }
 
index e1a35ec73c166cd367494c53bf494ecd0a98ef98..1b9631296b2ac5c5b6c31a4380521b74040dbd2d 100644 (file)
@@ -6,6 +6,7 @@ import {SetPlayerDetailsMessage} from "./Messages/SetPlayerDetailsMessage";
 
 const SocketIo = require('socket.io-client');
 import Socket = SocketIOClient.Socket;
+import {PlayerAnimationNames} from "./Phaser/Player/Animation";
 
 
 enum EventMessage{
@@ -42,20 +43,14 @@ export interface PointInterface {
     x: number;
     y: number;
     direction : string;
+    moving: boolean;
 }
 
 export class Point implements PointInterface{
-    x: number;
-    y: number;
-    direction : string;
-
-    constructor(x : number, y : number, direction : string = "none") {
+    constructor(public x : number, public y : number, public direction : string = PlayerAnimationNames.WalkDown, public moving : boolean = false) {
         if(x  === null || y === null){
             throw Error("position x and y cannot be null");
         }
-        this.x = x;
-        this.y = y;
-        this.direction = direction;
     }
 }
 
@@ -84,6 +79,7 @@ export interface MessageUserJoined {
     userId: string;
     name: string;
     character: string;
+    position: PointInterface
 }
 
 export interface ListMessageUserPositionInterface {
@@ -104,7 +100,8 @@ class ListMessageUserPosition {
                 new Point(
                     userPosition.position.x,
                     userPosition.position.y,
-                    userPosition.position.direction
+                    userPosition.position.direction,
+                    userPosition.position.moving
                 ),
                 userPosition.name,
                 userPosition.character
@@ -133,9 +130,9 @@ export interface ConnexionInterface {
 
     loadMaps(): Promise<any>;
 
-    joinARoom(roomId: string, character: string): void;
+    joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void;
 
-    sharePosition(x: number, y: number, direction: string, roomId: string, character: string): void;
+    sharePosition(x: number, y: number, direction: string, moving: boolean): void;
 
     positionOfAllUser(): void;
 
@@ -215,20 +212,23 @@ export class Connexion implements ConnexionInterface {
             //if try to reconnect with last position
             if(this.lastRoom) {
                 //join the room
-                this.joinARoom(
-                    this.lastRoom
-                );
+                this.joinARoom(this.lastRoom,
+                    this.lastPositionShared ? this.lastPositionShared.x : 0,
+                    this.lastPositionShared ? this.lastPositionShared.y : 0,
+                    this.lastPositionShared ? this.lastPositionShared.direction : PlayerAnimationNames.WalkDown,
+                    this.lastPositionShared ? this.lastPositionShared.moving : false);
             }
 
-            if(this.lastPositionShared) {
+            /*if(this.lastPositionShared) {
 
                 //share your first position
                 this.sharePosition(
                     this.lastPositionShared ? this.lastPositionShared.x : 0,
                     this.lastPositionShared ? this.lastPositionShared.y : 0,
-                    this.lastPositionShared.direction
+                    this.lastPositionShared.direction,
+                    this.lastPositionShared.moving
                 );
-            }
+            }*/
 
             resolve(this);
         });
@@ -245,31 +245,18 @@ export class Connexion implements ConnexionInterface {
             });
     }
 
-    /**
-     *
-     * @param roomId
-     * @param character
-     */
-    joinARoom(roomId: string): void {
-        this.socket.emit(EventMessage.JOIN_ROOM, roomId, (userPositions: MessageUserPositionInterface[]) => {
+    joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void {
+        this.socket.emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => {
             this.GameManager.initUsersPosition(userPositions);
         });
         this.lastRoom = roomId;
     }
 
-    /**
-     *
-     * @param x
-     * @param y
-     * @param character
-     * @param roomId
-     * @param direction
-     */
-    sharePosition(x : number, y : number, direction : string = "none") : void{
+    sharePosition(x : number, y : number, direction : string, moving: boolean) : void{
         if(!this.socket){
             return;
         }
-        let point = new Point(x, y, direction);
+        let point = new Point(x, y, direction, moving);
         this.lastPositionShared = point;
         this.socket.emit(EventMessage.USER_POSITION, point);
     }
@@ -279,11 +266,11 @@ export class Connexion implements ConnexionInterface {
      * [
      * {
      *       userId: <string>,
-     *       roomId: <string>,
      *       position: {
      *           x : <number>,
      *           y : <number>,
-     *           direction: <string>
+     *           direction: <string>,
+     *           moving: <bool>
      *       }
      *     },
      * ...
index e126dbb96b292cc5042be96a0f99c68c3ffaacb9..826bfc6a91dfa125cf9b8cda73436d46633416d0 100644 (file)
@@ -26,7 +26,7 @@ export const PLAYER_RESOURCES: Array<any> = [
 
 export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite {
     private bubble: SpeechBubble;
-    private playerName: BitmapText;
+    private readonly playerName: BitmapText;
     public PlayerValue: string;
     public PlayerTexture: string;
 
index fcb386d1fe6d2984b8aebead756adb143880e1a2..6b848aa1aa1dbb908be443346a5c594da0b3340e 100644 (file)
@@ -16,6 +16,7 @@ export enum StatusGameManagerEnum {
 
 export interface HasMovedEvent {
     direction: string;
+    moving: boolean;
     x: number;
     y: number;
 }
@@ -71,8 +72,8 @@ export class GameManager {
         this.status = StatusGameManagerEnum.CURRENT_USER_CREATED;
     }
 
-    joinRoom(sceneKey : string){
-        this.ConnexionInstance.joinARoom(sceneKey);
+    joinRoom(sceneKey: string, startX: number, startY: number, direction: string, moving: boolean){
+        this.ConnexionInstance.joinARoom(sceneKey, startX, startY, direction, moving);
     }
 
     onUserJoins(message: MessageUserJoined): void {
@@ -80,7 +81,7 @@ export class GameManager {
             userId: message.userId,
             character: message.character,
             name: message.name,
-            position: new Point(-1000, -1000)
+            position: message.position
         }
         this.currentGameScene.addPlayer(userMessage);
     }
@@ -159,7 +160,7 @@ export class GameManager {
     }
 
     pushPlayerPosition(event: HasMovedEvent) {
-        this.ConnexionInstance.sharePosition(event.x, event.y, event.direction);
+        this.ConnexionInstance.sharePosition(event.x, event.y, event.direction, event.moving);
     }
 
     loadMap(mapUrl: string, scene: ScenePlugin): string {
index 0b0d08ed24e1a5875f53e1c90abb19c1e2e4a95e..4a003b3340545cdaceb38eca69aa5fdf15a05a33 100644 (file)
@@ -13,6 +13,7 @@ import Texture = Phaser.Textures.Texture;
 import Sprite = Phaser.GameObjects.Sprite;
 import CanvasTexture = Phaser.Textures.CanvasTexture;
 import {AddPlayerInterface} from "./AddPlayerInterface";
+import {PlayerAnimationNames} from "../Player/Animation";
 
 export enum Textures {
     Player = "male1"
@@ -273,16 +274,17 @@ export class GameScene extends Phaser.Scene {
             this.startX,
             this.startY,
             this.GameManager.getPlayerName(),
-            this.GameManager.getCharacterSelected()
+            this.GameManager.getCharacterSelected(),
+            PlayerAnimationNames.WalkDown,
+            false
         );
-        this.CurrentPlayer.initAnimation();
 
         //create collision
         this.createCollisionWithPlayer();
         this.createCollisionObject();
 
         //join room
-        this.GameManager.joinRoom(this.scene.key);
+        this.GameManager.joinRoom(this.scene.key, this.startX, this.startY, PlayerAnimationNames.WalkDown, false);
 
         //listen event to share position of user
         this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
@@ -415,9 +417,10 @@ export class GameScene extends Phaser.Scene {
             addPlayerData.position.x,
             addPlayerData.position.y,
             addPlayerData.name,
-            addPlayerData.character
+            addPlayerData.character,
+            addPlayerData.position.direction,
+            addPlayerData.position.moving
         );
-        player.initAnimation();
         this.MapPlayers.add(player);
         this.MapPlayersByKey.set(player.userId, player);
         player.updatePosition(addPlayerData.position);
@@ -429,6 +432,7 @@ export class GameScene extends Phaser.Scene {
     }
 
     public removePlayer(userId: string) {
+        console.log('Removing player ', userId)
         let player = this.MapPlayersByKey.get(userId);
         if (player === undefined) {
             console.error('Cannot find user with id ', userId);
index 332c862d7b43fae4859c84ff25bcc940362e9bc9..10cee1e89804d00097f523b5acf366398ecbe6d9 100644 (file)
@@ -14,7 +14,6 @@ export enum PlayerAnimationNames {
     WalkLeft = 'left',
     WalkUp = 'up',
     WalkRight = 'right',
-    None = 'none',
 }
 
 export const getPlayerAnimations = (name: string = Textures.Player): AnimationData[] => {
@@ -48,11 +47,3 @@ export const getPlayerAnimations = (name: string = Textures.Player): AnimationDa
         repeat: -1
     }];
 };
-
-export const playAnimation = (Player : Phaser.GameObjects.Sprite, direction : string) => {
-    if (direction !== PlayerAnimationNames.None && (!Player.anims.currentAnim || Player.anims.currentAnim.key !== direction)) {
-        Player.anims.play(direction);
-    } else if (direction === PlayerAnimationNames.None && Player.anims.currentAnim) {
-        Player.anims.stop();
-    }
-}
index 26acb1a3d5baf06d4d2e5ff524917b318c0b746d..850be5633350b208fd0ebaa32e11a288a1b73fcf 100644 (file)
@@ -1,4 +1,4 @@
-import {getPlayerAnimations, playAnimation, PlayerAnimationNames} from "./Animation";
+import {getPlayerAnimations, PlayerAnimationNames} from "./Animation";
 import {GameScene, Textures} from "../Game/GameScene";
 import {MessageUserPositionInterface, PointInterface} from "../../Connexion";
 import {ActiveEventList, UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
@@ -7,14 +7,12 @@ import {PlayableCaracter} from "../Entity/PlayableCaracter";
 
 export const hasMovedEventName = "hasMoved";
 export interface CurrentGamerInterface extends PlayableCaracter{
-    initAnimation() : void;
     moveUser(delta: number) : void;
     say(text : string) : void;
 }
 
 export interface GamerInterface extends PlayableCaracter{
     userId : string;
-    initAnimation() : void;
     updatePosition(position: PointInterface): void;
     say(text : string) : void;
 }
@@ -22,7 +20,8 @@ export interface GamerInterface extends PlayableCaracter{
 export class Player extends PlayableCaracter implements CurrentGamerInterface, GamerInterface {
     userId: string;
     userInputManager: UserInputManager;
-    previousMove: string;
+    previousDirection: string;
+    wasMoving: boolean;
 
     constructor(
         userId: string,
@@ -30,7 +29,9 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
         x: number,
         y: number,
         name: string,
-        PlayerTexture: string = Textures.Player
+        PlayerTexture: string,
+        direction: string,
+        moving: boolean
     ) {
         super(Scene, x, y, PlayerTexture, name, 1);
 
@@ -42,9 +43,18 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
 
         //the current player model should be push away by other players to prevent conflict
         this.setImmovable(false);
+        this.initAnimation();
+
+        console.warn("Start direction for added player ", direction)
+        console.warn("Position ", x, y)
+        /*this.play(`${PlayerTexture}-${direction}`, true);
+        if (!moving) {
+            this.stop();
+        }*/
+        this.playAnimation(direction, moving);
     }
 
-    initAnimation(): void {
+    private initAnimation(): void {
         getPlayerAnimations(this.PlayerTexture).forEach(d => {
             this.scene.anims.create({
                 key: d.key,
@@ -58,6 +68,7 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
     moveUser(delta: number): void {
         //if user client on shift, camera and player speed
         let direction = null;
+        let moving = false;
 
         let activeEvents = this.userInputManager.getEventListForGameTick();
         let speedMultiplier = activeEvents.get(UserInputEvent.SpeedUp) ? 25 : 9;
@@ -67,39 +78,56 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
         let y = 0;
         if (activeEvents.get(UserInputEvent.MoveUp)) {
             y = - moveAmount;
-            direction = `${this.PlayerTexture}-${PlayerAnimationNames.WalkUp}`;
+            direction = PlayerAnimationNames.WalkUp;
+            moving = true;
         } else if (activeEvents.get(UserInputEvent.MoveDown)) {
             y = moveAmount;
-            direction = `${this.PlayerTexture}-${PlayerAnimationNames.WalkDown}`;
+            direction = PlayerAnimationNames.WalkDown;
+            moving = true;
         }
         if (activeEvents.get(UserInputEvent.MoveLeft)) {
             x = -moveAmount;
-            direction = `${this.PlayerTexture}-${PlayerAnimationNames.WalkLeft}`;
+            direction = PlayerAnimationNames.WalkLeft;
+            moving = true;
         } else if (activeEvents.get(UserInputEvent.MoveRight)) {
             x = moveAmount;
-            direction = `${this.PlayerTexture}-${PlayerAnimationNames.WalkRight}`;
+            direction = PlayerAnimationNames.WalkRight;
+            moving = true;
         }
         if (x !== 0 || y !== 0) {
             this.move(x, y);
-            this.emit(hasMovedEventName, {direction, x: this.x, y: this.y});
+            this.emit(hasMovedEventName, {moving, direction, x: this.x, y: this.y});
         } else {
-            if (this.previousMove !== PlayerAnimationNames.None) {
-                direction = PlayerAnimationNames.None;
+            if (this.wasMoving) {
+                //direction = PlayerAnimationNames.None;
                 this.stop();
-                this.emit(hasMovedEventName, {direction, x: this.x, y: this.y});
+                this.emit(hasMovedEventName, {moving, direction: this.previousDirection, x: this.x, y: this.y});
             }
         }
 
         if (direction !== null) {
-            this.previousMove = direction;
+            this.previousDirection = direction;
         }
+        this.wasMoving = moving;
     }
 
     //todo: put this method into the NonPlayer class instead
     updatePosition(position: PointInterface): void {
-        playAnimation(this, position.direction);
+        this.playAnimation(position.direction, position.moving);
         this.setX(position.x);
         this.setY(position.y);
         this.setDepth(position.y);
     }
+
+    private playAnimation(direction : string, moving: boolean): void {
+        if (moving && (!this.anims.currentAnim || this.anims.currentAnim.key !== direction)) {
+            this.anims.play(this.PlayerTexture+'-'+direction);
+        } else if (!moving) {
+            /*if (this.anims.currentAnim) {
+                this.anims.stop();
+            }*/
+            this.anims.play(this.PlayerTexture+'-'+direction);
+            this.anims.stop();
+        }
+    }
 }