Merge branch 'develop' of github.com:thecodingmachine/workadventure into menuInSvelte
@ -7,14 +7,14 @@ not overwrite existing ones) and click on the animation editor:
|
||||
|
||||
|
||||
<div class="px-5 card rounded d-inline-block">
|
||||
<img class="document-img" src="https://workadventu.re/img/docs/anims/camera.png" alt="" />
|
||||
<img class="document-img" src="images/anims/camera.png" alt="" />
|
||||
</div>
|
||||
|
||||
You can now add all tiles that should be part of the animation via drag and drop to the "playlist" and adjust the frame duration:
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img class="figure-img img-fluid rounded" src="https://workadventu.re/img/docs/anims/animation_editor.png" alt="" />
|
||||
<img class="figure-img img-fluid rounded" src="images/anims/animation_editor.png" alt="" />
|
||||
<figcaption class="figure-caption">The tile animation editor</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
@ -24,7 +24,7 @@ You can preview animations directly in Tiled, using the "Show tile animations" o
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img class="figure-img img-fluid rounded" src="https://workadventu.re/img/docs/anims/settings_show_animations.png" alt="" />
|
||||
<img class="figure-img img-fluid rounded" src="images/anims/settings_show_animations.png" alt="" />
|
||||
<figcaption class="figure-caption">The Show Tile Animations option</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@ If you use group layers in your map, to reference a layer in a group you will ne
|
||||
Example :
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/groupLayer.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/groupLayer.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -28,7 +28,7 @@ Listens to the position of the current user. The event is triggered when the use
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/trigger_event.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<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>
|
||||
@ -140,7 +140,7 @@ Replace the tile at the `x` and `y` coordinates in the layer named `layer` by th
|
||||
If `tile` is a string, it's not the id of the tile but the value of the property `name`.
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/nameIndexProperty.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/nameIndexProperty.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -70,7 +70,7 @@ Each object will represent a variable.
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/object_variable.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/object_variable.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -9,10 +9,10 @@ You can position this popup by using a "rectangle" object in Tiled that you will
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/screen_popup_tiled.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/screen_popup_tiled.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/screen_popup_in_game.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/screen_popup_in_game.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -85,7 +85,7 @@ WA.ui.registerMenuCommand("test", () => {
|
||||
```
|
||||
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/menu-command.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/menu-command.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ WA.ui.displayActionMessage({
|
||||
Displays a message at the bottom of the screen (that will disappear when space bar is pressed).
|
||||
|
||||
<div class="col">
|
||||
<img src="https://workadventu.re/img/docs/trigger_message.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/trigger_message.png" class="figure-img img-fluid rounded" alt="" />
|
||||
</div>
|
||||
|
||||
Example:
|
||||
|
BIN
docs/maps/images/anims/animation_editor.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
docs/maps/images/anims/camera.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
docs/maps/images/anims/settings_show_animations.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
docs/maps/images/collides-1.png
Normal file
After Width: | Height: | Size: 290 KiB |
BIN
docs/maps/images/collides-2.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
docs/maps/images/collides-3.png
Normal file
After Width: | Height: | Size: 129 KiB |
BIN
docs/maps/images/collides-4.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
docs/maps/images/groupLayer.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
docs/maps/images/menu-command.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
docs/maps/images/nameIndexProperty.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
docs/maps/images/object_variable.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
docs/maps/images/open_website_allow_api.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
docs/maps/images/screen_popup_in_game.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
docs/maps/images/screen_popup_tiled.png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
docs/maps/images/script_property.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
docs/maps/images/text-object.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
docs/maps/images/tiled_screenshot_1.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
docs/maps/images/trigger_event.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
docs/maps/images/trigger_message.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
docs/maps/images/website_allowapi_property.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
docs/maps/images/website_url_property.png
Normal file
After Width: | Height: | Size: 59 KiB |
@ -46,7 +46,7 @@ You can put relative URLs. If your script file is next to your map, you can simp
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/script_property.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/script_property.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<figcaption class="figure-caption">The script property</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
@ -72,7 +72,7 @@ In order to allow communication with WorkAdventure, you need to add an additiona
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/open_website_allow_api.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<img src="images/open_website_allow_api.png" class="figure-img img-fluid rounded" alt="" />
|
||||
<figcaption class="figure-caption">The `openWebsiteAllowApi` property</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
@ -29,7 +29,7 @@ font that has support for a variety of accents. It renders great when used at *8
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/text-object.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<img src="images/text-object.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<figcaption class="figure-caption">The "font-family" property</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@ A few things to notice:
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/tiled_screenshot_1.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<img src="images/tiled_screenshot_1.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<figcaption class="figure-caption">"floorLayer" is compulsory</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
@ -62,21 +62,21 @@ To make a tile "collidable", you should:
|
||||
|
||||
1. select the relevant tileset and switch to "edit" mode:
|
||||
|
||||
![](https://workadventu.re/img/docs/collides-1.png){.document-img}
|
||||
![](images/collides-1.png){.document-img}
|
||||
|
||||
2. right click on a tile of the tileset to select it:
|
||||
|
||||
![](https://workadventu.re/img/docs/collides-2.png){.document-img}
|
||||
![](images/collides-2.png){.document-img}
|
||||
|
||||
3. on the left pane in the custom properties section, right click and select "Add properties":
|
||||
|
||||
![](https://workadventu.re/img/docs/collides-3.png){.document-img}
|
||||
![](images/collides-3.png){.document-img}
|
||||
|
||||
Please add a `collides` property. The type of the property must be **bool**.
|
||||
|
||||
4. finally, check the checkbox for the `collides` property:
|
||||
|
||||
![](https://workadventu.re/img/docs/collides-4.png){.document-img}
|
||||
![](images/collides-4.png){.document-img}
|
||||
|
||||
Repeat for every tile that should be "collidable".
|
||||
|
||||
|
@ -11,7 +11,7 @@ To do this in Tiled:
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/website_url_property.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<img src="images/website_url_property.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<figcaption class="figure-caption">A "website" object</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
@ -34,7 +34,7 @@ to explicitly allow it, by setting an additional `allowApi` property to `true`.
|
||||
|
||||
<div>
|
||||
<figure class="figure">
|
||||
<img src="https://workadventu.re/img/docs/website_allowapi_property.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<img src="images/website_allowapi_property.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
|
||||
<figcaption class="figure-caption">A "website" object that can communicate using the Iframe API</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
@ -288,57 +288,67 @@ class IframeListener {
|
||||
this.iframes.delete(iframe);
|
||||
}
|
||||
|
||||
registerScript(scriptUrl: string): void {
|
||||
console.log("Loading map related script at ", scriptUrl);
|
||||
registerScript(scriptUrl: string): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
console.log("Loading map related script at ", scriptUrl);
|
||||
|
||||
if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") {
|
||||
// Using external iframe mode (
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.id = IframeListener.getIFrameId(scriptUrl);
|
||||
iframe.style.display = "none";
|
||||
iframe.src = "/iframe.html?script=" + encodeURIComponent(scriptUrl);
|
||||
if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") {
|
||||
// Using external iframe mode (
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.id = IframeListener.getIFrameId(scriptUrl);
|
||||
iframe.style.display = "none";
|
||||
iframe.src = "/iframe.html?script=" + encodeURIComponent(scriptUrl);
|
||||
|
||||
// We are putting a sandbox on this script because it will run in the same domain as the main website.
|
||||
iframe.sandbox.add("allow-scripts");
|
||||
iframe.sandbox.add("allow-top-navigation-by-user-activation");
|
||||
// We are putting a sandbox on this script because it will run in the same domain as the main website.
|
||||
iframe.sandbox.add("allow-scripts");
|
||||
iframe.sandbox.add("allow-top-navigation-by-user-activation");
|
||||
|
||||
document.body.prepend(iframe);
|
||||
iframe.addEventListener("load", () => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
this.scripts.set(scriptUrl, iframe);
|
||||
this.registerIframe(iframe);
|
||||
} else {
|
||||
// production code
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.id = IframeListener.getIFrameId(scriptUrl);
|
||||
iframe.style.display = "none";
|
||||
document.body.prepend(iframe);
|
||||
|
||||
// We are putting a sandbox on this script because it will run in the same domain as the main website.
|
||||
iframe.sandbox.add("allow-scripts");
|
||||
iframe.sandbox.add("allow-top-navigation-by-user-activation");
|
||||
this.scripts.set(scriptUrl, iframe);
|
||||
this.registerIframe(iframe);
|
||||
} else {
|
||||
// production code
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.id = IframeListener.getIFrameId(scriptUrl);
|
||||
iframe.style.display = "none";
|
||||
|
||||
//iframe.src = "data:text/html;charset=utf-8," + escape(html);
|
||||
iframe.srcdoc =
|
||||
"<!doctype html>\n" +
|
||||
"\n" +
|
||||
'<html lang="en">\n' +
|
||||
"<head>\n" +
|
||||
'<script src="' +
|
||||
window.location.protocol +
|
||||
"//" +
|
||||
window.location.host +
|
||||
'/iframe_api.js" ></script>\n' +
|
||||
'<script src="' +
|
||||
scriptUrl +
|
||||
'" ></script>\n' +
|
||||
"<title></title>\n" +
|
||||
"</head>\n" +
|
||||
"</html>\n";
|
||||
// We are putting a sandbox on this script because it will run in the same domain as the main website.
|
||||
iframe.sandbox.add("allow-scripts");
|
||||
iframe.sandbox.add("allow-top-navigation-by-user-activation");
|
||||
|
||||
document.body.prepend(iframe);
|
||||
//iframe.src = "data:text/html;charset=utf-8," + escape(html);
|
||||
iframe.srcdoc =
|
||||
"<!doctype html>\n" +
|
||||
"\n" +
|
||||
'<html lang="en">\n' +
|
||||
"<head>\n" +
|
||||
'<script src="' +
|
||||
window.location.protocol +
|
||||
"//" +
|
||||
window.location.host +
|
||||
'/iframe_api.js" ></script>\n' +
|
||||
'<script src="' +
|
||||
scriptUrl +
|
||||
'" ></script>\n' +
|
||||
"<title></title>\n" +
|
||||
"</head>\n" +
|
||||
"</html>\n";
|
||||
|
||||
this.scripts.set(scriptUrl, iframe);
|
||||
this.registerIframe(iframe);
|
||||
}
|
||||
iframe.addEventListener("load", () => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
document.body.prepend(iframe);
|
||||
|
||||
this.scripts.set(scriptUrl, iframe);
|
||||
this.registerIframe(iframe);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getBaseUrl(src: string, source: MessageEventSource | null): string {
|
||||
|
@ -107,7 +107,7 @@ export class GameManager {
|
||||
if (this.currentGameSceneName === null) throw "No current scene id set!";
|
||||
const gameScene: GameScene = this.scenePlugin.get(this.currentGameSceneName) as GameScene;
|
||||
gameScene.cleanupClosingScene();
|
||||
this.scenePlugin.stop(this.currentGameSceneName);
|
||||
gameScene.createSuccessorGameScene(false, false);
|
||||
menuIconVisiblilityStore.set(false);
|
||||
if (!this.scenePlugin.get(targetSceneName)) {
|
||||
this.scenePlugin.add(targetSceneName, sceneClass, false);
|
||||
|
@ -91,9 +91,7 @@ import { PropertyUtils } from "../Map/PropertyUtils";
|
||||
import Tileset = Phaser.Tilemaps.Tileset;
|
||||
import { userIsAdminStore } from "../../Stores/GameStore";
|
||||
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
|
||||
import { get } from "svelte/store";
|
||||
import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager";
|
||||
import { helpCameraSettingsVisibleStore } from "../../Stores/HelpCameraSettingsStore";
|
||||
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface | null;
|
||||
@ -404,12 +402,6 @@ export class GameScene extends DirtyScene {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Now, let's load the script, if any
|
||||
const scripts = this.getScriptUrls(this.mapFile);
|
||||
for (const script of scripts) {
|
||||
iframeListener.registerScript(script);
|
||||
}
|
||||
}
|
||||
|
||||
//hook initialisation
|
||||
@ -568,6 +560,12 @@ export class GameScene extends DirtyScene {
|
||||
}
|
||||
|
||||
this.createPromiseResolve();
|
||||
// Now, let's load the script, if any
|
||||
const scripts = this.getScriptUrls(this.mapFile);
|
||||
const scriptPromises = [];
|
||||
for (const script of scripts) {
|
||||
scriptPromises.push(iframeListener.registerScript(script));
|
||||
}
|
||||
|
||||
this.userInputManager.spaceEvent(() => {
|
||||
this.outlinedItem?.activate();
|
||||
@ -585,6 +583,7 @@ export class GameScene extends DirtyScene {
|
||||
this.triggerOnMapLayerPropertyChange();
|
||||
|
||||
if (!this.room.isDisconnected()) {
|
||||
this.scene.sleep();
|
||||
this.connect();
|
||||
}
|
||||
|
||||
@ -608,6 +607,10 @@ export class GameScene extends DirtyScene {
|
||||
this.chatVisibilityUnsubscribe = chatVisibilityStore.subscribe((v) => {
|
||||
this.openChatIcon.setVisible(!v);
|
||||
});
|
||||
|
||||
Promise.all([this.connectionAnswerPromise as Promise<unknown>, ...scriptPromises]).then(() => {
|
||||
this.scene.wake();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -685,19 +688,7 @@ export class GameScene extends DirtyScene {
|
||||
this.connection.onServerDisconnected(() => {
|
||||
console.log("Player disconnected from server. Reloading scene.");
|
||||
this.cleanupClosingScene();
|
||||
|
||||
const gameSceneKey = "somekey" + Math.round(Math.random() * 10000);
|
||||
const game: Phaser.Scene = new GameScene(this.room, this.MapUrlFile, gameSceneKey);
|
||||
this.scene.add(gameSceneKey, game, true, {
|
||||
initPosition: {
|
||||
x: this.CurrentPlayer.x,
|
||||
y: this.CurrentPlayer.y,
|
||||
},
|
||||
reconnecting: true,
|
||||
});
|
||||
|
||||
this.scene.stop(this.scene.key);
|
||||
this.scene.remove(this.scene.key);
|
||||
this.createSuccessorGameScene(true, true);
|
||||
});
|
||||
|
||||
this.connection.onActionableEvent((message) => {
|
||||
@ -759,8 +750,9 @@ export class GameScene extends DirtyScene {
|
||||
this.connectionAnswerPromiseResolve(onConnect.room);
|
||||
// Analyze tags to find if we are admin. If yes, show console.
|
||||
|
||||
this.scene.wake();
|
||||
this.scene.stop(ReconnectingSceneName);
|
||||
if (this.scene.isSleeping()) {
|
||||
this.scene.stop(ReconnectingSceneName);
|
||||
}
|
||||
|
||||
//init user position and play trigger to check layers properties
|
||||
this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y);
|
||||
@ -1924,4 +1916,24 @@ ${escapedMessage}
|
||||
waScaleManager.zoomModifier *= zoomFactor;
|
||||
biggestAvailableAreaStore.recompute();
|
||||
}
|
||||
|
||||
public createSuccessorGameScene(autostart: boolean, reconnecting: boolean) {
|
||||
const gameSceneKey = "somekey" + Math.round(Math.random() * 10000);
|
||||
const game = new GameScene(this.room, this.MapUrlFile, gameSceneKey);
|
||||
this.scene.add(gameSceneKey, game, autostart, {
|
||||
initPosition: {
|
||||
x: this.CurrentPlayer.x,
|
||||
y: this.CurrentPlayer.y,
|
||||
},
|
||||
reconnecting: reconnecting,
|
||||
});
|
||||
|
||||
//If new gameScene doesn't start automatically then we change the gameScene in gameManager so that it can start the new gameScene
|
||||
if (!autostart) {
|
||||
gameManager.gameSceneIsCreated(game);
|
||||
}
|
||||
|
||||
this.scene.stop(this.scene.key);
|
||||
this.scene.remove(this.scene.key);
|
||||
}
|
||||
}
|
||||
|