Merge pull request #1544 from thecodingmachine/property-layer-management
Implement on enters/leaves layer events
This commit is contained in:
commit
145117dc58
@ -3,19 +3,21 @@
|
|||||||
|
|
||||||
The list of functions below is **deprecated**. You should not use those but. use the replacement functions.
|
The list of functions below is **deprecated**. You should not use those but. use the replacement functions.
|
||||||
|
|
||||||
- Method `WA.sendChatMessage` is deprecated. It has been renamed to `WA.chat.sendChatMessage`.
|
- Method `WA.sendChatMessage` is deprecated. It has been renamed to [`WA.chat.sendChatMessage`](api-chat.md#sending-a-message-in-the-chat).
|
||||||
- Method `WA.disablePlayerControls` is deprecated. It has been renamed to `WA.controls.disablePlayerControls`.
|
- Method `WA.disablePlayerControls` is deprecated. It has been renamed to [`WA.controls.disablePlayerControls`](api-controls.md#disabling--restoring-controls).
|
||||||
- Method `WA.restorePlayerControls` is deprecated. It has been renamed to `WA.controls.restorePlayerControls`.
|
- Method `WA.restorePlayerControls` is deprecated. It has been renamed to [`WA.controls.restorePlayerControls`](api-controls.md#disabling--restoring-controls).
|
||||||
- Method `WA.displayBubble` is deprecated. It has been renamed to `WA.ui.displayBubble`.
|
- Method `WA.displayBubble` is deprecated. It has been renamed to `WA.ui.displayBubble`.
|
||||||
- Method `WA.removeBubble` is deprecated. It has been renamed to `WA.ui.removeBubble`.
|
- Method `WA.removeBubble` is deprecated. It has been renamed to `WA.ui.removeBubble`.
|
||||||
- Method `WA.openTab` is deprecated. It has been renamed to `WA.nav.openTab`.
|
- Method `WA.openTab` is deprecated. It has been renamed to [`WA.nav.openTab`](api-nav.md#opening-a-web-page-in-a-new-tab).
|
||||||
- Method `WA.loadSound` is deprecated. It has been renamed to `WA.sound.loadSound`.
|
- Method `WA.loadSound` is deprecated. It has been renamed to [`WA.sound.loadSound`](api-sound.md#load-a-sound-from-an-url).
|
||||||
- Method `WA.goToPage` is deprecated. It has been renamed to `WA.nav.goToPage`.
|
- Method `WA.goToPage` is deprecated. It has been renamed to [`WA.nav.goToPage`](api-nav.md#opening-a-web-page-in-the-current-tab).
|
||||||
- Method `WA.goToRoom` is deprecated. It has been renamed to `WA.nav.goToRoom`.
|
- Method `WA.goToRoom` is deprecated. It has been renamed to [`WA.nav.goToRoom`](api-nav.md#going-to-a-different-map-from-the-script).
|
||||||
- Method `WA.openCoWebSite` is deprecated. It has been renamed to `WA.nav.openCoWebSite`.
|
- Method `WA.openCoWebSite` is deprecated. It has been renamed to [`WA.nav.openCoWebSite`](api-nav.md#openingclosing-web-page-in-co-websites).
|
||||||
- Method `WA.closeCoWebSite` is deprecated. It has been renamed to `WA.nav.closeCoWebSite`.
|
- Method `WA.closeCoWebSite` is deprecated. It has been remove and [replace by a function close](api-nav.md#openingclosing-web-page-in-co-websites).
|
||||||
- Method `WA.openPopup` is deprecated. It has been renamed to `WA.ui.openPopup`.
|
- Method `WA.openPopup` is deprecated. It has been renamed to [`WA.ui.openPopup`](api-ui.md#opening-a-popup).
|
||||||
- Method `WA.onChatMessage` is deprecated. It has been renamed to `WA.chat.onChatMessage`.
|
- Method `WA.onChatMessage` is deprecated. It has been renamed to [`WA.chat.onChatMessage`](api-chat.md#listening-to-messages-from-the-chat).
|
||||||
- Method `WA.onEnterZone` is deprecated. It has been renamed to `WA.room.onEnterZone`.
|
- Method `WA.onEnterZone` is deprecated. It has been renamed to [`WA.room.onEnterZone`](api-room.md#detecting-when-the-user-entersleaves-a-layer).
|
||||||
- Method `WA.onLeaveZone` is deprecated. It has been renamed to `WA.room.onLeaveZone`.
|
- Method `WA.onLeaveZone` is deprecated. It has been renamed to [`WA.room.onLeaveZone`](api-room.md#detecting-when-the-user-entersleaves-a-layer).
|
||||||
- Method `WA.ui.registerMenuCommand` parameter `callback` is deprecated. Use `WA.ui.registerMenuCommand(commandDescriptor: string, options: MenuOptions)`.
|
- Method `WA.ui.registerMenuCommand` parameter `callback` is deprecated. Use [`WA.ui.registerMenuCommand(commandDescriptor: string, options: MenuOptions)`](api-ui.md#add-custom-menu).
|
||||||
|
- Method `WA.room.onEnterZone` is deprecated. Use instead [`WA.room.onEnterLayer`](api-room.md#detecting-when-the-user-entersleaves-a-layer).
|
||||||
|
- Method `WA.room.onLeaveZone` is deprecated. Use instead [`WA.room.onLeaveLayer`](api-room.md#detecting-when-the-user-entersleaves-a-layer).
|
@ -68,7 +68,9 @@ The event has the following attributes :
|
|||||||
* **moving (boolean):** **true** when the current player is moving, **false** otherwise.
|
* **moving (boolean):** **true** when the current player is moving, **false** otherwise.
|
||||||
* **direction (string):** **"right"** | **"left"** | **"down"** | **"top"** the direction where the current player is moving.
|
* **direction (string):** **"right"** | **"left"** | **"down"** | **"top"** the direction where the current player is moving.
|
||||||
* **x (number):** coordinate X of the current player.
|
* **x (number):** coordinate X of the current player.
|
||||||
* **y (number):** coordinate Y of the current player.
|
* **y (number):** coordinate Y of the current player.
|
||||||
|
* **oldX (number):** old coordinate X of the current player.
|
||||||
|
* **oldY (number):** old coordinate Y of the current player.
|
||||||
|
|
||||||
**callback:** the function that will be called when the current player is moving. It contains the event.
|
**callback:** the function that will be called when the current player is moving. It contains the event.
|
||||||
|
|
||||||
|
@ -17,35 +17,27 @@ The name of the layers of this map are :
|
|||||||
* `bottom/build/carpet`
|
* `bottom/build/carpet`
|
||||||
* `wall`
|
* `wall`
|
||||||
|
|
||||||
### Detecting when the user enters/leaves a zone
|
### Detecting when the user enters/leaves a layer
|
||||||
|
|
||||||
```
|
```
|
||||||
WA.room.onEnterZone(name: string, callback: () => void): void
|
WA.room.onEnterLayer(name: string): Subscription
|
||||||
WA.room.onLeaveZone(name: string, callback: () => void): void
|
WA.room.onLeaveLayer(name: string): Subscription
|
||||||
```
|
```
|
||||||
|
|
||||||
Listens to the position of the current user. The event is triggered when the user enters or leaves a given zone. The name of the zone is stored in the map, on a dedicated layer with the `zone` property.
|
Listens to the position of the current user. The event is triggered when the user enters or leaves a given layer.
|
||||||
|
|
||||||
<div>
|
* **name**: the name of the layer who as defined in Tiled.
|
||||||
<figure class="figure">
|
|
||||||
<img src="images/trigger_event.png" class="figure-img img-fluid rounded" alt="" />
|
|
||||||
<figcaption class="figure-caption">The `zone` property, applied on a layer</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
* **name**: the name of the zone, as defined in the `zone` property.
|
|
||||||
* **callback**: the function that will be called when a user enters or leaves the zone.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
WA.room.onEnterZone('myZone', () => {
|
WA.room.onEnterLayer('myLayer').subscribe(() => {
|
||||||
WA.chat.sendChatMessage("Hello!", 'Mr Robot');
|
WA.chat.sendChatMessage("Hello!", 'Mr Robot');
|
||||||
})
|
});
|
||||||
|
|
||||||
WA.room.onLeaveZone('myZone', () => {
|
WA.room.onLeaveLayer('myLayer').subscribe(() => {
|
||||||
WA.chat.sendChatMessage("Goodbye!", 'Mr Robot');
|
WA.chat.sendChatMessage("Goodbye!", 'Mr Robot');
|
||||||
})
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Show / Hide a layer
|
### Show / Hide a layer
|
||||||
@ -71,7 +63,7 @@ WA.room.setProperty(layerName : string, propertyName : string, propertyValue : s
|
|||||||
|
|
||||||
Set the value of the `propertyName` property of the layer `layerName` at `propertyValue`. If the property doesn't exist, create the property `propertyName` and set the value of the property at `propertyValue`.
|
Set the value of the `propertyName` property of the layer `layerName` at `propertyValue`. If the property doesn't exist, create the property `propertyName` and set the value of the property at `propertyValue`.
|
||||||
|
|
||||||
Note :
|
Note :
|
||||||
To unset a property from a layer, use `setProperty` with `propertyValue` set to `undefined`.
|
To unset a property from a layer, use `setProperty` with `propertyValue` set to `undefined`.
|
||||||
|
|
||||||
Example :
|
Example :
|
||||||
@ -131,7 +123,7 @@ console.log("Map generated with Tiled version ", map.tiledversion);
|
|||||||
|
|
||||||
Check the [Tiled documentation to learn more about the format of the JSON map](https://doc.mapeditor.org/en/stable/reference/json-map-format/).
|
Check the [Tiled documentation to learn more about the format of the JSON map](https://doc.mapeditor.org/en/stable/reference/json-map-format/).
|
||||||
|
|
||||||
### Changing tiles
|
### Changing tiles
|
||||||
```
|
```
|
||||||
WA.room.setTiles(tiles: TileDescriptor[]): void
|
WA.room.setTiles(tiles: TileDescriptor[]): void
|
||||||
```
|
```
|
||||||
@ -144,7 +136,7 @@ If `tile` is a string, it's not the id of the tile but the value of the property
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
`TileDescriptor` has the following attributes :
|
`TileDescriptor` has the following attributes :
|
||||||
* **x (number) :** The coordinate x of the tile that you want to replace.
|
* **x (number) :** The coordinate x of the tile that you want to replace.
|
||||||
* **y (number) :** The coordinate y of the tile that you want to replace.
|
* **y (number) :** The coordinate y of the tile that you want to replace.
|
||||||
* **tile (number | string) :** The id of the tile that will be placed in the map.
|
* **tile (number | string) :** The id of the tile that will be placed in the map.
|
||||||
@ -154,7 +146,7 @@ If `tile` is a string, it's not the id of the tile but the value of the property
|
|||||||
|
|
||||||
Note: If you want to unset a tile, use `setTiles` with `tile` set to `null`.
|
Note: If you want to unset a tile, use `setTiles` with `tile` set to `null`.
|
||||||
|
|
||||||
Example :
|
Example :
|
||||||
```javascript
|
```javascript
|
||||||
WA.room.setTiles([
|
WA.room.setTiles([
|
||||||
{x: 6, y: 4, tile: 'blue', layer: 'setTiles'},
|
{x: 6, y: 4, tile: 'blue', layer: 'setTiles'},
|
||||||
@ -246,7 +238,7 @@ const website = WA.room.website.create({
|
|||||||
WA.room.website.delete(name: string): Promise<void>
|
WA.room.website.delete(name: string): Promise<void>
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `WA.room.website.delete` to completely remove an embedded website from your map.
|
Use `WA.room.website.delete` to completely remove an embedded website from your map.
|
||||||
|
|
||||||
|
|
||||||
### The EmbeddedWebsite class
|
### The EmbeddedWebsite class
|
||||||
@ -271,7 +263,7 @@ When you modify a property of an `EmbeddedWebsite` instance, the iframe is autom
|
|||||||
|
|
||||||
|
|
||||||
{.alert.alert-warning}
|
{.alert.alert-warning}
|
||||||
The websites you add/edit/delete via the scripting API are only shown locally. If you want them
|
The websites you add/edit/delete via the scripting API are only shown locally. If you want them
|
||||||
to be displayed for every player, you can use [variables](api-start.md) to share a common state
|
to be displayed for every player, you can use [variables](api-start.md) to share a common state
|
||||||
between all users.
|
between all users.
|
||||||
|
|
||||||
|
11
front/src/Api/Events/ChangeLayerEvent.ts
Normal file
11
front/src/Api/Events/ChangeLayerEvent.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import * as tg from "generic-type-guard";
|
||||||
|
|
||||||
|
export const isChangeLayerEvent = new tg.IsInterface()
|
||||||
|
.withProperties({
|
||||||
|
name: tg.isString,
|
||||||
|
})
|
||||||
|
.get();
|
||||||
|
/**
|
||||||
|
* A message sent from the game to the iFrame when a user enters or leaves a layer.
|
||||||
|
*/
|
||||||
|
export type ChangeLayerEvent = tg.GuardedType<typeof isChangeLayerEvent>;
|
@ -6,6 +6,8 @@ export const isHasPlayerMovedEvent = new tg.IsInterface()
|
|||||||
moving: tg.isBoolean,
|
moving: tg.isBoolean,
|
||||||
x: tg.isNumber,
|
x: tg.isNumber,
|
||||||
y: tg.isNumber,
|
y: tg.isNumber,
|
||||||
|
oldX: tg.isOptional(tg.isNumber),
|
||||||
|
oldY: tg.isOptional(tg.isNumber),
|
||||||
})
|
})
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import type {
|
|||||||
} from "./ui/TriggerActionMessageEvent";
|
} from "./ui/TriggerActionMessageEvent";
|
||||||
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
|
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
|
||||||
import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
|
import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
|
||||||
|
import type { ChangeLayerEvent } from "./ChangeLayerEvent";
|
||||||
|
|
||||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||||
data: T;
|
data: T;
|
||||||
@ -75,6 +76,8 @@ export interface IframeResponseEventMap {
|
|||||||
userInputChat: UserInputChatEvent;
|
userInputChat: UserInputChatEvent;
|
||||||
enterEvent: EnterLeaveEvent;
|
enterEvent: EnterLeaveEvent;
|
||||||
leaveEvent: EnterLeaveEvent;
|
leaveEvent: EnterLeaveEvent;
|
||||||
|
enterLayerEvent: ChangeLayerEvent;
|
||||||
|
leaveLayerEvent: ChangeLayerEvent;
|
||||||
buttonClickedEvent: ButtonClickedEvent;
|
buttonClickedEvent: ButtonClickedEvent;
|
||||||
hasPlayerMoved: HasPlayerMovedEvent;
|
hasPlayerMoved: HasPlayerMovedEvent;
|
||||||
menuItemClicked: MenuItemClickedEvent;
|
menuItemClicked: MenuItemClickedEvent;
|
||||||
|
@ -30,6 +30,7 @@ import { SetTilesEvent, isSetTilesEvent } from "./Events/SetTilesEvent";
|
|||||||
import type { SetVariableEvent } from "./Events/SetVariableEvent";
|
import type { SetVariableEvent } from "./Events/SetVariableEvent";
|
||||||
import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent";
|
import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent";
|
||||||
import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore";
|
import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore";
|
||||||
|
import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent";
|
||||||
|
|
||||||
type AnswererCallback<T extends keyof IframeQueryMap> = (
|
type AnswererCallback<T extends keyof IframeQueryMap> = (
|
||||||
query: IframeQueryMap[T]["query"],
|
query: IframeQueryMap[T]["query"],
|
||||||
@ -395,6 +396,24 @@ class IframeListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendEnterLayerEvent(layerName: string) {
|
||||||
|
this.postMessage({
|
||||||
|
type: "enterLayerEvent",
|
||||||
|
data: {
|
||||||
|
name: layerName,
|
||||||
|
} as ChangeLayerEvent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendLeaveLayerEvent(layerName: string) {
|
||||||
|
this.postMessage({
|
||||||
|
type: "leaveLayerEvent",
|
||||||
|
data: {
|
||||||
|
name: layerName,
|
||||||
|
} as ChangeLayerEvent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
hasPlayerMoved(event: HasPlayerMovedEvent) {
|
hasPlayerMoved(event: HasPlayerMovedEvent) {
|
||||||
if (this.sendPlayerMove) {
|
if (this.sendPlayerMove) {
|
||||||
this.postMessage({
|
this.postMessage({
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Subject } from "rxjs";
|
import { Subject } from "rxjs";
|
||||||
|
|
||||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
||||||
|
import { ChangeLayerEvent, isChangeLayerEvent } from "../Events/ChangeLayerEvent";
|
||||||
|
|
||||||
import { IframeApiContribution, queryWorkadventure, sendToWorkadventure } from "./IframeApiContribution";
|
import { IframeApiContribution, queryWorkadventure, sendToWorkadventure } from "./IframeApiContribution";
|
||||||
import { apiCallback } from "./registeredCallbacks";
|
import { apiCallback } from "./registeredCallbacks";
|
||||||
@ -12,6 +13,9 @@ import website from "./website";
|
|||||||
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||||
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||||
|
|
||||||
|
const enterLayerStreams: Map<string, Subject<void>> = new Map<string, Subject<void>>();
|
||||||
|
const leaveLayerStreams: Map<string, Subject<void>> = new Map<string, Subject<void>>();
|
||||||
|
|
||||||
interface TileDescriptor {
|
interface TileDescriptor {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
@ -47,8 +51,25 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
|||||||
leaveStreams.get(payloadData.name)?.next();
|
leaveStreams.get(payloadData.name)?.next();
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
apiCallback({
|
||||||
|
type: "enterLayerEvent",
|
||||||
|
typeChecker: isChangeLayerEvent,
|
||||||
|
callback: (payloadData: ChangeLayerEvent) => {
|
||||||
|
enterLayerStreams.get(payloadData.name)?.next();
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apiCallback({
|
||||||
|
type: "leaveLayerEvent",
|
||||||
|
typeChecker: isChangeLayerEvent,
|
||||||
|
callback: (payloadData) => {
|
||||||
|
leaveLayerStreams.get(payloadData.name)?.next();
|
||||||
|
},
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use onEnterLayer instead
|
||||||
|
*/
|
||||||
onEnterZone(name: string, callback: () => void): void {
|
onEnterZone(name: string, callback: () => void): void {
|
||||||
let subject = enterStreams.get(name);
|
let subject = enterStreams.get(name);
|
||||||
if (subject === undefined) {
|
if (subject === undefined) {
|
||||||
@ -57,6 +78,10 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
|||||||
}
|
}
|
||||||
subject.subscribe(callback);
|
subject.subscribe(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use onLeaveLayer instead
|
||||||
|
*/
|
||||||
onLeaveZone(name: string, callback: () => void): void {
|
onLeaveZone(name: string, callback: () => void): void {
|
||||||
let subject = leaveStreams.get(name);
|
let subject = leaveStreams.get(name);
|
||||||
if (subject === undefined) {
|
if (subject === undefined) {
|
||||||
@ -65,12 +90,35 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
|||||||
}
|
}
|
||||||
subject.subscribe(callback);
|
subject.subscribe(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEnterLayer(layerName: string): Subject<void> {
|
||||||
|
let subject = enterLayerStreams.get(layerName);
|
||||||
|
if (subject === undefined) {
|
||||||
|
subject = new Subject<ChangeLayerEvent>();
|
||||||
|
enterLayerStreams.set(layerName, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
onLeaveLayer(layerName: string): Subject<void> {
|
||||||
|
let subject = leaveLayerStreams.get(layerName);
|
||||||
|
if (subject === undefined) {
|
||||||
|
subject = new Subject<ChangeLayerEvent>();
|
||||||
|
leaveLayerStreams.set(layerName, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
showLayer(layerName: string): void {
|
showLayer(layerName: string): void {
|
||||||
sendToWorkadventure({ type: "showLayer", data: { name: layerName } });
|
sendToWorkadventure({ type: "showLayer", data: { name: layerName } });
|
||||||
}
|
}
|
||||||
|
|
||||||
hideLayer(layerName: string): void {
|
hideLayer(layerName: string): void {
|
||||||
sendToWorkadventure({ type: "hideLayer", data: { name: layerName } });
|
sendToWorkadventure({ type: "hideLayer", data: { name: layerName } });
|
||||||
}
|
}
|
||||||
|
|
||||||
setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
|
setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
|
||||||
sendToWorkadventure({
|
sendToWorkadventure({
|
||||||
type: "setProperty",
|
type: "setProperty",
|
||||||
@ -81,10 +129,12 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTiledMap(): Promise<ITiledMap> {
|
async getTiledMap(): Promise<ITiledMap> {
|
||||||
const event = await queryWorkadventure({ type: "getMapData", data: undefined });
|
const event = await queryWorkadventure({ type: "getMapData", data: undefined });
|
||||||
return event.data as ITiledMap;
|
return event.data as ITiledMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTiles(tiles: TileDescriptor[]) {
|
setTiles(tiles: TileDescriptor[]) {
|
||||||
sendToWorkadventure({
|
sendToWorkadventure({
|
||||||
type: "setTiles",
|
type: "setTiles",
|
||||||
|
@ -2,6 +2,7 @@ import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiled
|
|||||||
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
||||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
||||||
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
|
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
|
||||||
|
import { iframeListener } from "../../Api/IframeListener";
|
||||||
|
|
||||||
export type PropertyChangeCallback = (
|
export type PropertyChangeCallback = (
|
||||||
newValue: string | number | boolean | undefined,
|
newValue: string | number | boolean | undefined,
|
||||||
@ -9,14 +10,25 @@ export type PropertyChangeCallback = (
|
|||||||
allProps: Map<string, string | boolean | number>
|
allProps: Map<string, string | boolean | number>
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
|
export type layerChangeCallback = (
|
||||||
|
layersChangedByAction: Array<ITiledMapLayer>,
|
||||||
|
allLayersOnNewPosition: Array<ITiledMapLayer>,
|
||||||
|
|
||||||
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around a ITiledMap interface to provide additional capabilities.
|
* A wrapper around a ITiledMap interface to provide additional capabilities.
|
||||||
* It is used to handle layer properties.
|
* It is used to handle layer properties.
|
||||||
*/
|
*/
|
||||||
export class GameMap {
|
export class GameMap {
|
||||||
|
// oldKey is the index of the previous tile.
|
||||||
|
private oldKey: number | undefined;
|
||||||
|
// key is the index of the current tile.
|
||||||
private key: number | undefined;
|
private key: number | undefined;
|
||||||
private lastProperties = new Map<string, string | boolean | number>();
|
private lastProperties = new Map<string, string | boolean | number>();
|
||||||
private callbacks = new Map<string, Array<PropertyChangeCallback>>();
|
private propertiesChangeCallbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||||
|
private enterLayerCallbacks = Array<layerChangeCallback>();
|
||||||
|
private leaveLayerCallbacks = Array<layerChangeCallback>();
|
||||||
private tileNameMap = new Map<string, number>();
|
private tileNameMap = new Map<string, number>();
|
||||||
|
|
||||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapProperty> } = {};
|
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapProperty> } = {};
|
||||||
@ -68,22 +80,32 @@ export class GameMap {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getLayersByKey(key: number): Array<ITiledMapLayer> {
|
||||||
|
return this.flatLayers.filter(flatLayer => flatLayer.type === 'tilelayer' && flatLayer.data[key] !== 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the position of the current player (in pixels)
|
* Sets the position of the current player (in pixels)
|
||||||
* This will trigger events if properties are changing.
|
* This will trigger events if properties are changing.
|
||||||
*/
|
*/
|
||||||
public setPosition(x: number, y: number) {
|
public setPosition(x: number, y: number) {
|
||||||
|
this.oldKey = this.key;
|
||||||
|
|
||||||
const xMap = Math.floor(x / this.map.tilewidth);
|
const xMap = Math.floor(x / this.map.tilewidth);
|
||||||
const yMap = Math.floor(y / this.map.tileheight);
|
const yMap = Math.floor(y / this.map.tileheight);
|
||||||
const key = xMap + yMap * this.map.width;
|
const key = xMap + yMap * this.map.width;
|
||||||
|
|
||||||
if (key === this.key) {
|
if (key === this.key) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.triggerAll();
|
|
||||||
|
this.triggerAllProperties();
|
||||||
|
this.triggerLayersChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
private triggerAll(): void {
|
private triggerAllProperties(): void {
|
||||||
const newProps = this.getProperties(this.key ?? 0);
|
const newProps = this.getProperties(this.key ?? 0);
|
||||||
const oldProps = this.lastProperties;
|
const oldProps = this.lastProperties;
|
||||||
this.lastProperties = newProps;
|
this.lastProperties = newProps;
|
||||||
@ -105,6 +127,36 @@ export class GameMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private triggerLayersChange() {
|
||||||
|
const layersByOldKey = this.oldKey ? this.getLayersByKey(this.oldKey) : [];
|
||||||
|
const layersByNewKey = this.key ? this.getLayersByKey(this.key) : [];
|
||||||
|
|
||||||
|
const enterLayers = new Set(layersByNewKey);
|
||||||
|
const leaveLayers = new Set(layersByOldKey);
|
||||||
|
|
||||||
|
enterLayers.forEach(layer => {
|
||||||
|
if (leaveLayers.has(layer)) {
|
||||||
|
leaveLayers.delete(layer);
|
||||||
|
enterLayers.delete(layer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (enterLayers.size > 0) {
|
||||||
|
const layerArray = Array.from(enterLayers);
|
||||||
|
for (const callback of this.enterLayerCallbacks) {
|
||||||
|
callback(layerArray, layersByNewKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leaveLayers.size > 0) {
|
||||||
|
const layerArray = Array.from(leaveLayers);
|
||||||
|
for (const callback of this.leaveLayerCallbacks) {
|
||||||
|
callback(layerArray, layersByNewKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public getCurrentProperties(): Map<string, string | boolean | number> {
|
public getCurrentProperties(): Map<string, string | boolean | number> {
|
||||||
return this.lastProperties;
|
return this.lastProperties;
|
||||||
}
|
}
|
||||||
@ -167,7 +219,7 @@ export class GameMap {
|
|||||||
newValue: string | number | boolean | undefined,
|
newValue: string | number | boolean | undefined,
|
||||||
allProps: Map<string, string | boolean | number>
|
allProps: Map<string, string | boolean | number>
|
||||||
) {
|
) {
|
||||||
const callbacksArray = this.callbacks.get(propName);
|
const callbacksArray = this.propertiesChangeCallbacks.get(propName);
|
||||||
if (callbacksArray !== undefined) {
|
if (callbacksArray !== undefined) {
|
||||||
for (const callback of callbacksArray) {
|
for (const callback of callbacksArray) {
|
||||||
callback(newValue, oldValue, allProps);
|
callback(newValue, oldValue, allProps);
|
||||||
@ -179,14 +231,28 @@ export class GameMap {
|
|||||||
* Registers a callback called when the user moves to a tile where the property propName is different from the last tile the user was on.
|
* Registers a callback called when the user moves to a tile where the property propName is different from the last tile the user was on.
|
||||||
*/
|
*/
|
||||||
public onPropertyChange(propName: string, callback: PropertyChangeCallback) {
|
public onPropertyChange(propName: string, callback: PropertyChangeCallback) {
|
||||||
let callbacksArray = this.callbacks.get(propName);
|
let callbacksArray = this.propertiesChangeCallbacks.get(propName);
|
||||||
if (callbacksArray === undefined) {
|
if (callbacksArray === undefined) {
|
||||||
callbacksArray = new Array<PropertyChangeCallback>();
|
callbacksArray = new Array<PropertyChangeCallback>();
|
||||||
this.callbacks.set(propName, callbacksArray);
|
this.propertiesChangeCallbacks.set(propName, callbacksArray);
|
||||||
}
|
}
|
||||||
callbacksArray.push(callback);
|
callbacksArray.push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a callback called when the user moves inside another layer.
|
||||||
|
*/
|
||||||
|
public onEnterLayer(callback: layerChangeCallback) {
|
||||||
|
this.enterLayerCallbacks.push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a callback called when the user moves outside another layer.
|
||||||
|
*/
|
||||||
|
public onLeaveLayer(callback: layerChangeCallback) {
|
||||||
|
this.leaveLayerCallbacks.push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
public findLayer(layerName: string): ITiledMapLayer | undefined {
|
public findLayer(layerName: string): ITiledMapLayer | undefined {
|
||||||
return this.flatLayers.find((layer) => layer.name === layerName);
|
return this.flatLayers.find((layer) => layer.name === layerName);
|
||||||
}
|
}
|
||||||
@ -284,7 +350,8 @@ export class GameMap {
|
|||||||
}
|
}
|
||||||
property.value = propertyValue;
|
property.value = propertyValue;
|
||||||
|
|
||||||
this.triggerAll();
|
this.triggerAllProperties();
|
||||||
|
this.triggerLayersChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,15 +1,32 @@
|
|||||||
import type { GameScene } from "./GameScene";
|
import type { GameScene } from "./GameScene";
|
||||||
import type { GameMap } from "./GameMap";
|
import type { GameMap } from "./GameMap";
|
||||||
import { scriptUtils } from "../../Api/ScriptUtils";
|
import { scriptUtils } from "../../Api/ScriptUtils";
|
||||||
|
import type { CoWebsite } from "../../WebRtc/CoWebsiteManager";
|
||||||
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
|
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
|
||||||
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
|
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
|
||||||
|
import { get } from 'svelte/store';
|
||||||
import {
|
import {
|
||||||
ON_ACTION_TRIGGER_BUTTON,
|
ON_ACTION_TRIGGER_BUTTON,
|
||||||
TRIGGER_WEBSITE_PROPERTIES,
|
TRIGGER_WEBSITE_PROPERTIES,
|
||||||
WEBSITE_MESSAGE_PROPERTIES,
|
WEBSITE_MESSAGE_PROPERTIES,
|
||||||
} from "../../WebRtc/LayoutManager";
|
} from "../../WebRtc/LayoutManager";
|
||||||
|
import type { ITiledMapLayer } from "../Map/ITiledMap";
|
||||||
|
|
||||||
|
enum OpenCoWebsiteState {
|
||||||
|
LOADING,
|
||||||
|
OPENED,
|
||||||
|
MUST_BE_CLOSE,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OpenCoWebsite {
|
||||||
|
coWebsite: CoWebsite | undefined,
|
||||||
|
state: OpenCoWebsiteState
|
||||||
|
}
|
||||||
|
|
||||||
export class GameMapPropertiesListener {
|
export class GameMapPropertiesListener {
|
||||||
|
private coWebsitesOpenByLayer = new Map<ITiledMapLayer, OpenCoWebsite>();
|
||||||
|
private coWebsitesActionTriggerByLayer = new Map<ITiledMapLayer, string>();
|
||||||
|
|
||||||
constructor(private scene: GameScene, private gameMap: GameMap) {}
|
constructor(private scene: GameScene, private gameMap: GameMap) {}
|
||||||
|
|
||||||
register() {
|
register() {
|
||||||
@ -36,42 +53,178 @@ export class GameMapPropertiesListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.gameMap.onPropertyChange("openWebsite", (newValue, oldValue, allProps) => {
|
|
||||||
const handler = async () => {
|
|
||||||
if (newValue === undefined || newValue !== oldValue) {
|
|
||||||
layoutManagerActionStore.removeAction("openWebsite");
|
|
||||||
await coWebsiteManager.closeCoWebsites();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newValue !== undefined) {
|
// Open a new co-website by the property.
|
||||||
|
this.gameMap.onEnterLayer((newLayers) => {
|
||||||
|
const handler = () => {
|
||||||
|
newLayers.forEach(layer => {
|
||||||
|
if (!layer.properties) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let openWebsiteProperty: string | undefined;
|
||||||
|
let allowApiProperty: boolean | undefined;
|
||||||
|
let websitePolicyProperty: string | undefined;
|
||||||
|
let websiteWidthProperty: number | undefined;
|
||||||
|
let websitePositionProperty: number | undefined;
|
||||||
|
let websiteTriggerProperty: string | undefined;
|
||||||
|
let websiteTriggerMessageProperty: string | undefined;
|
||||||
|
|
||||||
|
layer.properties.forEach(property => {
|
||||||
|
switch(property.name) {
|
||||||
|
case 'openWebsite':
|
||||||
|
openWebsiteProperty = property.value as string | undefined;
|
||||||
|
break;
|
||||||
|
case 'openWebsiteAllowApi':
|
||||||
|
allowApiProperty = property.value as boolean | undefined;
|
||||||
|
break;
|
||||||
|
case 'openWebsitePolicy':
|
||||||
|
websitePolicyProperty = property.value as string | undefined;
|
||||||
|
break;
|
||||||
|
case 'openWebsiteWidth':
|
||||||
|
websiteWidthProperty = property.value as number | undefined;
|
||||||
|
break;
|
||||||
|
case 'openWebsitePosition':
|
||||||
|
websitePositionProperty = property.value as number | undefined;
|
||||||
|
break;
|
||||||
|
case TRIGGER_WEBSITE_PROPERTIES:
|
||||||
|
websiteTriggerProperty = property.value as string | undefined;
|
||||||
|
break;
|
||||||
|
case WEBSITE_MESSAGE_PROPERTIES:
|
||||||
|
websiteTriggerMessageProperty = property.value as string | undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!openWebsiteProperty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionUuid = "openWebsite-" + (Math.random() + 1).toString(36).substring(7);
|
||||||
|
|
||||||
|
if (this.coWebsitesOpenByLayer.has(layer)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.coWebsitesOpenByLayer.set(layer, {
|
||||||
|
coWebsite: undefined,
|
||||||
|
state: OpenCoWebsiteState.LOADING,
|
||||||
|
});
|
||||||
|
|
||||||
const openWebsiteFunction = () => {
|
const openWebsiteFunction = () => {
|
||||||
coWebsiteManager.loadCoWebsite(
|
coWebsiteManager.loadCoWebsite(
|
||||||
newValue as string,
|
openWebsiteProperty as string,
|
||||||
this.scene.MapUrlFile,
|
this.scene.MapUrlFile,
|
||||||
allProps.get("openWebsiteAllowApi") as boolean | undefined,
|
allowApiProperty,
|
||||||
allProps.get("openWebsitePolicy") as string | undefined,
|
websitePolicyProperty,
|
||||||
allProps.get("openWebsiteWidth") as number | undefined
|
websiteWidthProperty,
|
||||||
);
|
websitePositionProperty,
|
||||||
|
).then(coWebsite => {
|
||||||
|
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||||
|
if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
|
||||||
|
coWebsiteManager.closeCoWebsite(coWebsite);
|
||||||
|
this.coWebsitesOpenByLayer.delete(layer);
|
||||||
|
this.coWebsitesActionTriggerByLayer.delete(layer);
|
||||||
|
} else {
|
||||||
|
this.coWebsitesOpenByLayer.set(layer, {
|
||||||
|
coWebsite,
|
||||||
|
state: OpenCoWebsiteState.OPENED
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
layoutManagerActionStore.removeAction("openWebsite");
|
layoutManagerActionStore.removeAction(actionUuid);
|
||||||
};
|
};
|
||||||
const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES);
|
|
||||||
if (openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) {
|
if (websiteTriggerProperty && websiteTriggerProperty === ON_ACTION_TRIGGER_BUTTON) {
|
||||||
let message = allProps.get(WEBSITE_MESSAGE_PROPERTIES);
|
if (!websiteTriggerMessageProperty) {
|
||||||
if (message === undefined) {
|
websiteTriggerMessageProperty = "Press SPACE or touch here to open web site";
|
||||||
message = "Press SPACE or touch here to open web site";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.coWebsitesActionTriggerByLayer.set(layer, actionUuid);
|
||||||
|
|
||||||
layoutManagerActionStore.addAction({
|
layoutManagerActionStore.addAction({
|
||||||
uuid: "openWebsite",
|
uuid: actionUuid,
|
||||||
type: "message",
|
type: "message",
|
||||||
message: message,
|
message: websiteTriggerMessageProperty,
|
||||||
callback: () => openWebsiteFunction(),
|
callback: () => openWebsiteFunction(),
|
||||||
userInputManager: this.scene.userInputManager,
|
userInputManager: this.scene.userInputManager,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
openWebsiteFunction();
|
openWebsiteFunction();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handler();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close opened co-websites on leave the layer who contain the property.
|
||||||
|
this.gameMap.onLeaveLayer((oldLayers) => {
|
||||||
|
const handler = () => {
|
||||||
|
oldLayers.forEach(layer => {
|
||||||
|
if (!layer.properties) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let openWebsiteProperty: string | undefined;
|
||||||
|
let websiteTriggerProperty: string | undefined;
|
||||||
|
|
||||||
|
layer.properties.forEach(property => {
|
||||||
|
switch(property.name) {
|
||||||
|
case 'openWebsite':
|
||||||
|
openWebsiteProperty = property.value as string | undefined;
|
||||||
|
break;
|
||||||
|
case TRIGGER_WEBSITE_PROPERTIES:
|
||||||
|
websiteTriggerProperty = property.value as string | undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!openWebsiteProperty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||||
|
|
||||||
|
if (!coWebsiteOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coWebsiteOpen.state === OpenCoWebsiteState.LOADING) {
|
||||||
|
coWebsiteOpen.state = OpenCoWebsiteState.MUST_BE_CLOSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coWebsiteOpen.state !== OpenCoWebsiteState.OPENED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coWebsiteOpen.coWebsite !== undefined) {
|
||||||
|
coWebsiteManager.closeCoWebsite(coWebsiteOpen.coWebsite);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.coWebsitesOpenByLayer.delete(layer);
|
||||||
|
|
||||||
|
if (!websiteTriggerProperty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionStore = get(layoutManagerActionStore);
|
||||||
|
const actionTriggerUuid = this.coWebsitesActionTriggerByLayer.get(layer);
|
||||||
|
|
||||||
|
if (!actionTriggerUuid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = actionStore && actionStore.length > 0 ?
|
||||||
|
actionStore.find(action => action.uuid === actionTriggerUuid) : undefined;
|
||||||
|
|
||||||
|
|
||||||
|
if (action) {
|
||||||
|
layoutManagerActionStore.removeAction(actionTriggerUuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handler();
|
handler();
|
||||||
|
@ -186,6 +186,8 @@ export class GameScene extends DirtyScene {
|
|||||||
moving: false,
|
moving: false,
|
||||||
x: -1000,
|
x: -1000,
|
||||||
y: -1000,
|
y: -1000,
|
||||||
|
oldX: -1000,
|
||||||
|
oldY: -1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
private gameMap!: GameMap;
|
private gameMap!: GameMap;
|
||||||
@ -764,6 +766,19 @@ export class GameScene extends DirtyScene {
|
|||||||
|
|
||||||
//init user position and play trigger to check layers properties
|
//init user position and play trigger to check layers properties
|
||||||
this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y);
|
this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y);
|
||||||
|
|
||||||
|
// Init layer change listener
|
||||||
|
this.gameMap.onEnterLayer(layers => {
|
||||||
|
layers.forEach(layer => {
|
||||||
|
iframeListener.sendEnterLayerEvent(layer.name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.gameMap.onLeaveLayer(layers => {
|
||||||
|
layers.forEach(layer => {
|
||||||
|
iframeListener.sendLeaveLayerEvent(layer.name);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,6 +910,7 @@ export class GameScene extends DirtyScene {
|
|||||||
audioManagerVisibilityStore.set(!(newValue === undefined));
|
audioManagerVisibilityStore.set(!(newValue === undefined));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Legacy functionnality replace by layer change
|
||||||
this.gameMap.onPropertyChange("zone", (newValue, oldValue) => {
|
this.gameMap.onPropertyChange("zone", (newValue, oldValue) => {
|
||||||
if (oldValue) {
|
if (oldValue) {
|
||||||
iframeListener.sendLeaveEvent(oldValue as string);
|
iframeListener.sendLeaveEvent(oldValue as string);
|
||||||
@ -1749,7 +1765,11 @@ ${escapedMessage}
|
|||||||
const playerMovement = new PlayerMovement(
|
const playerMovement = new PlayerMovement(
|
||||||
{ x: player.x, y: player.y },
|
{ x: player.x, y: player.y },
|
||||||
this.currentTick,
|
this.currentTick,
|
||||||
message.position,
|
{
|
||||||
|
...message.position,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
|
},
|
||||||
this.currentTick + POSITION_DELAY
|
this.currentTick + POSITION_DELAY
|
||||||
);
|
);
|
||||||
this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement);
|
this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement);
|
||||||
|
@ -38,6 +38,8 @@ export class PlayerMovement {
|
|||||||
return {
|
return {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
oldX: this.startPosition.x,
|
||||||
|
oldY: this.startPosition.y,
|
||||||
direction: this.endPosition.direction,
|
direction: this.endPosition.direction,
|
||||||
moving: true,
|
moving: true,
|
||||||
};
|
};
|
||||||
|
@ -64,14 +64,14 @@ export class Player extends Character {
|
|||||||
|
|
||||||
if (x !== 0 || y !== 0) {
|
if (x !== 0 || y !== 0) {
|
||||||
this.move(x, y);
|
this.move(x, y);
|
||||||
this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y });
|
this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y, oldX: x, oldY: y });
|
||||||
} else if (this.wasMoving && moving) {
|
} else if (this.wasMoving && moving) {
|
||||||
// slow joystick movement
|
// slow joystick movement
|
||||||
this.move(0, 0);
|
this.move(0, 0);
|
||||||
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y });
|
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y, oldX: x, oldY: y });
|
||||||
} else if (this.wasMoving && !moving) {
|
} else if (this.wasMoving && !moving) {
|
||||||
this.stop();
|
this.stop();
|
||||||
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y });
|
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y, oldX: x, oldY: y });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction !== null) {
|
if (direction !== null) {
|
||||||
|
@ -9,7 +9,9 @@ export interface LayoutManagerAction {
|
|||||||
userInputManager: UserInputManager | undefined;
|
userInputManager: UserInputManager | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function createLayoutManagerAction() {
|
function createLayoutManagerAction() {
|
||||||
|
|
||||||
const { subscribe, set, update } = writable<LayoutManagerAction[]>([]);
|
const { subscribe, set, update } = writable<LayoutManagerAction[]>([]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -7,7 +7,12 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
x: 100, y: 200
|
x: 100, y: 200
|
||||||
}, 42000,
|
}, 42000,
|
||||||
{
|
{
|
||||||
x: 200, y: 100, moving: true, direction: "up"
|
x: 200,
|
||||||
|
y: 100,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
|
moving: true,
|
||||||
|
direction: "up"
|
||||||
},
|
},
|
||||||
42200
|
42200
|
||||||
);
|
);
|
||||||
@ -19,6 +24,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
expect(playerMovement.getPosition(42100)).toEqual({
|
expect(playerMovement.getPosition(42100)).toEqual({
|
||||||
x: 150,
|
x: 150,
|
||||||
y: 150,
|
y: 150,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
direction: 'up',
|
direction: 'up',
|
||||||
moving: true
|
moving: true
|
||||||
});
|
});
|
||||||
@ -26,6 +33,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
expect(playerMovement.getPosition(42200)).toEqual({
|
expect(playerMovement.getPosition(42200)).toEqual({
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 100,
|
y: 100,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
direction: 'up',
|
direction: 'up',
|
||||||
moving: true
|
moving: true
|
||||||
});
|
});
|
||||||
@ -33,6 +42,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
expect(playerMovement.getPosition(42300)).toEqual({
|
expect(playerMovement.getPosition(42300)).toEqual({
|
||||||
x: 250,
|
x: 250,
|
||||||
y: 50,
|
y: 50,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
direction: 'up',
|
direction: 'up',
|
||||||
moving: true
|
moving: true
|
||||||
});
|
});
|
||||||
@ -43,7 +54,12 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
x: 100, y: 200
|
x: 100, y: 200
|
||||||
}, 42000,
|
}, 42000,
|
||||||
{
|
{
|
||||||
x: 200, y: 100, moving: false, direction: "up"
|
x: 200,
|
||||||
|
y: 100,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
|
moving: false,
|
||||||
|
direction: "up"
|
||||||
},
|
},
|
||||||
42200
|
42200
|
||||||
);
|
);
|
||||||
@ -51,6 +67,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
expect(playerMovement.getPosition(42300)).toEqual({
|
expect(playerMovement.getPosition(42300)).toEqual({
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 100,
|
y: 100,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
direction: 'up',
|
direction: 'up',
|
||||||
moving: false
|
moving: false
|
||||||
});
|
});
|
||||||
@ -61,7 +79,12 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
x: 100, y: 200
|
x: 100, y: 200
|
||||||
}, 42000,
|
}, 42000,
|
||||||
{
|
{
|
||||||
x: 200, y: 100, moving: false, direction: "up"
|
x: 200,
|
||||||
|
y: 100,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
|
moving: false,
|
||||||
|
direction: "up"
|
||||||
},
|
},
|
||||||
42200
|
42200
|
||||||
);
|
);
|
||||||
@ -69,6 +92,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||||||
expect(playerMovement.getPosition(42100)).toEqual({
|
expect(playerMovement.getPosition(42100)).toEqual({
|
||||||
x: 150,
|
x: 150,
|
||||||
y: 150,
|
y: 150,
|
||||||
|
oldX: undefined,
|
||||||
|
oldY: undefined,
|
||||||
direction: 'up',
|
direction: 'up',
|
||||||
moving: true
|
moving: true
|
||||||
});
|
});
|
||||||
|
617
maps/tests/ChangeLayerApi/change_layer_api.json
Normal file
617
maps/tests/ChangeLayerApi/change_layer_api.json
Normal file
@ -0,0 +1,617 @@
|
|||||||
|
{ "compressionlevel":-1,
|
||||||
|
"height":10,
|
||||||
|
"infinite":false,
|
||||||
|
"layers":[
|
||||||
|
{
|
||||||
|
"data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
"height":10,
|
||||||
|
"id":1,
|
||||||
|
"name":"floor",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":2,
|
||||||
|
"name":"start",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23],
|
||||||
|
"height":10,
|
||||||
|
"id":5,
|
||||||
|
"name":"myLayer",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"draworder":"topdown",
|
||||||
|
"id":3,
|
||||||
|
"name":"floorLayer",
|
||||||
|
"objects":[
|
||||||
|
{
|
||||||
|
"height":111.874771331266,
|
||||||
|
"id":1,
|
||||||
|
"name":"Tests",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"fontfamily":"Sans Serif",
|
||||||
|
"pixelsize":8,
|
||||||
|
"text":"Test 1:\nGo on the blue carpet.\nResult:\nA message has been sent to the chat.\n\nTest 2:\nGo outside the blue carpet.\nResult:\nAnother message has been sent to the chat.\n",
|
||||||
|
"wrap":true
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":316.770833333333,
|
||||||
|
"x":1.64026713939023,
|
||||||
|
"y":206.086424886945
|
||||||
|
}],
|
||||||
|
"opacity":1,
|
||||||
|
"type":"objectgroup",
|
||||||
|
"visible":true,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 27, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":8,
|
||||||
|
"name":"objects",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
}],
|
||||||
|
"nextlayerid":9,
|
||||||
|
"nextobjectid":3,
|
||||||
|
"orientation":"orthogonal",
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"script",
|
||||||
|
"type":"string",
|
||||||
|
"value":"script.js"
|
||||||
|
}],
|
||||||
|
"renderorder":"right-down",
|
||||||
|
"tiledversion":"1.7.2",
|
||||||
|
"tileheight":32,
|
||||||
|
"tilesets":[
|
||||||
|
{
|
||||||
|
"columns":11,
|
||||||
|
"firstgid":1,
|
||||||
|
"image":"..\/tileset1.png",
|
||||||
|
"imageheight":352,
|
||||||
|
"imagewidth":352,
|
||||||
|
"margin":0,
|
||||||
|
"name":"tileset1",
|
||||||
|
"spacing":0,
|
||||||
|
"tilecount":121,
|
||||||
|
"tileheight":32,
|
||||||
|
"tiles":[
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":2,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":3,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":4,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":5,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":6,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":7,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":8,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":9,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":10,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":12,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":16,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":17,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":18,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":19,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":20,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":21,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":23,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":24,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":25,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":26,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":27,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":28,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":29,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":30,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":31,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":32,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":34,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":35,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":42,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":43,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":45,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":46,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":59,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":60,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":70,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":71,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":80,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":81,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":89,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":91,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":93,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":94,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":95,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":96,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":97,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":100,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":102,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":103,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":104,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":105,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":106,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":107,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":108,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":114,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":115,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"tilewidth":32
|
||||||
|
}],
|
||||||
|
"tilewidth":32,
|
||||||
|
"type":"map",
|
||||||
|
"version":"1.6",
|
||||||
|
"width":10
|
||||||
|
}
|
7
maps/tests/ChangeLayerApi/script.js
Normal file
7
maps/tests/ChangeLayerApi/script.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
WA.room.onEnterLayer('myLayer').subscribe(() => {
|
||||||
|
WA.chat.sendChatMessage("Hello!", 'Wooka');
|
||||||
|
});
|
||||||
|
|
||||||
|
WA.room.onLeaveLayer('myLayer').subscribe(() => {
|
||||||
|
WA.chat.sendChatMessage("Goodbye!", 'Wooka');
|
||||||
|
});
|
@ -235,6 +235,14 @@
|
|||||||
<a href="#" class="testLink" data-testmap="EmbeddedWebsite/website_in_map_script.json" target="_blank">Testing scripting API for websites inside a map</a>
|
<a href="#" class="testLink" data-testmap="EmbeddedWebsite/website_in_map_script.json" target="_blank">Testing scripting API for websites inside a map</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="radio" name="test-change-layer-api"> Success <input type="radio" name="test-change-layer-api"> Failure <input type="radio" name="test-change-layer-api" checked> Pending
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="#" class="testLink" data-testmap="ChangeLayerApi/change_layer_api.json" target="_blank">Testing scripting API for enters/leaves layer</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<h2>CoWebsite</h2>
|
<h2>CoWebsite</h2>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
@ -243,7 +251,7 @@
|
|||||||
<input type="radio" name="test-cowebsite-property"> Success <input type="radio" name="test-cowebsite-property"> Failure <input type="radio" name="test-cowebsite-property" checked> Pending
|
<input type="radio" name="test-cowebsite-property"> Success <input type="radio" name="test-cowebsite-property"> Failure <input type="radio" name="test-cowebsite-property" checked> Pending
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="#" class="testLink" data-testmap="cowebsite_property.json" target="_blank">Open co-websites by map property</a>
|
<a href="#" class="testLink" data-testmap="CoWebsite/cowebsite_property.json" target="_blank">Open co-websites by map property</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -231,12 +231,12 @@ export class SocketManager implements ZoneEventListener {
|
|||||||
try {
|
try {
|
||||||
client.viewport = viewport;
|
client.viewport = viewport;
|
||||||
|
|
||||||
const world = this.rooms.get(client.roomId);
|
const room = this.rooms.get(client.roomId);
|
||||||
if (!world) {
|
if (!room) {
|
||||||
console.error("In SET_VIEWPORT, could not find world with id '", client.roomId, "'");
|
console.error("In SET_VIEWPORT, could not find world with id '", client.roomId, "'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
world.setViewport(client, client.viewport);
|
room.setViewport(client, client.viewport);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('An error occurred on "SET_VIEWPORT" event');
|
console.error('An error occurred on "SET_VIEWPORT" event');
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
Loading…
Reference in New Issue
Block a user