Adding Outline capabilities and a ActionableItem notion.
This commit is contained in:
parent
f7466994c5
commit
ed146226cf
@ -199,7 +199,19 @@
|
|||||||
"draworder":"topdown",
|
"draworder":"topdown",
|
||||||
"id":3,
|
"id":3,
|
||||||
"name":"floorLayer",
|
"name":"floorLayer",
|
||||||
"objects":[],
|
"objects":[
|
||||||
|
{
|
||||||
|
"height":0,
|
||||||
|
"id":1,
|
||||||
|
"name":"computer",
|
||||||
|
"point":true,
|
||||||
|
"rotation":0,
|
||||||
|
"type":"computer",
|
||||||
|
"visible":true,
|
||||||
|
"width":0,
|
||||||
|
"x":431,
|
||||||
|
"y":142
|
||||||
|
}],
|
||||||
"opacity":1,
|
"opacity":1,
|
||||||
"type":"objectgroup",
|
"type":"objectgroup",
|
||||||
"visible":true,
|
"visible":true,
|
||||||
@ -225,7 +237,7 @@
|
|||||||
"y":0
|
"y":0
|
||||||
}],
|
}],
|
||||||
"nextlayerid":18,
|
"nextlayerid":18,
|
||||||
"nextobjectid":1,
|
"nextobjectid":2,
|
||||||
"orientation":"orthogonal",
|
"orientation":"orthogonal",
|
||||||
"renderorder":"right-down",
|
"renderorder":"right-down",
|
||||||
"tiledversion":"1.3.3",
|
"tiledversion":"1.3.3",
|
||||||
|
@ -38,6 +38,28 @@ services:
|
|||||||
- "traefik.http.routers.front-ssl.tls=true"
|
- "traefik.http.routers.front-ssl.tls=true"
|
||||||
- "traefik.http.routers.front-ssl.service=front"
|
- "traefik.http.routers.front-ssl.service=front"
|
||||||
|
|
||||||
|
maps:
|
||||||
|
image: thecodingmachine/nodejs:12-apache
|
||||||
|
environment:
|
||||||
|
DEBUG_MODE: "$DEBUG_MODE"
|
||||||
|
HOST: "0.0.0.0"
|
||||||
|
NODE_ENV: development
|
||||||
|
APACHE_DOCUMENT_ROOT: dist/
|
||||||
|
#APACHE_EXTENSIONS: headers
|
||||||
|
#APACHE_EXTENSION_HEADERS: 1
|
||||||
|
STARTUP_COMMAND_0: sudo a2enmod headers
|
||||||
|
STARTUP_COMMAND_1: yarn install
|
||||||
|
STARTUP_COMMAND_2: yarn run dev &
|
||||||
|
volumes:
|
||||||
|
- ./maps:/var/www/html
|
||||||
|
labels:
|
||||||
|
- "traefik.http.routers.maps.rule=Host(`maps.workadventure.localhost`)"
|
||||||
|
- "traefik.http.routers.maps.entryPoints=web,traefik"
|
||||||
|
- "traefik.http.services.maps.loadbalancer.server.port=80"
|
||||||
|
- "traefik.http.routers.maps-ssl.rule=Host(`maps.workadventure.localhost`)"
|
||||||
|
- "traefik.http.routers.maps-ssl.entryPoints=websecure"
|
||||||
|
- "traefik.http.routers.maps-ssl.tls=true"
|
||||||
|
- "traefik.http.routers.maps-ssl.service=maps"
|
||||||
|
|
||||||
back:
|
back:
|
||||||
image: thecodingmachine/nodejs:12
|
image: thecodingmachine/nodejs:12
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
"phaser": "^3.22.0",
|
"phaser": "^3.22.0",
|
||||||
"queue-typescript": "^1.0.1",
|
"queue-typescript": "^1.0.1",
|
||||||
"simple-peer": "^9.6.2",
|
"simple-peer": "^9.6.2",
|
||||||
"socket.io-client": "^2.3.0"
|
"socket.io-client": "^2.3.0",
|
||||||
|
"webpack-require-http": "^0.4.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "webpack-dev-server --open",
|
"start": "webpack-dev-server --open",
|
||||||
|
@ -10,7 +10,7 @@ import { DEBUG_MODE, ZOOM_LEVEL, POSITION_DELAY } from "../../Enum/EnvironmentVa
|
|||||||
import {
|
import {
|
||||||
ITiledMap,
|
ITiledMap,
|
||||||
ITiledMapLayer,
|
ITiledMapLayer,
|
||||||
ITiledMapLayerProperty,
|
ITiledMapLayerProperty, ITiledMapObject,
|
||||||
ITiledTileSet
|
ITiledTileSet
|
||||||
} from "../Map/ITiledMap";
|
} from "../Map/ITiledMap";
|
||||||
import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character";
|
import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character";
|
||||||
@ -28,6 +28,8 @@ import {SimplePeer} from "../../WebRtc/SimplePeer";
|
|||||||
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
||||||
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
||||||
import {FourOFourSceneName} from "../Reconnecting/FourOFourScene";
|
import {FourOFourSceneName} from "../Reconnecting/FourOFourScene";
|
||||||
|
import {ItemFactoryInterface} from "../Items/ItemFactoryInterface";
|
||||||
|
import {ActionableItem} from "../Items/ActionableItem";
|
||||||
|
|
||||||
|
|
||||||
export enum Textures {
|
export enum Textures {
|
||||||
@ -89,6 +91,9 @@ export class GameScene extends Phaser.Scene {
|
|||||||
private connection: Connection;
|
private connection: Connection;
|
||||||
private simplePeer : SimplePeer;
|
private simplePeer : SimplePeer;
|
||||||
private connectionPromise: Promise<Connection>
|
private connectionPromise: Promise<Connection>
|
||||||
|
// A promise that will resolve when the "create" method is called (signaling loading is ended)
|
||||||
|
private createPromise: Promise<void>;
|
||||||
|
private createPromiseResolve: (value?: void | PromiseLike<void>) => void;
|
||||||
|
|
||||||
MapKey: string;
|
MapKey: string;
|
||||||
MapUrlFile: string;
|
MapUrlFile: string;
|
||||||
@ -106,6 +111,9 @@ export class GameScene extends Phaser.Scene {
|
|||||||
|
|
||||||
private PositionNextScene: Array<Array<{ key: string, hash: string }>> = new Array<Array<{ key: string, hash: string }>>();
|
private PositionNextScene: Array<Array<{ key: string, hash: string }>> = new Array<Array<{ key: string, hash: string }>>();
|
||||||
private startLayerName: string|undefined;
|
private startLayerName: string|undefined;
|
||||||
|
private actionableItems: Array<ActionableItem> = new Array<ActionableItem>();
|
||||||
|
// The item that can be selected by pressing the space key.
|
||||||
|
private outlinedItem: ActionableItem|null = null;
|
||||||
|
|
||||||
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
||||||
const mapKey = GameScene.getMapKeyByUrl(mapUrlFile);
|
const mapKey = GameScene.getMapKeyByUrl(mapUrlFile);
|
||||||
@ -128,6 +136,10 @@ export class GameScene extends Phaser.Scene {
|
|||||||
this.MapKey = MapKey;
|
this.MapKey = MapKey;
|
||||||
this.MapUrlFile = MapUrlFile;
|
this.MapUrlFile = MapUrlFile;
|
||||||
this.RoomId = this.instance + '__' + MapKey;
|
this.RoomId = this.instance + '__' + MapKey;
|
||||||
|
|
||||||
|
this.createPromise = new Promise<void>((resolve, reject): void => {
|
||||||
|
this.createPromiseResolve = resolve;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//hook preload scene
|
//hook preload scene
|
||||||
@ -225,7 +237,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
|
|
||||||
// FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving.
|
// FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving.
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
private onMapLoad(data: any): void {
|
private async onMapLoad(data: any): Promise<void> {
|
||||||
// Triggered when the map is loaded
|
// Triggered when the map is loaded
|
||||||
// Load tiles attached to the map recursively
|
// Load tiles attached to the map recursively
|
||||||
this.mapFile = data.data;
|
this.mapFile = data.data;
|
||||||
@ -238,6 +250,85 @@ export class GameScene extends Phaser.Scene {
|
|||||||
//TODO strategy to add access token
|
//TODO strategy to add access token
|
||||||
this.load.image(`${url}/${tileset.image}`, `${url}/${tileset.image}`);
|
this.load.image(`${url}/${tileset.image}`, `${url}/${tileset.image}`);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Scan the object layers for objects to load and load them.
|
||||||
|
let objects = new Map<string, ITiledMapObject[]>();
|
||||||
|
|
||||||
|
for (let layer of this.mapFile.layers) {
|
||||||
|
if (layer.type === 'objectgroup') {
|
||||||
|
for (let object of layer.objects) {
|
||||||
|
let objectsOfType: ITiledMapObject[]|undefined;
|
||||||
|
if (!objects.has(object.type)) {
|
||||||
|
objectsOfType = new Array<ITiledMapObject>();
|
||||||
|
} else {
|
||||||
|
objectsOfType = objects.get(object.type);
|
||||||
|
if (objectsOfType === undefined) {
|
||||||
|
throw new Error('Unexpected object type not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
objectsOfType.push(object);
|
||||||
|
objects.set(object.type, objectsOfType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let [itemType, objectsOfType] of objects) {
|
||||||
|
// FIXME: we would ideally need for the loader to WAIT for the import to be performed, which means writing our own loader plugin.
|
||||||
|
|
||||||
|
let itemFactory: ItemFactoryInterface;
|
||||||
|
|
||||||
|
switch (itemType) {
|
||||||
|
case 'computer':
|
||||||
|
let module = await import('../Items/Computer/computer');
|
||||||
|
itemFactory = module.default as ItemFactoryInterface;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported object type: "'+ itemType +'"');
|
||||||
|
}
|
||||||
|
|
||||||
|
itemFactory.preload(this.load);
|
||||||
|
this.load.start(); // Let's manually start the loader because the import might be over AFTER the loading ends.
|
||||||
|
|
||||||
|
this.load.on('complete', () => {
|
||||||
|
// FIXME: the factory might fail because the resources might not be loaded yet...
|
||||||
|
// We would need to add a loader ended event in addition to the createPromise
|
||||||
|
this.createPromise.then(() => {
|
||||||
|
itemFactory.create(this);
|
||||||
|
|
||||||
|
for (let object of objectsOfType) {
|
||||||
|
// TODO: we should pass here a factory to create sprites (maybe?)
|
||||||
|
let actionableItem = itemFactory.factory(this, object);
|
||||||
|
this.actionableItems.push(actionableItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// import(/* webpackIgnore: true */ scriptUrl).then(result => {
|
||||||
|
//
|
||||||
|
// result.default.preload(this.load);
|
||||||
|
//
|
||||||
|
// this.load.start(); // Let's manually start the loader because the import might be over AFTER the loading ends.
|
||||||
|
// this.load.on('complete', () => {
|
||||||
|
// // FIXME: the factory might fail because the resources might not be loaded yet...
|
||||||
|
// // We would need to add a loader ended event in addition to the createPromise
|
||||||
|
// this.createPromise.then(() => {
|
||||||
|
// result.default.create(this);
|
||||||
|
//
|
||||||
|
// for (let object of objectsOfType) {
|
||||||
|
// // TODO: we should pass here a factory to create sprites (maybe?)
|
||||||
|
// let objectSprite = result.default.factory(this, object);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST: let's load a module dynamically!
|
||||||
|
/*let foo = "http://maps.workadventure.localhost/computer.js";
|
||||||
|
import(/* webpackIgnore: true * / foo).then(result => {
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//hook initialisation
|
//hook initialisation
|
||||||
@ -361,6 +452,8 @@ export class GameScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.createPromiseResolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
||||||
@ -526,6 +619,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
|
|
||||||
//listen event to share position of user
|
//listen event to share position of user
|
||||||
this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
|
this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
|
||||||
|
this.CurrentPlayer.on(hasMovedEventName, this.outlineItem.bind(this))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,6 +649,49 @@ export class GameScene extends Phaser.Scene {
|
|||||||
// Otherwise, do nothing.
|
// Otherwise, do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the correct item to outline and outline it (if there is an item to be outlined)
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
private outlineItem(event: HasMovedEvent): void {
|
||||||
|
let x = event.x;
|
||||||
|
let y = event.y;
|
||||||
|
switch (event.direction) {
|
||||||
|
case PlayerAnimationNames.WalkUp:
|
||||||
|
y -= 32;
|
||||||
|
break;
|
||||||
|
case PlayerAnimationNames.WalkDown:
|
||||||
|
y += 32;
|
||||||
|
break;
|
||||||
|
case PlayerAnimationNames.WalkLeft:
|
||||||
|
x -= 32;
|
||||||
|
break;
|
||||||
|
case PlayerAnimationNames.WalkRight:
|
||||||
|
x += 32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unexpected direction "' + event.direction + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
let shortestDistance: number = Infinity;
|
||||||
|
let selectedItem: ActionableItem|null = null;
|
||||||
|
for (let item of this.actionableItems) {
|
||||||
|
let distance = item.actionableDistance(x, y);
|
||||||
|
if (distance !== null && distance < shortestDistance) {
|
||||||
|
shortestDistance = distance;
|
||||||
|
selectedItem = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.outlinedItem === selectedItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.outlinedItem?.notSelectable();
|
||||||
|
this.outlinedItem = selectedItem;
|
||||||
|
this.outlinedItem?.selectable();
|
||||||
|
}
|
||||||
|
|
||||||
private doPushPlayerPosition(event: HasMovedEvent): void {
|
private doPushPlayerPosition(event: HasMovedEvent): void {
|
||||||
this.lastMoveEventSent = event;
|
this.lastMoveEventSent = event;
|
||||||
this.lastSentTick = this.currentTick;
|
this.lastSentTick = this.currentTick;
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* An actionable item represents an in-game object that can be activated using the space-bar.
|
||||||
|
* It has coordinates and an "activation radius"
|
||||||
|
*/
|
||||||
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
|
import {OutlinePipeline} from "../Shaders/OutlinePipeline";
|
||||||
|
|
||||||
|
export class ActionableItem {
|
||||||
|
private readonly activationRadiusSquared : number;
|
||||||
|
private isSelectable: boolean = false;
|
||||||
|
|
||||||
|
public constructor(private sprite: Sprite, private activationRadius: number) {
|
||||||
|
this.activationRadiusSquared = activationRadius * activationRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the square of the distance to the object center IF we are in item action range
|
||||||
|
* OR null if we are out of range.
|
||||||
|
*/
|
||||||
|
public actionableDistance(x: number, y: number): number|null {
|
||||||
|
let distanceSquared = (x - this.sprite.x)*(x - this.sprite.x) + (y - this.sprite.y)*(y - this.sprite.y);
|
||||||
|
if (distanceSquared < this.activationRadiusSquared) {
|
||||||
|
return distanceSquared;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the outline of the sprite.
|
||||||
|
*/
|
||||||
|
public selectable(): void {
|
||||||
|
if (this.isSelectable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isSelectable = true;
|
||||||
|
this.sprite.setPipeline(OutlinePipeline.KEY);
|
||||||
|
this.sprite.pipeline.setFloat2('uTextureSize',
|
||||||
|
this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the outline of the sprite
|
||||||
|
*/
|
||||||
|
public notSelectable(): void {
|
||||||
|
if (!this.isSelectable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isSelectable = false;
|
||||||
|
this.sprite.resetPipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when the "space" key is pressed and the object is in range of being activated.
|
||||||
|
*/
|
||||||
|
public activate(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
24
front/src/Phaser/Items/Computer/computer.ts
Normal file
24
front/src/Phaser/Items/Computer/computer.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import * as Phaser from 'phaser';
|
||||||
|
import {Scene} from "phaser";
|
||||||
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
|
import {ITiledMapObject} from "../../Map/ITiledMap";
|
||||||
|
import {ItemFactoryInterface} from "../ItemFactoryInterface";
|
||||||
|
import {GameScene} from "../../Game/GameScene";
|
||||||
|
import {ActionableItem} from "../ActionableItem";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
preload: (loader: Phaser.Loader.LoaderPlugin): void => {
|
||||||
|
loader.atlas('computer', 'http://maps.workadventure.localhost/computer/computer.png', 'http://maps.workadventure.localhost/computer/computer_atlas.json');
|
||||||
|
},
|
||||||
|
create: (scene: GameScene): void => {
|
||||||
|
|
||||||
|
},
|
||||||
|
factory: (scene: GameScene, object: ITiledMapObject): ActionableItem => {
|
||||||
|
// Idée: ESSAYER WebPack? https://paultavares.wordpress.com/2018/07/02/webpack-how-to-generate-an-es-module-bundle/
|
||||||
|
let foo = new Sprite(scene, object.x, object.y, 'computer');
|
||||||
|
scene.add.existing(foo);
|
||||||
|
|
||||||
|
return new ActionableItem(foo, 32);
|
||||||
|
//scene.add.sprite(object.x, object.y, 'computer');
|
||||||
|
}
|
||||||
|
} as ItemFactoryInterface;
|
10
front/src/Phaser/Items/ItemFactoryInterface.ts
Normal file
10
front/src/Phaser/Items/ItemFactoryInterface.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import LoaderPlugin = Phaser.Loader.LoaderPlugin;
|
||||||
|
import {GameScene} from "../Game/GameScene";
|
||||||
|
import {ITiledMapObject} from "../Map/ITiledMap";
|
||||||
|
import {ActionableItem} from "./ActionableItem";
|
||||||
|
|
||||||
|
export interface ItemFactoryInterface {
|
||||||
|
preload: (loader: LoaderPlugin) => void;
|
||||||
|
create: (scene: GameScene) => void;
|
||||||
|
factory: (scene: GameScene, object: ITiledMapObject) => ActionableItem;
|
||||||
|
}
|
@ -33,10 +33,6 @@ export class Player extends Character implements CurrentGamerInterface {
|
|||||||
|
|
||||||
//the current player model should be push away by other players to prevent conflict
|
//the current player model should be push away by other players to prevent conflict
|
||||||
this.setImmovable(false);
|
this.setImmovable(false);
|
||||||
|
|
||||||
this.setPipeline(OutlinePipeline.KEY);
|
|
||||||
this.pipeline.setFloat2('uTextureSize',
|
|
||||||
this.texture.getSourceImage().width, this.texture.getSourceImage().height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moveUser(delta: number): void {
|
moveUser(delta: number): void {
|
||||||
|
@ -50,7 +50,7 @@ export class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTint
|
|||||||
|
|
||||||
if (texture.a == 0.0 && max(max(upAlpha, downAlpha), max(leftAlpha, rightAlpha)) == 1.0)
|
if (texture.a == 0.0 && max(max(upAlpha, downAlpha), max(leftAlpha, rightAlpha)) == 1.0)
|
||||||
{
|
{
|
||||||
color = vec4(1.0, 1.0, 1.0, 1.0);
|
color = vec4(1.0, 1.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
|
@ -47,6 +47,7 @@ export class UserInputManager {
|
|||||||
{event: UserInputEvent.SpeedUp, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SHIFT) },
|
{event: UserInputEvent.SpeedUp, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SHIFT) },
|
||||||
|
|
||||||
{event: UserInputEvent.Interact, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E) },
|
{event: UserInputEvent.Interact, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E) },
|
||||||
|
{event: UserInputEvent.Interact, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE) },
|
||||||
{event: UserInputEvent.Shout, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F) },
|
{event: UserInputEvent.Shout, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F) },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"noImplicitAny": true,
|
"module": "ESNext",
|
||||||
"module": "CommonJS",
|
"target": "ES2015",
|
||||||
"target": "es5",
|
|
||||||
"downlevelIteration": true,
|
"downlevelIteration": true,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
@ -33,6 +33,9 @@ module.exports = {
|
|||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
publicPath: '/'
|
publicPath: '/'
|
||||||
},
|
},
|
||||||
|
externals:[
|
||||||
|
require('webpack-require-http')
|
||||||
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
new HtmlWebpackPlugin(
|
new HtmlWebpackPlugin(
|
||||||
{
|
{
|
||||||
|
@ -801,6 +801,11 @@ chardet@^0.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||||
|
|
||||||
|
charenc@~0.0.1:
|
||||||
|
version "0.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
||||||
|
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
|
||||||
|
|
||||||
chokidar@^2.1.8:
|
chokidar@^2.1.8:
|
||||||
version "2.1.8"
|
version "2.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
|
||||||
@ -1063,6 +1068,11 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
|||||||
shebang-command "^1.2.0"
|
shebang-command "^1.2.0"
|
||||||
which "^1.2.9"
|
which "^1.2.9"
|
||||||
|
|
||||||
|
crypt@~0.0.1:
|
||||||
|
version "0.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
||||||
|
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
|
||||||
|
|
||||||
crypto-browserify@^3.11.0:
|
crypto-browserify@^3.11.0:
|
||||||
version "3.12.0"
|
version "3.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
||||||
@ -2350,7 +2360,7 @@ is-binary-path@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions "^1.0.0"
|
binary-extensions "^1.0.0"
|
||||||
|
|
||||||
is-buffer@^1.1.5:
|
is-buffer@^1.1.5, is-buffer@~1.1.1:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||||
|
|
||||||
@ -2691,6 +2701,15 @@ md5.js@^1.3.4:
|
|||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
safe-buffer "^5.1.2"
|
safe-buffer "^5.1.2"
|
||||||
|
|
||||||
|
md5@^2.0.0:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
|
||||||
|
integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
|
||||||
|
dependencies:
|
||||||
|
charenc "~0.0.1"
|
||||||
|
crypt "~0.0.1"
|
||||||
|
is-buffer "~1.1.1"
|
||||||
|
|
||||||
media-typer@0.3.0:
|
media-typer@0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
@ -4501,6 +4520,14 @@ webpack-merge@^4.2.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.15"
|
lodash "^4.17.15"
|
||||||
|
|
||||||
|
webpack-require-http@^0.4.3:
|
||||||
|
version "0.4.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/webpack-require-http/-/webpack-require-http-0.4.3.tgz#5690d8cc57246a53a81f1ccffd20d0394d70261c"
|
||||||
|
integrity sha1-VpDYzFckalOoHxzP/SDQOU1wJhw=
|
||||||
|
dependencies:
|
||||||
|
md5 "^2.0.0"
|
||||||
|
url "^0.11.0"
|
||||||
|
|
||||||
webpack-sources@^1.4.0, webpack-sources@^1.4.1:
|
webpack-sources@^1.4.0, webpack-sources@^1.4.1:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"
|
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"
|
||||||
|
1
maps/.gitignore
vendored
Normal file
1
maps/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/node_modules/
|
1
maps/dist/.htaccess
vendored
Normal file
1
maps/dist/.htaccess
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Header set Access-Control-Allow-Origin "*"
|
@ -0,0 +1,56 @@
|
|||||||
|
import * as Phaser from 'phaser';
|
||||||
|
import {Scene} from "phaser";
|
||||||
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
|
|
||||||
|
interface ITiledMapObject {
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tile object id
|
||||||
|
*/
|
||||||
|
gid: number;
|
||||||
|
height: number;
|
||||||
|
name: string;
|
||||||
|
properties: {[key: string]: string};
|
||||||
|
rotation: number;
|
||||||
|
type: string;
|
||||||
|
visible: boolean;
|
||||||
|
width: number;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not object is an ellipse
|
||||||
|
*/
|
||||||
|
ellipse: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polygon points
|
||||||
|
*/
|
||||||
|
polygon: {x: number, y: number}[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polyline points
|
||||||
|
*/
|
||||||
|
polyline: {x: number, y: number}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class MySprite extends Sprite {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
preload: (loader: Phaser.Loader.LoaderPlugin) => {
|
||||||
|
loader.atlas('computer', 'http://maps.workadventure.localhost/computer/computer.png', 'http://maps.workadventure.localhost/computer/computer_atlas.json');
|
||||||
|
},
|
||||||
|
create: (scene: Scene) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
factory: (scene: Scene, object: ITiledMapObject) => {
|
||||||
|
// Idée: ESSAYER WebPack? https://paultavares.wordpress.com/2018/07/02/webpack-how-to-generate-an-es-module-bundle/
|
||||||
|
let foo = new MySprite(scene, object.x, object.y, 'computer');
|
||||||
|
scene.add.existing(foo);
|
||||||
|
//scene.add.sprite(object.x, object.y, 'computer');
|
||||||
|
}
|
||||||
|
};
|
@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "workadventureback",
|
"name": "workadventuremaps",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tsc": "tsc",
|
"tsc": "tsc",
|
||||||
"dev": "ts-node-dev --respawn --transpileOnly ./server.ts",
|
"dev": "tsc -w",
|
||||||
"prod": "tsc && node ./dist/server.js",
|
"prod": "tsc",
|
||||||
"profile": "tsc && node --prof ./dist/server.js",
|
|
||||||
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
||||||
"lint": "node_modules/.bin/eslint src/ . --ext .ts",
|
"lint": "node_modules/.bin/eslint src/ . --ext .ts",
|
||||||
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts"
|
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts"
|
||||||
@ -36,22 +35,9 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/thecodingmachine/workadventure#readme",
|
"homepage": "https://github.com/thecodingmachine/workadventure#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/express": "^4.17.4",
|
"phaser": "^3.24.1",
|
||||||
"@types/http-status-codes": "^1.2.0",
|
|
||||||
"@types/jsonwebtoken": "^8.3.8",
|
|
||||||
"@types/socket.io": "^2.1.4",
|
|
||||||
"@types/uuidv4": "^5.0.0",
|
|
||||||
"body-parser": "^1.19.0",
|
|
||||||
"express": "^4.17.1",
|
|
||||||
"generic-type-guard": "^3.2.0",
|
|
||||||
"http-status-codes": "^1.4.0",
|
|
||||||
"jsonwebtoken": "^8.5.1",
|
|
||||||
"prom-client": "^12.0.0",
|
|
||||||
"socket.io": "^2.3.0",
|
|
||||||
"systeminformation": "^4.26.5",
|
|
||||||
"ts-node-dev": "^1.0.0-pre.44",
|
"ts-node-dev": "^1.0.0-pre.44",
|
||||||
"typescript": "^3.8.3",
|
"typescript": "^3.8.3"
|
||||||
"uuidv4": "^6.0.7"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jasmine": "^3.5.10",
|
"@types/jasmine": "^3.5.10",
|
||||||
|
Loading…
Reference in New Issue
Block a user