This commit is contained in:
kharhamel 2020-04-19 20:45:34 +02:00
parent 61c6b9dacb
commit 60606947ab
18 changed files with 284 additions and 384 deletions

View file

@ -3,6 +3,7 @@ import Jwt from "jsonwebtoken";
import {BAD_REQUEST, OK} from "http-status-codes";
import {SECRET_KEY, ROOM} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
import { uuid } from 'uuidv4';
import {userManager} from "_Model/Users/UserManager";
export class AuthenticateController{
App : Application;
@ -10,6 +11,7 @@ export class AuthenticateController{
constructor(App : Application) {
this.App = App;
this.login();
this.getAllUsers();
}
//permit to login on application. Return token to connect on Websocket IO.
@ -22,13 +24,16 @@ export class AuthenticateController{
});
}
//TODO check user email for The Coding Machine game
let userId = uuid();
let token = Jwt.sign({email: param.email, roomId: ROOM, userId: userId}, SECRET_KEY, {expiresIn: '24h'});
return res.status(OK).send({
token: token,
roomId: ROOM,
userId: userId
});
let user = userManager.createUser(param.email);
let token = Jwt.sign({email: user.email, userId: user.id}, SECRET_KEY, {expiresIn: '24h'});
return res.status(OK).send(user);
});
}
getAllUsers(){
this.App.get("/users", (req: Request, res: Response) => {
let users = userManager.getAllUsers();
return res.status(OK).send(users);
});
}
}

View file

@ -7,6 +7,7 @@ import Jwt, {JsonWebTokenError} from "jsonwebtoken";
import {SECRET_KEY} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
import {ExtRooms, RefreshUserPositionFunction} from "../Model/Websocket/ExtRoom";
import {ExtRoomsInterface} from "_Model/Websocket/ExtRoomsInterface";
import {userManager} from "_Model/Users/UserManager";
export class IoSocketController{
Io: socketIO.Server;
@ -112,23 +113,12 @@ export class IoSocketController{
**/
seTimeOutInProgress : any = null;
shareUsersPosition(){
if(this.seTimeOutInProgress){
clearTimeout(this.seTimeOutInProgress);
}
//send for each room, all data of position user
let arrayMap = (this.Io.sockets.adapter.rooms as ExtRooms).userPositionMapByRoom;
if(!arrayMap){
this.seTimeOutInProgress = setTimeout(() => {
this.shareUsersPosition();
}, 10);
return;
}
arrayMap.forEach((value : any) => {
let roomId = value[0];
this.Io.in(roomId).emit('user-position', JSON.stringify(arrayMap));
});
this.seTimeOutInProgress = setTimeout(() => {
this.shareUsersPosition();
}, 10);
//every 1/10 of seconds, emit the current list of events
setInterval(() => {
let userEvents = userManager.getEventList();
if (userEvents.length) {
this.Io.emit('user-position', JSON.stringify(userEvents));
}
}, 100)
}
}

View file

@ -0,0 +1,86 @@
import {uuid} from "uuidv4";
import {BehaviorSubject} from "rxjs";
export interface UserPosition {
x: number;
y: number;
}
export class User {
name: string;
email: string;
position: UserPosition;
id: string;
constructor(id: string, name: string, email: string, position: UserPosition) {
this.id = id;
this.name = name;
this.email = email;
this.position = position
}
}
export interface UserPositionChangeEvent {
user: User;
deleted: boolean
added: boolean
}
class UserManager {
private usersList: Map<string, User> = new Map();
private eventsList: UserPositionChangeEvent[] = [];
//todo add more parameters
createUser(email: string): User {
let userId = uuid();
let user = new User(userId, "toto", email, {x: 0, y: 0});
this.usersList.set(userId, user);
this.eventsList.push({added: true, deleted: false, user})
return user;
}
deleteUser(id: string): User {
let user = this.usersList.get(id);
if (!user) {
throw "Could not delete user with id "+id;
}
this.usersList.delete(id);
this.eventsList.push({added: false, deleted: true, user});
return user;
}
updateUserPosition(id: string, userPosition: UserPosition): User {
let user = this.usersList.get(id);
if (!user) {
throw "Could not find user with id "+id;
}
user.position = userPosition;
this.usersList.set(id, user);
this.eventsList.push({added: false, deleted: false, user});
return user;
}
getAllUsers(): User[] {
let array = [];
for (const value of this.usersList.values()) {
array.push(value);
}
return array;
}
//flush the list of events
getEventList(): UserPositionChangeEvent[] {
let events = this.eventsList;
this.eventsList = [];
return events;
}
}
export const userManager = new UserManager();

View file

@ -66,6 +66,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"downlevelIteration": true,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}

View file

@ -17,6 +17,7 @@
"@types/axios": "^0.14.0",
"@types/socket.io-client": "^1.4.32",
"phaser": "^3.22.0",
"rxjs": "^6.5.5",
"socket.io-client": "^2.3.0"
},
"scripts": {

View file

@ -0,0 +1,17 @@
export class ConnectedUser {
id: string;
name: string;
email: string;
x: number;
y: number;
roomId: string
constructor( id: string,name: string, email: string, x: number, y: number) {
this.id = id;
this.name = name;
this.email = email;
this.x = x;
this.y = y;
this.roomId = "THECODINGMACHINE";
}
}

View file

@ -0,0 +1,37 @@
import {ConnectedUser} from "./ConnectedUser";
const SocketIo = require('socket.io-client');
import Axios from "axios";
import {API_URL} from "../Enum/EnvironmentVariable";
class ConnexionManager {
socket : any;
token : string;
email : string;
userId: string;
startedRoom : string;
async createConnexion(email : string) : Promise<{connectedUser: ConnectedUser, socket: any}>{
let res = await Axios.post(`${API_URL}/login`, {email});
this.token = res.data.token;
this.startedRoom = res.data.roomId;
this.userId = res.data.userId;
let connectedUser = new ConnectedUser(res.data.userId, res.data.name, res.data.email, 0, 0);
let socket = SocketIo(`${API_URL}`, {
query: {
token: this.token
}
});
return {connectedUser, socket};
}
getAllUsers() {
return Axios.post(`${API_URL}/users`).then(res => {
return res.data.map((user:any) => new ConnectedUser(user.id, user.name, user.email, user.x, user.y))
});
}
}
export const connexionManager = new ConnexionManager();

View file

@ -0,0 +1,73 @@
import {ConnectedUser} from "./ConnectedUser";
import {BehaviorSubject} from "rxjs";
import {connexionManager} from "./ConnexionManager";
export enum StatusGameManagerEnum {
IN_PROGRESS = 1,
CURRENT_USER_CREATED = 2
}
interface Position{
x: number;
y: number;
}
class ConnectedUserPositionData{
userId: string;
position: Position;
constructor(userId: string, position: Position) {
this.userId = userId;
this.position = position;
}
}
export interface UserPositionChangeEvent {
userId: string;
x: number;
y: number;
deleted: boolean
added: boolean
}
export class GameManager {
status: StatusGameManagerEnum;
private connectedUser: ConnectedUser;
private socket: any;
private connectedUserPosition = new BehaviorSubject({x: 0, y: 0});
public otherUserPositionsChange: BehaviorSubject<UserPositionChangeEvent[]> = new BehaviorSubject([]);
constructor() {
this.status = StatusGameManagerEnum.IN_PROGRESS;
}
async login(email:string) {
let response = await connexionManager.createConnexion(email);
this.connectedUser = response.connectedUser;
this.socket = response.socket;
this.socket.on('message-error', (message : string) => {
console.error("message-error", message);
});
this.socket.on("user-position", (message: string) => {
let eventList = JSON.parse(message);
this.otherUserPositionsChange.next(eventList);
});
this.connectedUserPosition.subscribe(position => {
let data = new ConnectedUserPositionData(this.connectedUser.id, position);
this.socket.emit('user-position', JSON.stringify(data));
})
}
updateConnectedUserPosition(x: number, y: number) {
this.connectedUserPosition.next({x, y});
}
}
export const gameManager = new GameManager();

View file

@ -1,209 +0,0 @@
import {gameManager, GameManagerInterface} from "./Phaser/Game/GameManager";
const SocketIo = require('socket.io-client');
import Axios from "axios";
import {API_URL} from "./Enum/EnvironmentVariable";
class Message {
userId: string;
roomId: string;
constructor(userId : string, roomId : string) {
this.userId = userId;
this.roomId = roomId;
}
toJson() {
return {
userId: this.userId,
roomId: this.roomId,
}
}
}
export interface PointInterface {
x: number;
y: number;
direction : string;
toJson() : object;
}
class Point implements PointInterface{
x: number;
y: number;
direction : string;
constructor(x : number, y : number, direction : string = "none") {
if(x === null || y === null){
throw Error("position x and y cannot be null");
}
this.x = x;
this.y = y;
this.direction = direction;
}
toJson(){
return {
x : this.x,
y: this.y,
direction: this.direction
}
}
}
export interface MessageUserPositionInterface {
userId: string;
roomId: string;
position: PointInterface;
}
class MessageUserPosition extends Message implements MessageUserPositionInterface{
position: PointInterface;
constructor(userId : string, roomId : string, point : Point) {
super(userId, roomId);
this.position = point;
}
toString() {
return JSON.stringify(
Object.assign(
super.toJson(),
{
position: this.position.toJson()
})
);
}
}
export interface ListMessageUserPositionInterface {
roomId : string;
listUsersPosition: Array<MessageUserPosition>;
}
class ListMessageUserPosition{
roomId : string;
listUsersPosition: Array<MessageUserPosition>;
constructor(roomId : string, data : any) {
this.roomId = roomId;
this.listUsersPosition = new Array<MessageUserPosition>();
data.forEach((userPosition: any) => {
this.listUsersPosition.push(new MessageUserPosition(
userPosition.userId,
userPosition.roomId,
new Point(
userPosition.position.x,
userPosition.position.y,
userPosition.position.direction
)
));
});
}
}
export interface ConnexionInterface {
socket : any;
token : string;
email : string;
userId: string;
startedRoom : string;
createConnexion(userName:string, email: string) : Promise<any>;
joinARoom(roomId : string) : void;
sharePosition(roomId : string, x : number, y : number, direction : string) : void;
positionOfAllUser() : void;
}
export class ConnexionManager implements ConnexionInterface{
socket : any;
token : string;
email : string;
userId: string;
startedRoom : string;
shareUserPositionCallback: Function;
constructor() {
}
async createConnexion(email : string) : Promise<ConnexionInterface>{
let res = await Axios.post(`${API_URL}/login`, {email});
this.token = res.data.token;
this.startedRoom = res.data.roomId;
this.userId = res.data.userId;
this.socket = SocketIo(`${API_URL}`, {
query: {
token: this.token
}
});
//join the room
this.joinARoom(this.startedRoom);
//share your first position
this.sharePosition(this.startedRoom, 0, 0);
this.positionOfAllUser();
this.errorMessage();
return this;
}
/**
* Permit to join a room
* @param roomId
*/
joinARoom(roomId : string) : void {
let messageUserPosition = new MessageUserPosition(this.userId, this.startedRoom, new Point(0, 0));
this.socket.emit('join-room', messageUserPosition.toString());
}
/**
*
* @param roomId
* @param x
* @param y
* @param direction
*/
sharePosition(roomId : string, x : number, y : number, direction : string = "none") : void{
if(!this.socket){
return;
}
let messageUserPosition = new MessageUserPosition(this.userId, roomId, new Point(x, y, direction));
this.socket.emit('user-position', messageUserPosition.toString());
}
/**
* The data sent is an array with information for each user :
* [
* {
* userId: <string>,
* roomId: <string>,
* position: {
* x : <number>,
* y : <number>,
* direction: <string>
* }
* },
* ...
* ]
**/
positionOfAllUser() : void {
this.socket.on("user-position", (message: string) => {
let dataList = JSON.parse(message);
dataList.forEach((UserPositions: any) => {
let listMessageUserPosition = new ListMessageUserPosition(UserPositions[0], UserPositions[1]);
if (this.shareUserPositionCallback) {
this.shareUserPositionCallback(listMessageUserPosition)
}
});
});
}
errorMessage() : void {
this.socket.on('message-error', (message : string) => {
console.error("message-error", message);
})
}
registerShareUserPositionCallback(callback: (l:ListMessageUserPosition) => {}) {
this.shareUserPositionCallback = callback;
}
}
export const connectionManager = new ConnexionManager();

View file

@ -18,6 +18,17 @@ export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite {
this.setOffset(8, 16);
}
initAnimation(): void {
getPlayerAnimations().forEach(d => {
this.scene.anims.create({
key: d.key,
frames: this.scene.anims.generateFrameNumbers(d.frameModel, {start: d.frameStart, end: d.frameEnd}),
frameRate: d.frameRate,
repeat: d.repeat
});
})
}
move(x: number, y: number){
this.setVelocity(x, y);

View file

@ -1,57 +0,0 @@
import {GameSceneInterface, GameScene} from "./GameScene";
import {ROOM} from "../../Enum/EnvironmentVariable"
import {
ConnexionInterface,
ListMessageUserPositionInterface,
connectionManager
} from "../../ConnexionManager";
export enum StatusGameManagerEnum {
IN_PROGRESS = 1,
CURRENT_USER_CREATED = 2
}
export let ConnexionInstance : ConnexionInterface;
export interface GameManagerInterface {
GameScenes: Array<GameSceneInterface>;
status : number;
createCurrentPlayer() : void;
shareUserPosition(ListMessageUserPosition : ListMessageUserPositionInterface): void;
}
export class GameManager implements GameManagerInterface {
GameScenes: Array<GameSceneInterface> = [];
status: number;
constructor() {
this.status = StatusGameManagerEnum.IN_PROGRESS;
}
/**
* Permit to create player in started room
*/
createCurrentPlayer(): void {
this.status = StatusGameManagerEnum.CURRENT_USER_CREATED;
}
/**
* Share position in game
* @param ListMessageUserPosition
*/
shareUserPosition(ListMessageUserPosition: ListMessageUserPositionInterface): void {
if (this.status === StatusGameManagerEnum.IN_PROGRESS) {
return;
}
try {
let Game: GameSceneInterface = this.GameScenes.find((Game: GameSceneInterface) => Game.RoomId === ListMessageUserPosition.roomId);
if (!Game) {
return;
}
Game.shareUserPosition(ListMessageUserPosition.listUsersPosition)
} catch (e) {
console.error(e);
}
}
}
export const gameManager = new GameManager();

View file

@ -1,11 +1,12 @@
import {gameManager, GameManagerInterface, StatusGameManagerEnum} from "./GameManager";
import {connectionManager, MessageUserPositionInterface} from "../../ConnexionManager";
import {CurrentGamerInterface, GamerInterface, Player} from "../Player/Player";
import {CurrentGamerInterface, Player} from "../Player/Player";
import {DEBUG_MODE, RESOLUTION, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable";
import Tile = Phaser.Tilemaps.Tile;
import {ITiledMap, ITiledTileSet} from "../Map/ITiledMap";
import {cypressAsserter} from "../../Cypress/CypressAsserter";
import {NonPlayer} from "../NonPlayer/NonPlayer";
import {ConnectedUser} from "../../Connexion/ConnectedUser";
import {gameManager, UserPositionChangeEvent} from "../../Connexion/GameManager";
import {connexionManager} from "../../Connexion/ConnexionManager";
export const GameSceneName = "GameScene";
export enum Textures {
@ -13,14 +14,7 @@ export enum Textures {
Map = 'map'
}
export interface GameSceneInterface extends Phaser.Scene {
RoomId : string;
Map: Phaser.Tilemaps.Tilemap;
createCurrentPlayer(UserId : string) : void;
shareUserPosition(UsersPosition : Array<MessageUserPositionInterface>): void;
}
export class GameScene extends Phaser.Scene implements GameSceneInterface{
GameManager : GameManagerInterface;
export class GameScene extends Phaser.Scene {
RoomId : string;
Terrains : Array<Phaser.Tilemaps.Tileset>;
CurrentPlayer: CurrentGamerInterface;
@ -37,8 +31,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
super({
key: GameSceneName
});
this.RoomId = connectionManager.startedRoom;
this.GameManager = gameManager;
this.RoomId = connexionManager.startedRoom;
this.Terrains = [];
}
@ -105,6 +98,8 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
//notify game manager can to create currentUser in map
this.createCurrentPlayer();
gameManager.otherUserPositionsChange.subscribe((list:any) => this.updateOrCreateMapPlayer(list))
//initialise camera
@ -157,8 +152,8 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
createCurrentPlayer(){
//initialise player
this.CurrentPlayer = new Player(
connectionManager.userId,
connectionManager.email,
connexionManager.userId,
connexionManager.email,
this,
this.startX,
this.startY,
@ -168,7 +163,6 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
//create collision
this.createCollisionWithPlayer();
this.createCollisionObject();
gameManager.createCurrentPlayer();
}
EventToClickOnTile(){
@ -187,59 +181,42 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
this.CurrentPlayer.moveUser();
}
/**
* Share position in scene
* @param UsersPosition
*/
shareUserPosition(UsersPosition : Array<MessageUserPositionInterface>): void {
this.updateOrCreateMapPlayer(UsersPosition);
}
/**
* Create new player and clean the player on the map
* @param UsersPosition
*/
updateOrCreateMapPlayer(UsersPosition : Array<MessageUserPositionInterface>){
if(!this.CurrentPlayer){
return;
}
updateOrCreateMapPlayer(userEvents : UserPositionChangeEvent[]){
//add or create new user
UsersPosition.forEach((userPosition : MessageUserPositionInterface) => {
if(userPosition.userId === this.CurrentPlayer.userId){
return;
}
let player = this.findPlayerInMap(userPosition.userId);
userEvents.forEach(userEvent => {
let player = this.findPlayerInMap(userEvent.userId);
if(!player){
this.addPlayer(userPosition);
this.addPlayer(userEvent);
}else{
player.updatePosition(userPosition);
if (userEvent.deleted) {
player.destroy();
} else {
player.updatePosition(userEvent);
}
}
});
//clean map
this.MapPlayers.getChildren().forEach((player: GamerInterface) => {
if(UsersPosition.find((message : MessageUserPositionInterface) => message.userId === player.userId)){
return;
}
player.destroy();
this.MapPlayers.remove(player);
});
})
}
private findPlayerInMap(UserId : string) : GamerInterface | null{
private findPlayerInMap(UserId : string) : any | null{
let player = this.MapPlayers.getChildren().find((player: Player) => UserId === player.userId);
if(!player){
return null;
}
return (player as GamerInterface);
return player;
}
/**
* Create new player
* @param MessageUserPosition
*/
addPlayer(MessageUserPosition : MessageUserPositionInterface){
addPlayer(MessageUserPosition : any){
//initialise player
let player = new NonPlayer(
MessageUserPosition.userId,
@ -252,7 +229,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{
player.updatePosition(MessageUserPosition);
//init colision
this.physics.add.overlap(this.CurrentPlayer, player, (CurrentPlayer: CurrentGamerInterface, MapPlayer: GamerInterface) => {
this.physics.add.overlap(this.CurrentPlayer, player, (CurrentPlayer: CurrentGamerInterface, MapPlayer: any) => {
CurrentPlayer.say("Salut ça va?");
MapPlayer.say("Oui et toi?");
});

View file

@ -1,6 +1,6 @@
import KeyboardKeydownCallback = Phaser.Types.Input.Keyboard.KeyboardKeydownCallback;
import {connectionManager} from "../../ConnexionManager";
import {GameSceneName} from "../Game/GameScene";
import {connexionManager} from "../../Connexion/ConnexionManager";
export const LoginSceneName = "LoginScene";
enum LoginTextures {
@ -46,7 +46,7 @@ export class LogincScene extends Phaser.Scene {
async login() {
let email = this.textEntry.text;
if (!email) return;
await connectionManager.createConnexion("a.poly@thecodingmachine.com");
await connexionManager.createConnexion("a.poly@thecodingmachine.com");
this.scene.start(GameSceneName);
}
}

View file

@ -2,7 +2,6 @@ import {PlayableCaracter} from "../Entity/PlayableCaracter";
import {Textures} from "../Game/GameScene";
import {UserInputEvent} from "../UserInput/UserInputManager";
import {Player} from "../Player/Player";
import {MessageUserPositionInterface} from "../../ConnexionManager";
import {getPlayerAnimations, playAnimation} from "../Player/Animation";
export class NonPlayer extends PlayableCaracter {
@ -20,7 +19,7 @@ export class NonPlayer extends PlayableCaracter {
}
updatePosition(MessageUserPosition : MessageUserPositionInterface){
updatePosition(MessageUserPosition:any){
playAnimation(this, MessageUserPosition.position.direction);
this.setX(MessageUserPosition.position.x);
this.setY(MessageUserPosition.position.y);

View file

@ -1,9 +1,8 @@
import {getPlayerAnimations, playAnimation, PlayerAnimationNames} from "./Animation";
import {GameSceneInterface, Textures} from "../Game/GameScene";
import {ConnexionInstance} from "../Game/GameManager";
import {MessageUserPositionInterface} from "../../ConnexionManager";
import {ActiveEventList, UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
import {PlayableCaracter} from "../Entity/PlayableCaracter";
import {gameManager} from "../../Connexion/GameManager";
import {Textures} from "../Game/GameScene";
export interface CurrentGamerInterface extends PlayableCaracter{
userId : string;
@ -13,15 +12,7 @@ export interface CurrentGamerInterface extends PlayableCaracter{
say(text : string) : void;
}
export interface GamerInterface extends PlayableCaracter{
userId : string;
PlayerValue : string;
initAnimation() : void;
updatePosition(MessageUserPosition : MessageUserPositionInterface) : void;
say(text : string) : void;
}
export class Player extends PlayableCaracter implements CurrentGamerInterface, GamerInterface {
export class Player extends PlayableCaracter implements CurrentGamerInterface {
userId: string;
PlayerValue: string;
userInputManager: UserInputManager;
@ -30,7 +21,7 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
constructor(
userId: string,
email: string,
Scene: GameSceneInterface,
Scene: Phaser.Scene,
x: number,
y: number,
PlayerValue: string = Textures.Player
@ -50,17 +41,6 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
this.say("My email is "+this.email)
}
initAnimation(): void {
getPlayerAnimations().forEach(d => {
this.scene.anims.create({
key: d.key,
frames: this.scene.anims.generateFrameNumbers(d.frameModel, {start: d.frameStart, end: d.frameEnd}),
frameRate: d.frameRate,
repeat: d.repeat
});
})
}
moveUser(): void {
//if user client on shift, camera and player speed
let haveMove = false;
@ -93,18 +73,7 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
direction = PlayerAnimationNames.None;
this.stop();
}
this.sharePosition(direction);
}
private sharePosition(direction: string) {
if (ConnexionInstance) {
ConnexionInstance.sharePosition((this.scene as GameSceneInterface).RoomId, this.x, this.y, direction);
}
}
updatePosition(MessageUserPosition: MessageUserPositionInterface) {
playAnimation(this, MessageUserPosition.position.direction);
this.setX(MessageUserPosition.position.x);
this.setY(MessageUserPosition.position.y);
gameManager.updateConnectedUserPosition(this.x, this.y);
}
}

View file

@ -1,5 +1,4 @@
import Map = Phaser.Structs.Map;
import {GameSceneInterface} from "../Game/GameScene";
interface UserInputManagerDatum {
keyCode: number;
@ -50,7 +49,7 @@ export class UserInputManager {
{keyCode: Phaser.Input.Keyboard.KeyCodes.F, event: UserInputEvent.Shout, keyInstance: null},
];
constructor(Scene : GameSceneInterface) {
constructor(Scene : Phaser.Scene) {
this.KeysCode.forEach(d => {
d.keyInstance = Scene.input.keyboard.addKey(d.keyCode);
});

View file

@ -7,6 +7,7 @@
"module": "es6",
"target": "es5",
"jsx": "react",
"downlevelIteration": true,
"allowJs": true
}
}

View file

@ -3278,7 +3278,7 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
rxjs@^6.5.3:
rxjs@^6.5.3, rxjs@^6.5.5:
version "6.5.5"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec"
integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==