Browse Source

[ts][phaser] Add inline loading example for Phaser.

Davide Tantillo 6 months ago
parent
commit
5f28cae564
1 changed files with 173 additions and 0 deletions
  1. 173 0
      spine-ts/spine-phaser/example/inline-loading.html

+ 173 - 0
spine-ts/spine-phaser/example/inline-loading.html

@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8" />
+		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
+		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+		<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
+		<script src="../dist/iife/spine-phaser.js"></script>
+		<link rel="stylesheet" href="../../index.css" />
+		<title>Spine Phaser Example</title>
+	</head>
+
+	<body class="p-4 flex flex-col items-center">
+		<h1>Inline loading example</h1>
+	</body>
+
+<script>
+
+const png0 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAF0lEQVR4XmNgGAWDGPwHAnSxUTAKaAYAuNkD/UsHnp0AAAAASUVORK5CYII=";
+const png1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGklEQVR4XmNgGAWDGPyHAnRxogHFBoyCEQUAsVwP8T2BZi4AAAAASUVORK5CYII=";
+const atlasString =
+`spine.png
+size:16,16
+filter:Linear,Linear
+pma:true
+pixel1
+bounds:6,6,1,1
+
+spine_2.png
+size:16,16
+filter:Linear,Linear
+pma:true
+pixel2
+bounds:6,6,2,2
+`
+
+const skeletonJson = {
+  "skeleton": {
+	"hash": "Xgvriu12nCE",
+	"spine": "0.0.00",
+	"x": -150,
+	"y": -50,
+	"width": 300,
+	"height": 100,
+	"images": "./images/",
+	"audio": "./audio"
+  },
+  "bones": [
+	{ "name": "root", "scaleX": 50, "scaleY": 50 }
+  ],
+  "slots": [
+	{ "name": "1", "bone": "root", "attachment": "pixel1" },
+	{ "name": "2", "bone": "root", "attachment": "pixel2" }
+  ],
+  "skins": [
+	{
+	  "name": "default",
+	  "attachments": {
+		"1": {
+		  "pixel1": { "x": 1, "width": 1, "height": 1 }
+		},
+		"2": {
+		  "pixel2": { "x": -1, "width": 2, "height": 2 }
+		}
+	  }
+	}
+  ],
+  "animations": {
+	"animation": {
+	  "slots": {
+		"1": {
+		  "rgba": [
+			{ "color": "3f00ffff" },
+			{ "time": 0.3333, "color": "ffffffff" },
+			{ "time": 0.6667, "color": "3f00ffff" }
+		  ]
+		},
+		"2": {
+		  "rgba": [
+			{ "color": "ff0000ff" },
+			{ "time": 0.3333, "color": "ffffffff" },
+			{ "time": 0.6667, "color": "ff0000ff" }
+		  ]
+		}
+	  }
+	}
+  }
+}
+
+class BasicExample extends Phaser.Scene {
+
+	atlasKey = "spineboy-atlas";
+
+	async preload() {
+		// manually add the text atlas to the game cache
+		this.game.cache.text.add(this.atlasKey, { data: atlasString, premultipliedAlpha: true });
+
+		// manually add the json skeleton to the game cache
+		this.game.cache.json.add("spineboy-data", skeletonJson);
+	}
+
+	async create() {
+
+		// associate the base64 encoded pngs to their name in the text atlas
+		const texturesMap = {
+		"spine.png": png0,
+		"spine_2.png": png1,
+		}
+
+		const loadedTexturePromises = [];
+		const textureCallbackList = [];
+		const textureCallback = (resolve, combinedKey) => key => {
+		if (combinedKey === key) resolve()
+		}
+
+		// loop over the pngs to load
+		Object.entries(texturesMap).forEach(([keyTexture, value]) => {
+
+		// the cache key that spine plugin will search
+		const combinedKey = `${this.atlasKey}!${keyTexture}`;
+
+		// addBase64 is async and we should wait for the ADD event before starting the game
+		this.textures.addBase64(combinedKey,  value);
+		const promise = new Promise((resolve) => {
+			const cb = textureCallback(resolve, combinedKey);
+			textureCallbackList.push(cb);
+			this.textures.on(Phaser.Textures.Events.ADD, cb);
+		});
+
+		// collecting all promises waiting for the ADD event
+		loadedTexturePromises.push(promise);
+		})
+
+		// wait for all pngs to be decoded and loaded
+		await Promise.all(loadedTexturePromises);
+
+		// unregister the listener to the textures since we're done at listenting at texture events
+		textureCallbackList.forEach(cb => this.textures.off(Phaser.Textures.Events.ADD, cb));
+
+		// now all assets are loaded, create the game object as usual
+		const spineboy = this.add.spine(
+			400,
+			300,
+			"spineboy-data",
+			"spineboy-atlas"
+		);
+		spineboy.setInteractive();
+		spineboy.displayWidth = 200;
+		spineboy.displayHeight = (spineboy.height / spineboy.width) * 200;
+		this.input.enableDebug(spineboy, 0xff00ff);
+		spineboy.animationState.setAnimation(0, "animation", true);
+	}
+}
+
+new Phaser.Game({
+type: Phaser.AUTO,
+width: 800,
+height: 600,
+type: Phaser.WEBGL,
+scene: [BasicExample],
+plugins: {
+	scene: [
+		{
+			key: "spine.SpinePlugin",
+			plugin: spine.SpinePlugin,
+			mapping: "spine",
+		},
+	],
+},
+});
+</script>
+
+</html>