mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Merge branch '4.1' into 4.2-beta
# Conflicts: # .gitignore # spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp # spine-ts/package-lock.json # spine-ts/package.json
This commit is contained in:
commit
68a9096049
1
.gitignore
vendored
1
.gitignore
vendored
@ -185,3 +185,4 @@ spine-flutter/src/spine-cpp
|
|||||||
|
|
||||||
spine-godot/.clang-format
|
spine-godot/.clang-format
|
||||||
|
|
||||||
|
spine-ts/spine-phaser/dist
|
||||||
|
|||||||
@ -357,6 +357,29 @@ cp -f ../spineboy/export/spineboy-pro.skel "$ROOT/spine-ts/spine-player/example/
|
|||||||
cp -f ../spineboy/export/spineboy-pma.atlas "$ROOT/spine-ts/spine-player/example/assets/"
|
cp -f ../spineboy/export/spineboy-pma.atlas "$ROOT/spine-ts/spine-player/example/assets/"
|
||||||
cp -f ../spineboy/export/spineboy-pma.png "$ROOT/spine-ts/spine-player/example/assets/"
|
cp -f ../spineboy/export/spineboy-pma.png "$ROOT/spine-ts/spine-player/example/assets/"
|
||||||
|
|
||||||
|
rm "$ROOT/spine-ts/spine-phaser/example/assets/"*
|
||||||
|
cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../raptor/export/raptor-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../raptor/export/raptor-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
|
cp -f ../spineboy/export/spineboy-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../spineboy/export/spineboy-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../spineboy/export/spineboy-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
|
cp -f ../coin/export/coin-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../coin/export/coin-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../coin/export/coin-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
|
cp -f ../stretchyman/export/stretchyman-pro.json "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../stretchyman/export/stretchyman-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../stretchyman/export/stretchyman-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../stretchyman/export/stretchyman-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
|
cp -f ../mix-and-match/export/mix-and-match-pro.json "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../mix-and-match/export/mix-and-match-pma.atlas "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
cp -f ../mix-and-match/export/mix-and-match-pma.png "$ROOT/spine-ts/spine-phaser/example/assets/"
|
||||||
|
|
||||||
echo "spine-monogame"
|
echo "spine-monogame"
|
||||||
rm "$ROOT/spine-monogame/spine-monogame-example/data/"*
|
rm "$ROOT/spine-monogame/spine-monogame-example/data/"*
|
||||||
cp -f ../coin/export/coin-pro.json "$ROOT/spine-monogame/spine-monogame-example/data/"
|
cp -f ../coin/export/coin-pro.json "$ROOT/spine-monogame/spine-monogame-example/data/"
|
||||||
|
|||||||
@ -34,42 +34,42 @@
|
|||||||
using namespace spine;
|
using namespace spine;
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
String atlasFile("data/spineboy-pma.atlas");
|
String atlasFile("data/spineboy-pma.atlas");
|
||||||
String skeletonFile("data/spineboy-pro.skel");
|
String skeletonFile("data/spineboy-pro.skel");
|
||||||
float scale = 0.6f;
|
float scale = 0.6f;
|
||||||
SFMLTextureLoader textureLoader;
|
SFMLTextureLoader textureLoader;
|
||||||
Atlas *atlas = new Atlas(atlasFile, &textureLoader);
|
Atlas *atlas = new Atlas(atlasFile, &textureLoader);
|
||||||
SkeletonData *skeletonData = nullptr;
|
SkeletonData *skeletonData = nullptr;
|
||||||
if (strncmp(skeletonFile.buffer(), ".skel", skeletonFile.length()) > 0) {
|
if (strncmp(skeletonFile.buffer(), ".skel", skeletonFile.length()) > 0) {
|
||||||
SkeletonBinary binary(atlas);
|
SkeletonBinary binary(atlas);
|
||||||
binary.setScale(scale);
|
binary.setScale(scale);
|
||||||
skeletonData = binary.readSkeletonDataFile(skeletonFile);
|
skeletonData = binary.readSkeletonDataFile(skeletonFile);
|
||||||
} else {
|
} else {
|
||||||
SkeletonJson json(atlas);
|
SkeletonJson json(atlas);
|
||||||
json.setScale(scale);
|
json.setScale(scale);
|
||||||
skeletonData = json.readSkeletonDataFile(skeletonFile);
|
skeletonData = json.readSkeletonDataFile(skeletonFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationStateData stateData(skeletonData);
|
AnimationStateData stateData(skeletonData);
|
||||||
SkeletonDrawable drawable(skeletonData, &stateData);
|
SkeletonDrawable drawable(skeletonData, &stateData);
|
||||||
drawable.skeleton->setPosition(320, 590);
|
drawable.skeleton->setPosition(320, 590);
|
||||||
drawable.state->setAnimation(0, "walk", true);
|
drawable.state->setAnimation(0, "walk", true);
|
||||||
|
|
||||||
sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - testbed");
|
sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - testbed");
|
||||||
window.setFramerateLimit(60);
|
window.setFramerateLimit(60);
|
||||||
sf::Event event;
|
sf::Event event;
|
||||||
sf::Clock deltaClock;
|
sf::Clock deltaClock;
|
||||||
while (window.isOpen()) {
|
while (window.isOpen()) {
|
||||||
while (window.pollEvent(event))
|
while (window.pollEvent(event))
|
||||||
if (event.type == sf::Event::Closed) window.close();
|
if (event.type == sf::Event::Closed) window.close();
|
||||||
|
|
||||||
float delta = deltaClock.getElapsedTime().asSeconds();
|
float delta = deltaClock.getElapsedTime().asSeconds();
|
||||||
deltaClock.restart();
|
deltaClock.restart();
|
||||||
drawable.update(delta);
|
drawable.update(delta);
|
||||||
window.clear();
|
window.clear();
|
||||||
window.draw(drawable);
|
window.draw(drawable);
|
||||||
window.display();
|
window.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
8
spine-ts/.vscode/launch.json
vendored
8
spine-ts/.vscode/launch.json
vendored
@ -31,6 +31,14 @@
|
|||||||
"name": "threejs-example",
|
"name": "threejs-example",
|
||||||
"url": "http://localhost:8080/spine-threejs/example/index.html",
|
"url": "http://localhost:8080/spine-threejs/example/index.html",
|
||||||
"webRoot": "${workspaceFolder}"
|
"webRoot": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "pwa-chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "phaser-example",
|
||||||
|
"url": "http://localhost:8080/spine-phaser/example/index.html",
|
||||||
|
"webRoot": "${workspaceFolder}"
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,10 @@
|
|||||||
<li><a href="/spine-canvas/example">Example</a></li>
|
<li><a href="/spine-canvas/example">Example</a></li>
|
||||||
<li><a href="/spine-canvas/example/mouse-click.html">Mouse click</a></li>
|
<li><a href="/spine-canvas/example/mouse-click.html">Mouse click</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<li>Phaser</li>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/spine-phaser/example/index.html">Example</a></li>
|
||||||
|
</ul>
|
||||||
<li>Player</li>
|
<li>Player</li>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/spine-player/example/example.html">Example</a></li>
|
<li><a href="/spine-player/example/example.html">Example</a></li>
|
||||||
|
|||||||
@ -7,20 +7,22 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublish": "npm run clean && npm run build",
|
"prepublish": "npm run clean && npm run build",
|
||||||
"clean": "npx rimraf spine-core/dist spine-canvas/dist spine-webgl/dist spine-player/dist spine-threejs/dist",
|
"clean": "npx rimraf spine-core/dist spine-canvas/dist spine-webgl/dist spine-phaser/dist spine-player/dist spine-threejs/dist",
|
||||||
"build": "npm run clean && npm run build:modules && concurrently \"npm run build:core\" \"npm run build:canvas\" \"npm run build:webgl\" \"npm run build:player\" \"npm run build:threejs\"",
|
"build": "npm run clean && npm run build:modules && concurrently \"npm run build:core\" \"npm run build:canvas\" \"npm run build:webgl\" \"npm run build:phaser\" \"npm run build:player\" \"npm run build:threejs\"",
|
||||||
"postbuild": "npm run minify",
|
"postbuild": "npm run minify",
|
||||||
"build:modules": "npx tsc -b -clean && npx tsc -b",
|
"build:modules": "npx tsc -b -clean && npx tsc -b",
|
||||||
"build:core": "npx esbuild --bundle spine-core/src/index.ts --tsconfig=spine-core/tsconfig.json --sourcemap --outfile=spine-core/dist/iife/spine-core.js --format=iife --global-name=spine",
|
"build:core": "npx esbuild --bundle spine-core/src/index.ts --tsconfig=spine-core/tsconfig.json --sourcemap --outfile=spine-core/dist/iife/spine-core.js --format=iife --global-name=spine",
|
||||||
"build:canvas": "npx esbuild --bundle spine-canvas/src/index.ts --tsconfig=spine-canvas/tsconfig.json --sourcemap --outfile=spine-canvas/dist/iife/spine-canvas.js --format=iife --global-name=spine",
|
"build:canvas": "npx esbuild --bundle spine-canvas/src/index.ts --tsconfig=spine-canvas/tsconfig.json --sourcemap --outfile=spine-canvas/dist/iife/spine-canvas.js --format=iife --global-name=spine",
|
||||||
"build:webgl": "npx esbuild --bundle spine-webgl/src/index.ts --tsconfig=spine-webgl/tsconfig.json --sourcemap --outfile=spine-webgl/dist/iife/spine-webgl.js --format=iife --global-name=spine",
|
"build:webgl": "npx esbuild --bundle spine-webgl/src/index.ts --tsconfig=spine-webgl/tsconfig.json --sourcemap --outfile=spine-webgl/dist/iife/spine-webgl.js --format=iife --global-name=spine",
|
||||||
"build:player": "npx copyfiles -f spine-player/css/spine-player.css spine-player/dist/ && npx npx esbuild --bundle spine-player/src/index.ts --tsconfig=spine-player/tsconfig.json --sourcemap --outfile=spine-player/dist/iife/spine-player.js --format=iife --global-name=spine",
|
"build:player": "npx copyfiles -f spine-player/css/spine-player.css spine-player/dist/ && npx npx esbuild --bundle spine-player/src/index.ts --tsconfig=spine-player/tsconfig.json --sourcemap --outfile=spine-player/dist/iife/spine-player.js --format=iife --global-name=spine",
|
||||||
|
"build:phaser": "npx esbuild --bundle spine-phaser/src/index.ts --tsconfig=spine-phaser/tsconfig.json --sourcemap --outfile=spine-phaser/dist/iife/spine-phaser.js --external:Phaser --alias:phaser=Phaser --format=iife --global-name=spine",
|
||||||
"build:threejs": "npx esbuild --bundle spine-threejs/src/index.ts --tsconfig=spine-threejs/tsconfig.json --sourcemap --outfile=spine-threejs/dist/iife/spine-threejs.js --external:three --format=iife --global-name=spine",
|
"build:threejs": "npx esbuild --bundle spine-threejs/src/index.ts --tsconfig=spine-threejs/tsconfig.json --sourcemap --outfile=spine-threejs/dist/iife/spine-threejs.js --external:three --format=iife --global-name=spine",
|
||||||
"minify": "npx esbuild --minify spine-core/dist/iife/spine-core.js --outfile=spine-core/dist/iife/spine-core.min.js && npx esbuild --minify spine-canvas/dist/iife/spine-canvas.js --outfile=spine-canvas/dist/iife/spine-canvas.min.js && npx esbuild --minify spine-player/dist/iife/spine-player.js --outfile=spine-player/dist/iife/spine-player.min.js && npx esbuild --minify spine-webgl/dist/iife/spine-webgl.js --outfile=spine-webgl/dist/iife/spine-webgl.min.js && npx esbuild --minify spine-threejs/dist/iife/spine-threejs.js --outfile=spine-threejs/dist/iife/spine-threejs.min.js",
|
"minify": "npx esbuild --minify spine-core/dist/iife/spine-core.js --outfile=spine-core/dist/iife/spine-core.min.js && npx esbuild --minify spine-canvas/dist/iife/spine-canvas.js --outfile=spine-canvas/dist/iife/spine-canvas.min.js && npx esbuild --minify spine-player/dist/iife/spine-player.js --outfile=spine-player/dist/iife/spine-player.min.js && npx esbuild --minify spine-phaser/dist/iife/spine-phaser.js --outfile=spine-phaser/dist/iife/spine-phaser.min.js && npx esbuild --minify spine-webgl/dist/iife/spine-webgl.js --outfile=spine-webgl/dist/iife/spine-webgl.min.js && npx esbuild --minify spine-threejs/dist/iife/spine-threejs.js --outfile=spine-threejs/dist/iife/spine-threejs.min.js",
|
||||||
"dev": "concurrently \"npx live-server --no-browser\" \"npm run dev:modules\" \"npm run dev:canvas\" \"npm run dev:webgl\" \"npm run dev:player\" \"npm run dev:threejs\"",
|
"dev": "concurrently \"npx live-server --no-browser\" \"npm run dev:canvas\" \"npm run dev:webgl\" \"npm run dev:phaser\" \"npm run dev:player\" \"npm run dev:threejs\"",
|
||||||
"dev:modules": "npm run build:modules -- --watch",
|
"dev:modules": "npm run build:modules -- --watch",
|
||||||
"dev:canvas": "npm run build:canvas -- --watch",
|
"dev:canvas": "npm run build:canvas -- --watch",
|
||||||
"dev:webgl": "npm run build:webgl -- --watch",
|
"dev:webgl": "npm run build:webgl -- --watch",
|
||||||
|
"dev:phaser": "npm run build:phaser -- --watch",
|
||||||
"dev:player": "npm run build:player -- --watch",
|
"dev:player": "npm run build:player -- --watch",
|
||||||
"dev:threejs": "npm run build:threejs -- --watch"
|
"dev:threejs": "npm run build:threejs -- --watch"
|
||||||
},
|
},
|
||||||
@ -46,18 +48,18 @@
|
|||||||
"workspaces": [
|
"workspaces": [
|
||||||
"spine-core",
|
"spine-core",
|
||||||
"spine-canvas",
|
"spine-canvas",
|
||||||
|
"spine-phaser",
|
||||||
"spine-player",
|
"spine-player",
|
||||||
"spine-threejs",
|
"spine-threejs",
|
||||||
"spine-webgl"
|
"spine-webgl"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^6.2.1",
|
"@types/offscreencanvas": "^2019.6.4",
|
||||||
|
"concurrently": "^7.6.0",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"esbuild": "^0.12.22",
|
"esbuild": "^0.16.4",
|
||||||
"live-server": "^1.2.1",
|
"live-server": "^1.2.2",
|
||||||
"npx": "^10.2.2",
|
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"typescript": "^4.9.3",
|
"typescript": "^4.9.4"
|
||||||
"@types/offscreencanvas": "^2019.6.4"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ fi
|
|||||||
sed -i '' "s/$lastVersion/$newVersion/" package.json
|
sed -i '' "s/$lastVersion/$newVersion/" package.json
|
||||||
sed -i '' "s/$lastVersion/$newVersion/" spine-canvas/package.json
|
sed -i '' "s/$lastVersion/$newVersion/" spine-canvas/package.json
|
||||||
sed -i '' "s/$lastVersion/$newVersion/" spine-core/package.json
|
sed -i '' "s/$lastVersion/$newVersion/" spine-core/package.json
|
||||||
|
sed -i '' "s/$lastVersion/$newVersion/" spine-phaser/package.json
|
||||||
sed -i '' "s/$lastVersion/$newVersion/" spine-player/package.json
|
sed -i '' "s/$lastVersion/$newVersion/" spine-player/package.json
|
||||||
sed -i '' "s/$lastVersion/$newVersion/" spine-threejs/package.json
|
sed -i '' "s/$lastVersion/$newVersion/" spine-threejs/package.json
|
||||||
sed -i '' "s/$lastVersion/$newVersion/" spine-webgl/package.json
|
sed -i '' "s/$lastVersion/$newVersion/" spine-webgl/package.json
|
||||||
|
|||||||
@ -45,6 +45,8 @@ import { Color, Utils, MathUtils, Vector2, NumberArrayLike } from "./Utils";
|
|||||||
*
|
*
|
||||||
* See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. */
|
* See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. */
|
||||||
export class Skeleton {
|
export class Skeleton {
|
||||||
|
static yDown = false;;
|
||||||
|
|
||||||
/** The skeleton's setup pose data. */
|
/** The skeleton's setup pose data. */
|
||||||
data: SkeletonData;
|
data: SkeletonData;
|
||||||
|
|
||||||
@ -81,7 +83,15 @@ export class Skeleton {
|
|||||||
|
|
||||||
/** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale
|
/** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale
|
||||||
* inheritance. */
|
* inheritance. */
|
||||||
scaleY = 1;
|
private _scaleY = 1;
|
||||||
|
|
||||||
|
public get scaleY() {
|
||||||
|
return Skeleton.yDown ? -this._scaleY : this._scaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set scaleY(scaleY: number) {
|
||||||
|
this._scaleY = scaleY;
|
||||||
|
}
|
||||||
|
|
||||||
/** Sets the skeleton X position, which is added to the root bone worldX position. */
|
/** Sets the skeleton X position, which is added to the root bone worldX position. */
|
||||||
x = 0;
|
x = 0;
|
||||||
|
|||||||
26
spine-ts/spine-phaser/LICENSE
Normal file
26
spine-ts/spine-phaser/LICENSE
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Spine Runtimes License Agreement
|
||||||
|
Last updated May 1, 2019. Replaces all prior versions.
|
||||||
|
|
||||||
|
Copyright (c) 2013-2019, Esoteric Software LLC
|
||||||
|
|
||||||
|
Integration of the Spine Runtimes into software or otherwise creating
|
||||||
|
derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
conditions of Section 2 of the Spine Editor License Agreement:
|
||||||
|
http://esotericsoftware.com/spine-editor-license
|
||||||
|
|
||||||
|
Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
"Products"), provided that each user of the Products must obtain their own
|
||||||
|
Spine Editor license and redistribution of the Products in any form must
|
||||||
|
include this license and copyright notice.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||||
|
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||||
|
INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
3
spine-ts/spine-phaser/README.md
Normal file
3
spine-ts/spine-phaser/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# spine-ts Phaser
|
||||||
|
|
||||||
|
Please see https://github.com/EsotericSoftware/spine-runtimes/blob/4.0/spine-ts/README.md for more information.
|
||||||
59
spine-ts/spine-phaser/example/arcade-physics-test.html
Normal file
59
spine-ts/spine-phaser/example/arcade-physics-test.html
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Arcade Physics example</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
physics: {
|
||||||
|
default: 'arcade',
|
||||||
|
arcade: {
|
||||||
|
debug: true,
|
||||||
|
gravity: { y: 200 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineBinary("coin-data", "assets/coin-pro.skel");
|
||||||
|
this.load.spineAtlas("coin-atlas", "assets/coin-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
let coin = this.add.spine(400, 200, 'coin-data', "coin-atlas");
|
||||||
|
coin.animationState.setAnimation(0, "animation", true);
|
||||||
|
coin.setScale(0.3);
|
||||||
|
coin.setSize(280, 280);
|
||||||
|
|
||||||
|
this.physics.add.existing(coin);
|
||||||
|
|
||||||
|
coin.body.setOffset(0, 50);
|
||||||
|
coin.body.setVelocity(100, 200);
|
||||||
|
coin.body.setBounce(1, 1);
|
||||||
|
coin.body.setCollideWorldBounds(true);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
19
spine-ts/spine-phaser/example/assets/coin-pma.atlas
Normal file
19
spine-ts/spine-phaser/example/assets/coin-pma.atlas
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
coin-pma.png
|
||||||
|
size: 1024, 1024
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
coin-front-logo
|
||||||
|
bounds: 2, 570, 305, 302
|
||||||
|
coin-front-shine-logo
|
||||||
|
bounds: 2, 286, 282, 282
|
||||||
|
coin-front-shine-spineboy
|
||||||
|
bounds: 305, 283, 282, 282
|
||||||
|
coin-front-spineboy
|
||||||
|
bounds: 309, 567, 305, 302
|
||||||
|
rotate: 90
|
||||||
|
coin-side-round
|
||||||
|
bounds: 2, 2, 144, 282
|
||||||
|
coin-side-straight
|
||||||
|
bounds: 286, 286, 17, 282
|
||||||
|
shine
|
||||||
|
bounds: 148, 39, 72, 245
|
||||||
BIN
spine-ts/spine-phaser/example/assets/coin-pma.png
Normal file
BIN
spine-ts/spine-phaser/example/assets/coin-pma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 222 KiB |
BIN
spine-ts/spine-phaser/example/assets/coin-pro.skel
Normal file
BIN
spine-ts/spine-phaser/example/assets/coin-pro.skel
Normal file
Binary file not shown.
363
spine-ts/spine-phaser/example/assets/mix-and-match-pma.atlas
Normal file
363
spine-ts/spine-phaser/example/assets/mix-and-match-pma.atlas
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
mix-and-match-pma.png
|
||||||
|
size: 1024, 512
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
base-head
|
||||||
|
bounds: 587, 2, 95, 73
|
||||||
|
boy/arm-front
|
||||||
|
bounds: 558, 271, 36, 115
|
||||||
|
boy/backpack
|
||||||
|
bounds: 235, 109, 119, 153
|
||||||
|
boy/backpack-pocket
|
||||||
|
bounds: 328, 73, 34, 62
|
||||||
|
rotate: 90
|
||||||
|
boy/backpack-strap-front
|
||||||
|
bounds: 665, 79, 38, 88
|
||||||
|
boy/backpack-up
|
||||||
|
bounds: 395, 364, 21, 70
|
||||||
|
rotate: 90
|
||||||
|
boy/body
|
||||||
|
bounds: 251, 264, 97, 132
|
||||||
|
rotate: 90
|
||||||
|
boy/boot-ribbon-front
|
||||||
|
bounds: 648, 131, 9, 11
|
||||||
|
boy/collar
|
||||||
|
bounds: 744, 4, 73, 29
|
||||||
|
rotate: 90
|
||||||
|
boy/ear
|
||||||
|
bounds: 383, 109, 19, 23
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-back-low-eyelid
|
||||||
|
bounds: 739, 284, 17, 6
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-back-pupil
|
||||||
|
bounds: 832, 443, 8, 9
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-back-up-eyelid
|
||||||
|
bounds: 558, 264, 23, 5
|
||||||
|
boy/eye-back-up-eyelid-back
|
||||||
|
bounds: 802, 491, 19, 10
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-front-low-eyelid
|
||||||
|
bounds: 386, 363, 22, 7
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-front-pupil
|
||||||
|
bounds: 816, 389, 9, 9
|
||||||
|
boy/eye-front-up-eyelid
|
||||||
|
bounds: 160, 71, 31, 6
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-front-up-eyelid-back
|
||||||
|
bounds: 801, 434, 26, 9
|
||||||
|
rotate: 90
|
||||||
|
boy/eye-iris-back
|
||||||
|
bounds: 618, 264, 17, 17
|
||||||
|
boy/eye-iris-front
|
||||||
|
bounds: 727, 264, 18, 18
|
||||||
|
boy/eye-white-back
|
||||||
|
bounds: 580, 131, 20, 12
|
||||||
|
boy/eye-white-front
|
||||||
|
bounds: 510, 130, 27, 13
|
||||||
|
boy/eyebrow-back
|
||||||
|
bounds: 751, 88, 20, 11
|
||||||
|
rotate: 90
|
||||||
|
boy/eyebrow-front
|
||||||
|
bounds: 483, 130, 25, 11
|
||||||
|
boy/hair-back
|
||||||
|
bounds: 494, 388, 122, 81
|
||||||
|
rotate: 90
|
||||||
|
boy/hair-bangs
|
||||||
|
bounds: 667, 284, 70, 37
|
||||||
|
boy/hair-side
|
||||||
|
bounds: 789, 374, 25, 43
|
||||||
|
boy/hand-backfingers
|
||||||
|
bounds: 467, 364, 19, 21
|
||||||
|
boy/hand-front-fingers
|
||||||
|
bounds: 488, 364, 19, 21
|
||||||
|
boy/hat
|
||||||
|
bounds: 615, 417, 93, 56
|
||||||
|
rotate: 90
|
||||||
|
boy/leg-front
|
||||||
|
bounds: 138, 104, 31, 158
|
||||||
|
boy/mouth-close
|
||||||
|
bounds: 551, 365, 21, 5
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/mouth-close
|
||||||
|
bounds: 551, 365, 21, 5
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/mouth-close
|
||||||
|
bounds: 551, 365, 21, 5
|
||||||
|
rotate: 90
|
||||||
|
girl/mouth-close
|
||||||
|
bounds: 551, 365, 21, 5
|
||||||
|
rotate: 90
|
||||||
|
boy/mouth-smile
|
||||||
|
bounds: 705, 79, 29, 7
|
||||||
|
boy/nose
|
||||||
|
bounds: 836, 473, 17, 10
|
||||||
|
rotate: 90
|
||||||
|
boy/pompom
|
||||||
|
bounds: 747, 273, 48, 43
|
||||||
|
rotate: 90
|
||||||
|
boy/zip
|
||||||
|
bounds: 648, 144, 14, 23
|
||||||
|
girl-blue-cape/back-eyebrow
|
||||||
|
bounds: 602, 131, 18, 12
|
||||||
|
girl-blue-cape/body-dress
|
||||||
|
bounds: 2, 264, 109, 246
|
||||||
|
girl-blue-cape/body-ribbon
|
||||||
|
bounds: 615, 283, 50, 38
|
||||||
|
girl-blue-cape/cape-back
|
||||||
|
bounds: 2, 69, 134, 193
|
||||||
|
girl-blue-cape/cape-back-up
|
||||||
|
bounds: 386, 387, 123, 106
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/cape-ribbon
|
||||||
|
bounds: 675, 264, 50, 18
|
||||||
|
girl-blue-cape/cape-shoulder-back
|
||||||
|
bounds: 751, 110, 49, 59
|
||||||
|
girl-blue-cape/cape-shoulder-front
|
||||||
|
bounds: 113, 264, 62, 76
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/cape-up-front
|
||||||
|
bounds: 399, 264, 98, 117
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/ear
|
||||||
|
bounds: 775, 2, 19, 23
|
||||||
|
girl-spring-dress/ear
|
||||||
|
bounds: 775, 2, 19, 23
|
||||||
|
girl/ear
|
||||||
|
bounds: 775, 2, 19, 23
|
||||||
|
girl-blue-cape/eye-back-low-eyelid
|
||||||
|
bounds: 802, 463, 17, 6
|
||||||
|
girl-spring-dress/eye-back-low-eyelid
|
||||||
|
bounds: 802, 463, 17, 6
|
||||||
|
girl/eye-back-low-eyelid
|
||||||
|
bounds: 802, 463, 17, 6
|
||||||
|
girl-blue-cape/eye-back-pupil
|
||||||
|
bounds: 816, 367, 8, 9
|
||||||
|
girl-spring-dress/eye-back-pupil
|
||||||
|
bounds: 816, 367, 8, 9
|
||||||
|
girl/eye-back-pupil
|
||||||
|
bounds: 816, 367, 8, 9
|
||||||
|
girl-blue-cape/eye-back-up-eyelid
|
||||||
|
bounds: 554, 131, 24, 12
|
||||||
|
girl-spring-dress/eye-back-up-eyelid
|
||||||
|
bounds: 554, 131, 24, 12
|
||||||
|
girl/eye-back-up-eyelid
|
||||||
|
bounds: 554, 131, 24, 12
|
||||||
|
girl-blue-cape/eye-back-up-eyelid-back
|
||||||
|
bounds: 832, 453, 17, 11
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/eye-back-up-eyelid-back
|
||||||
|
bounds: 832, 453, 17, 11
|
||||||
|
rotate: 90
|
||||||
|
girl/eye-back-up-eyelid-back
|
||||||
|
bounds: 832, 453, 17, 11
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/eye-front-low-eyelid
|
||||||
|
bounds: 739, 303, 18, 6
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/eye-front-low-eyelid
|
||||||
|
bounds: 739, 303, 18, 6
|
||||||
|
rotate: 90
|
||||||
|
girl/eye-front-low-eyelid
|
||||||
|
bounds: 739, 303, 18, 6
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/eye-front-pupil
|
||||||
|
bounds: 816, 378, 9, 9
|
||||||
|
girl-spring-dress/eye-front-pupil
|
||||||
|
bounds: 816, 378, 9, 9
|
||||||
|
girl/eye-front-pupil
|
||||||
|
bounds: 816, 378, 9, 9
|
||||||
|
girl-blue-cape/eye-front-up-eyelid
|
||||||
|
bounds: 392, 77, 30, 14
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/eye-front-up-eyelid
|
||||||
|
bounds: 392, 77, 30, 14
|
||||||
|
rotate: 90
|
||||||
|
girl/eye-front-up-eyelid
|
||||||
|
bounds: 392, 77, 30, 14
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/eye-front-up-eyelid-back
|
||||||
|
bounds: 455, 130, 26, 11
|
||||||
|
girl-spring-dress/eye-front-up-eyelid-back
|
||||||
|
bounds: 455, 130, 26, 11
|
||||||
|
girl/eye-front-up-eyelid-back
|
||||||
|
bounds: 455, 130, 26, 11
|
||||||
|
girl-blue-cape/eye-iris-back
|
||||||
|
bounds: 637, 264, 17, 17
|
||||||
|
girl-blue-cape/eye-iris-front
|
||||||
|
bounds: 802, 471, 18, 18
|
||||||
|
girl-blue-cape/eye-white-back
|
||||||
|
bounds: 596, 264, 20, 16
|
||||||
|
girl-spring-dress/eye-white-back
|
||||||
|
bounds: 596, 264, 20, 16
|
||||||
|
girl-blue-cape/eye-white-front
|
||||||
|
bounds: 796, 5, 20, 16
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/eye-white-front
|
||||||
|
bounds: 796, 5, 20, 16
|
||||||
|
rotate: 90
|
||||||
|
girl/eye-white-front
|
||||||
|
bounds: 796, 5, 20, 16
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/front-eyebrow
|
||||||
|
bounds: 608, 149, 18, 12
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/hair-back
|
||||||
|
bounds: 508, 145, 117, 98
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/hair-bangs
|
||||||
|
bounds: 673, 419, 91, 40
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/hair-head-side-back
|
||||||
|
bounds: 196, 331, 30, 52
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/hair-head-side-front
|
||||||
|
bounds: 738, 323, 41, 42
|
||||||
|
girl-blue-cape/hair-side
|
||||||
|
bounds: 473, 3, 36, 71
|
||||||
|
girl-blue-cape/hand-front-fingers
|
||||||
|
bounds: 509, 365, 19, 21
|
||||||
|
girl-spring-dress/hand-front-fingers
|
||||||
|
bounds: 509, 365, 19, 21
|
||||||
|
girl-blue-cape/leg-front
|
||||||
|
bounds: 168, 72, 30, 158
|
||||||
|
rotate: 90
|
||||||
|
girl-blue-cape/mouth-smile
|
||||||
|
bounds: 736, 79, 29, 7
|
||||||
|
girl-spring-dress/mouth-smile
|
||||||
|
bounds: 736, 79, 29, 7
|
||||||
|
girl/mouth-smile
|
||||||
|
bounds: 736, 79, 29, 7
|
||||||
|
girl-blue-cape/nose
|
||||||
|
bounds: 747, 264, 11, 7
|
||||||
|
girl-spring-dress/nose
|
||||||
|
bounds: 747, 264, 11, 7
|
||||||
|
girl/nose
|
||||||
|
bounds: 747, 264, 11, 7
|
||||||
|
girl-blue-cape/sleeve-back
|
||||||
|
bounds: 767, 79, 42, 29
|
||||||
|
girl-blue-cape/sleeve-front
|
||||||
|
bounds: 408, 76, 52, 119
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/arm-front
|
||||||
|
bounds: 596, 282, 17, 111
|
||||||
|
girl-spring-dress/back-eyebrow
|
||||||
|
bounds: 801, 420, 18, 12
|
||||||
|
girl-spring-dress/body-up
|
||||||
|
bounds: 179, 4, 64, 66
|
||||||
|
girl-spring-dress/cloak-down
|
||||||
|
bounds: 775, 27, 50, 50
|
||||||
|
girl-spring-dress/cloak-up
|
||||||
|
bounds: 360, 7, 64, 58
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/eye-iris-back
|
||||||
|
bounds: 656, 264, 17, 17
|
||||||
|
girl-spring-dress/eye-iris-front
|
||||||
|
bounds: 814, 492, 18, 18
|
||||||
|
girl-spring-dress/front-eyebrow
|
||||||
|
bounds: 822, 472, 18, 12
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/hair-back
|
||||||
|
bounds: 196, 363, 147, 93
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/hair-bangs
|
||||||
|
bounds: 696, 326, 91, 40
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/hair-head-side-back
|
||||||
|
bounds: 529, 76, 30, 52
|
||||||
|
girl-spring-dress/hair-head-side-front
|
||||||
|
bounds: 781, 323, 41, 42
|
||||||
|
girl-spring-dress/hair-side
|
||||||
|
bounds: 511, 3, 36, 71
|
||||||
|
girl-spring-dress/leg-front
|
||||||
|
bounds: 171, 104, 30, 158
|
||||||
|
girl-spring-dress/neck
|
||||||
|
bounds: 138, 70, 20, 32
|
||||||
|
girl-spring-dress/shoulder-ribbon
|
||||||
|
bounds: 622, 131, 36, 24
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/skirt
|
||||||
|
bounds: 113, 328, 182, 81
|
||||||
|
rotate: 90
|
||||||
|
girl-spring-dress/underskirt
|
||||||
|
bounds: 2, 2, 175, 65
|
||||||
|
girl/arm-front
|
||||||
|
bounds: 577, 395, 36, 115
|
||||||
|
girl/back-eyebrow
|
||||||
|
bounds: 834, 492, 18, 12
|
||||||
|
rotate: 90
|
||||||
|
girl/bag-base
|
||||||
|
bounds: 191, 264, 62, 58
|
||||||
|
rotate: 90
|
||||||
|
girl/bag-strap-front
|
||||||
|
bounds: 385, 265, 12, 96
|
||||||
|
girl/bag-top
|
||||||
|
bounds: 738, 367, 49, 50
|
||||||
|
girl/body
|
||||||
|
bounds: 356, 130, 97, 132
|
||||||
|
girl/boot-ribbon-front
|
||||||
|
bounds: 539, 130, 13, 13
|
||||||
|
girl/eye-iris-back
|
||||||
|
bounds: 821, 424, 17, 17
|
||||||
|
girl/eye-iris-front
|
||||||
|
bounds: 812, 443, 18, 18
|
||||||
|
girl/eye-white-back
|
||||||
|
bounds: 814, 5, 20, 16
|
||||||
|
rotate: 90
|
||||||
|
girl/front-eyebrow
|
||||||
|
bounds: 816, 400, 18, 12
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-back
|
||||||
|
bounds: 291, 363, 147, 93
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-bangs
|
||||||
|
bounds: 715, 419, 91, 40
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-flap-down-front
|
||||||
|
bounds: 288, 5, 70, 65
|
||||||
|
girl/hair-head-side-back
|
||||||
|
bounds: 561, 77, 30, 52
|
||||||
|
girl/hair-head-side-front
|
||||||
|
bounds: 757, 419, 41, 42
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-patch
|
||||||
|
bounds: 245, 4, 66, 41
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-side
|
||||||
|
bounds: 549, 3, 36, 71
|
||||||
|
girl/hair-strand-back-1
|
||||||
|
bounds: 684, 3, 58, 74
|
||||||
|
girl/hair-strand-back-2
|
||||||
|
bounds: 692, 171, 91, 58
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-strand-back-3
|
||||||
|
bounds: 615, 323, 92, 79
|
||||||
|
rotate: 90
|
||||||
|
girl/hair-strand-front-1
|
||||||
|
bounds: 518, 269, 38, 94
|
||||||
|
girl/hair-strand-front-2
|
||||||
|
bounds: 593, 79, 70, 50
|
||||||
|
girl/hair-strand-front-3
|
||||||
|
bounds: 705, 88, 44, 81
|
||||||
|
girl/hand-front-fingers
|
||||||
|
bounds: 530, 365, 19, 21
|
||||||
|
girl/hat
|
||||||
|
bounds: 608, 169, 93, 82
|
||||||
|
rotate: 90
|
||||||
|
girl/leg-front
|
||||||
|
bounds: 203, 104, 30, 158
|
||||||
|
girl/pompom
|
||||||
|
bounds: 757, 462, 48, 43
|
||||||
|
rotate: 90
|
||||||
|
girl/scarf
|
||||||
|
bounds: 455, 143, 119, 51
|
||||||
|
rotate: 90
|
||||||
|
girl/scarf-back
|
||||||
|
bounds: 420, 2, 72, 51
|
||||||
|
rotate: 90
|
||||||
|
girl/zip
|
||||||
|
bounds: 356, 109, 19, 25
|
||||||
|
rotate: 90
|
||||||
BIN
spine-ts/spine-phaser/example/assets/mix-and-match-pma.png
Normal file
BIN
spine-ts/spine-phaser/example/assets/mix-and-match-pma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 369 KiB |
8001
spine-ts/spine-phaser/example/assets/mix-and-match-pro.json
Normal file
8001
spine-ts/spine-phaser/example/assets/mix-and-match-pro.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
spine-ts/spine-phaser/example/assets/mix-and-match-pro.skel
Normal file
BIN
spine-ts/spine-phaser/example/assets/mix-and-match-pro.skel
Normal file
Binary file not shown.
101
spine-ts/spine-phaser/example/assets/raptor-pma.atlas
Normal file
101
spine-ts/spine-phaser/example/assets/raptor-pma.atlas
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
raptor-pma.png
|
||||||
|
size: 1024, 512
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
back-arm
|
||||||
|
bounds: 829, 88, 46, 25
|
||||||
|
rotate: 90
|
||||||
|
back-bracer
|
||||||
|
bounds: 195, 238, 39, 28
|
||||||
|
rotate: 90
|
||||||
|
back-hand
|
||||||
|
bounds: 724, 140, 36, 34
|
||||||
|
rotate: 90
|
||||||
|
back-knee
|
||||||
|
bounds: 760, 131, 49, 67
|
||||||
|
rotate: 90
|
||||||
|
back-thigh
|
||||||
|
bounds: 225, 238, 39, 24
|
||||||
|
rotate: 90
|
||||||
|
eyes-open
|
||||||
|
bounds: 975, 204, 47, 45
|
||||||
|
front-arm
|
||||||
|
bounds: 969, 112, 48, 26
|
||||||
|
front-bracer
|
||||||
|
bounds: 724, 97, 41, 29
|
||||||
|
rotate: 90
|
||||||
|
front-hand
|
||||||
|
bounds: 251, 239, 41, 38
|
||||||
|
front-open-hand
|
||||||
|
bounds: 856, 76, 43, 44
|
||||||
|
rotate: 90
|
||||||
|
front-thigh
|
||||||
|
bounds: 729, 178, 57, 29
|
||||||
|
rotate: 90
|
||||||
|
gun
|
||||||
|
bounds: 894, 251, 107, 103
|
||||||
|
gun-nohand
|
||||||
|
bounds: 764, 241, 105, 102
|
||||||
|
head
|
||||||
|
bounds: 756, 345, 136, 149
|
||||||
|
lower-leg
|
||||||
|
bounds: 475, 237, 73, 98
|
||||||
|
rotate: 90
|
||||||
|
mouth-grind
|
||||||
|
bounds: 975, 172, 47, 30
|
||||||
|
mouth-smile
|
||||||
|
bounds: 975, 140, 47, 30
|
||||||
|
neck
|
||||||
|
bounds: 366, 282, 18, 21
|
||||||
|
raptor-back-arm
|
||||||
|
bounds: 636, 97, 82, 86
|
||||||
|
rotate: 90
|
||||||
|
raptor-body
|
||||||
|
bounds: 2, 2, 632, 233
|
||||||
|
raptor-front-arm
|
||||||
|
bounds: 871, 168, 81, 102
|
||||||
|
rotate: 90
|
||||||
|
raptor-front-leg
|
||||||
|
bounds: 2, 237, 191, 257
|
||||||
|
raptor-hindleg-back
|
||||||
|
bounds: 195, 279, 169, 215
|
||||||
|
raptor-horn
|
||||||
|
bounds: 431, 312, 182, 80
|
||||||
|
rotate: 90
|
||||||
|
raptor-horn-back
|
||||||
|
bounds: 513, 318, 176, 77
|
||||||
|
rotate: 90
|
||||||
|
raptor-jaw
|
||||||
|
bounds: 894, 356, 126, 138
|
||||||
|
raptor-jaw-tooth
|
||||||
|
bounds: 294, 240, 37, 48
|
||||||
|
rotate: 90
|
||||||
|
raptor-mouth-inside
|
||||||
|
bounds: 344, 241, 36, 41
|
||||||
|
rotate: 90
|
||||||
|
raptor-saddle-strap-back
|
||||||
|
bounds: 575, 242, 54, 74
|
||||||
|
raptor-saddle-strap-front
|
||||||
|
bounds: 764, 182, 57, 95
|
||||||
|
rotate: 90
|
||||||
|
raptor-saddle-w-shadow
|
||||||
|
bounds: 592, 323, 162, 171
|
||||||
|
raptor-tail-shadow
|
||||||
|
bounds: 366, 305, 189, 63
|
||||||
|
rotate: 90
|
||||||
|
raptor-tongue
|
||||||
|
bounds: 387, 239, 86, 64
|
||||||
|
stirrup-back
|
||||||
|
bounds: 829, 136, 44, 35
|
||||||
|
rotate: 90
|
||||||
|
stirrup-front
|
||||||
|
bounds: 866, 121, 45, 50
|
||||||
|
rotate: 90
|
||||||
|
stirrup-strap
|
||||||
|
bounds: 918, 120, 49, 46
|
||||||
|
torso
|
||||||
|
bounds: 636, 181, 54, 91
|
||||||
|
rotate: 90
|
||||||
|
visor
|
||||||
|
bounds: 631, 237, 131, 84
|
||||||
BIN
spine-ts/spine-phaser/example/assets/raptor-pma.png
Normal file
BIN
spine-ts/spine-phaser/example/assets/raptor-pma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 409 KiB |
9161
spine-ts/spine-phaser/example/assets/raptor-pro.json
Normal file
9161
spine-ts/spine-phaser/example/assets/raptor-pro.json
Normal file
File diff suppressed because one or more lines are too long
102
spine-ts/spine-phaser/example/assets/spineboy-pma.atlas
Normal file
102
spine-ts/spine-phaser/example/assets/spineboy-pma.atlas
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
spineboy-pma.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
crosshair
|
||||||
|
bounds: 813, 160, 45, 45
|
||||||
|
eye-indifferent
|
||||||
|
bounds: 569, 2, 47, 45
|
||||||
|
eye-surprised
|
||||||
|
bounds: 643, 7, 47, 45
|
||||||
|
rotate: 90
|
||||||
|
front-bracer
|
||||||
|
bounds: 811, 51, 29, 40
|
||||||
|
front-fist-closed
|
||||||
|
bounds: 807, 93, 38, 41
|
||||||
|
front-fist-open
|
||||||
|
bounds: 815, 210, 43, 44
|
||||||
|
front-foot
|
||||||
|
bounds: 706, 64, 63, 35
|
||||||
|
rotate: 90
|
||||||
|
front-shin
|
||||||
|
bounds: 80, 11, 41, 92
|
||||||
|
front-thigh
|
||||||
|
bounds: 754, 12, 23, 56
|
||||||
|
front-upper-arm
|
||||||
|
bounds: 618, 5, 23, 49
|
||||||
|
goggles
|
||||||
|
bounds: 214, 20, 131, 83
|
||||||
|
gun
|
||||||
|
bounds: 347, 14, 105, 102
|
||||||
|
rotate: 90
|
||||||
|
head
|
||||||
|
bounds: 80, 105, 136, 149
|
||||||
|
hoverboard-board
|
||||||
|
bounds: 2, 8, 246, 76
|
||||||
|
rotate: 90
|
||||||
|
hoverboard-thruster
|
||||||
|
bounds: 478, 2, 30, 32
|
||||||
|
hoverglow-small
|
||||||
|
bounds: 218, 117, 137, 38
|
||||||
|
rotate: 90
|
||||||
|
mouth-grind
|
||||||
|
bounds: 775, 80, 47, 30
|
||||||
|
rotate: 90
|
||||||
|
mouth-oooo
|
||||||
|
bounds: 779, 31, 47, 30
|
||||||
|
rotate: 90
|
||||||
|
mouth-smile
|
||||||
|
bounds: 783, 207, 47, 30
|
||||||
|
rotate: 90
|
||||||
|
muzzle-glow
|
||||||
|
bounds: 779, 4, 25, 25
|
||||||
|
muzzle-ring
|
||||||
|
bounds: 451, 14, 25, 105
|
||||||
|
muzzle01
|
||||||
|
bounds: 664, 60, 67, 40
|
||||||
|
rotate: 90
|
||||||
|
muzzle02
|
||||||
|
bounds: 580, 56, 68, 42
|
||||||
|
rotate: 90
|
||||||
|
muzzle03
|
||||||
|
bounds: 478, 36, 83, 53
|
||||||
|
rotate: 90
|
||||||
|
muzzle04
|
||||||
|
bounds: 533, 49, 75, 45
|
||||||
|
rotate: 90
|
||||||
|
muzzle05
|
||||||
|
bounds: 624, 56, 68, 38
|
||||||
|
rotate: 90
|
||||||
|
neck
|
||||||
|
bounds: 806, 8, 18, 21
|
||||||
|
portal-bg
|
||||||
|
bounds: 258, 121, 133, 133
|
||||||
|
portal-flare1
|
||||||
|
bounds: 690, 2, 56, 30
|
||||||
|
rotate: 90
|
||||||
|
portal-flare2
|
||||||
|
bounds: 510, 3, 57, 31
|
||||||
|
portal-flare3
|
||||||
|
bounds: 722, 4, 58, 30
|
||||||
|
rotate: 90
|
||||||
|
portal-shade
|
||||||
|
bounds: 393, 121, 133, 133
|
||||||
|
portal-streaks1
|
||||||
|
bounds: 528, 126, 126, 128
|
||||||
|
portal-streaks2
|
||||||
|
bounds: 656, 129, 125, 125
|
||||||
|
rear-bracer
|
||||||
|
bounds: 826, 13, 28, 36
|
||||||
|
rear-foot
|
||||||
|
bounds: 743, 70, 57, 30
|
||||||
|
rotate: 90
|
||||||
|
rear-shin
|
||||||
|
bounds: 174, 14, 38, 89
|
||||||
|
rear-thigh
|
||||||
|
bounds: 783, 158, 28, 47
|
||||||
|
rear-upper-arm
|
||||||
|
bounds: 783, 136, 20, 44
|
||||||
|
rotate: 90
|
||||||
|
torso
|
||||||
|
bounds: 123, 13, 49, 90
|
||||||
BIN
spine-ts/spine-phaser/example/assets/spineboy-pma.png
Normal file
BIN
spine-ts/spine-phaser/example/assets/spineboy-pma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 239 KiB |
BIN
spine-ts/spine-phaser/example/assets/spineboy-pro.skel
Normal file
BIN
spine-ts/spine-phaser/example/assets/spineboy-pro.skel
Normal file
Binary file not shown.
16
spine-ts/spine-phaser/example/assets/stretchyman-pma.atlas
Normal file
16
spine-ts/spine-phaser/example/assets/stretchyman-pma.atlas
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
stretchyman-pma.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
back-arm
|
||||||
|
bounds: 149, 45, 72, 202
|
||||||
|
back-leg
|
||||||
|
bounds: 312, 4, 100, 318
|
||||||
|
rotate: 90
|
||||||
|
body
|
||||||
|
bounds: 223, 106, 141, 452
|
||||||
|
rotate: 90
|
||||||
|
front-arm
|
||||||
|
bounds: 2, 26, 145, 221
|
||||||
|
head
|
||||||
|
bounds: 223, 2, 87, 102
|
||||||
BIN
spine-ts/spine-phaser/example/assets/stretchyman-pma.png
Normal file
BIN
spine-ts/spine-phaser/example/assets/stretchyman-pma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
2116
spine-ts/spine-phaser/example/assets/stretchyman-pro.json
Normal file
2116
spine-ts/spine-phaser/example/assets/stretchyman-pro.json
Normal file
File diff suppressed because one or more lines are too long
BIN
spine-ts/spine-phaser/example/assets/stretchyman-pro.skel
Normal file
BIN
spine-ts/spine-phaser/example/assets/stretchyman-pro.skel
Normal file
Binary file not shown.
44
spine-ts/spine-phaser/example/basic-example.html
Normal file
44
spine-ts/spine-phaser/example/basic-example.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Basic example</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
63
spine-ts/spine-phaser/example/batching-test.html
Normal file
63
spine-ts/spine-phaser/example/batching-test.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Batching test</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
update: update,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
let debug;
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineJson("raptor-data", "assets/raptor-pro.json");
|
||||||
|
this.load.spineAtlas("raptor-atlas", "assets/raptor-pma.atlas");
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
let plugin = this.spine;
|
||||||
|
let x = 25;
|
||||||
|
let y = 60;
|
||||||
|
for (let j = 0; j < 10; j++, y+= 600 / 10) {
|
||||||
|
for (let i = 0; i < 20; i++, x += 800 / 20) {
|
||||||
|
let obj = Math.random() > 0.5
|
||||||
|
? this.add.spine(x, y, 'spineboy-data', "spineboy-atlas")
|
||||||
|
: this.add.spine(x, y, 'raptor-data', "raptor-atlas");
|
||||||
|
obj.animationState.setAnimation(0, "walk", true);
|
||||||
|
obj.scale = 0.1;
|
||||||
|
}
|
||||||
|
x = 25;
|
||||||
|
}
|
||||||
|
debug = this.add.text(0, 600 - 40, "FPS: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function update () {
|
||||||
|
debug.setText("draw calls: " + spine.PolygonBatcher.getAndResetGlobalDrawCalls() + "\ndelta: " + game.loop.delta);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
70
spine-ts/spine-phaser/example/blend-test.html
Normal file
70
spine-ts/spine-phaser/example/blend-test.html
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Blend test</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
backgroundColor: '#cdcdcd',
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
update: update
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let controls;
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
let obj = this.add.spine(i * 200, 600, 'spineboy-data', 'spineboy-atlas').setScale(0.25);
|
||||||
|
obj.setScale(0.25);
|
||||||
|
obj.animationState.setAnimation(0, "idle", true);
|
||||||
|
obj.animationState.setAnimation(1, "shoot", true);
|
||||||
|
}
|
||||||
|
var cursors = this.input.keyboard.createCursorKeys();
|
||||||
|
|
||||||
|
var controlConfig = {
|
||||||
|
camera: this.cameras.main,
|
||||||
|
left: cursors.left,
|
||||||
|
right: cursors.right,
|
||||||
|
up: cursors.up,
|
||||||
|
down: cursors.down,
|
||||||
|
zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q),
|
||||||
|
zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E),
|
||||||
|
acceleration: 0.35,
|
||||||
|
drag: 0.01,
|
||||||
|
maxSpeed: 1.2
|
||||||
|
};
|
||||||
|
|
||||||
|
controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update (time, delta) {
|
||||||
|
controls.update(delta);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
56
spine-ts/spine-phaser/example/bounds-test.html
Normal file
56
spine-ts/spine-phaser/example/bounds-test.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Bounds test</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
update: update,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
let spineboy;
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas", new spine.SkinsAndAnimationBoundsProvider("run"));
|
||||||
|
spineboy.scale = 0.4
|
||||||
|
spineboy.setInteractive();
|
||||||
|
this.input.enableDebug(spineboy, 0xff00ff);
|
||||||
|
spineboy.on("pointerdown", () => spineboy.animationState.setAnimation(0, "run", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
let time = 0;
|
||||||
|
function update (t, delta) {
|
||||||
|
time += delta / 1000;
|
||||||
|
let scale = 0.4 + Math.cos(time) * 0.2;
|
||||||
|
spineboy.scale = scale;
|
||||||
|
spineboy.angle++;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
113
spine-ts/spine-phaser/example/camera-pipeline-test.html
Normal file
113
spine-ts/spine-phaser/example/camera-pipeline-test.html
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Camera pipeline test</h1>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
backgroundColor: '#cdcdcd',
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fragShader = `
|
||||||
|
#define SHADER_NAME PLASMA_FS
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
uniform sampler2D uMainSampler;
|
||||||
|
uniform float uTime;
|
||||||
|
uniform vec2 uResolution;
|
||||||
|
|
||||||
|
varying vec2 outTexCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / uResolution.xy;
|
||||||
|
|
||||||
|
float x = p.x;
|
||||||
|
float y = p.y;
|
||||||
|
float mov0 = x+y+cos(sin(uTime)*2.0)*100.+sin(x/100.)*1000.;
|
||||||
|
float mov1 = y / 0.9 + uTime;
|
||||||
|
float mov2 = x / 0.2;
|
||||||
|
float c1 = abs(sin(mov1+uTime)/2.+mov2/2.-mov1-mov2+uTime);
|
||||||
|
float c2 = abs(sin(c1+sin(mov0/1000.+uTime)+sin(y/40.+uTime)+sin((x+y)/100.)*3.));
|
||||||
|
float c3 = abs(sin(c2+cos(mov1+mov2+c2)+cos(mov2)+sin(x/1000.)));
|
||||||
|
|
||||||
|
vec4 pixel = texture2D(uMainSampler, outTexCoord);
|
||||||
|
|
||||||
|
gl_FragColor = pixel * vec4(c1, c2, c3, 1);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
class PlasmaPostFX extends Phaser.Renderer.WebGL.Pipelines.PostFXPipeline {
|
||||||
|
constructor(game) {
|
||||||
|
super({
|
||||||
|
game,
|
||||||
|
name: 'PlasmaPostFX',
|
||||||
|
fragShader,
|
||||||
|
uniforms: [
|
||||||
|
'uMainSampler',
|
||||||
|
'uTime',
|
||||||
|
'uResolution'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onPreRender() {
|
||||||
|
this.set1f('uTime', this.game.loop.time / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDraw(renderTarget) {
|
||||||
|
this.set2f('uResolution', renderTarget.width, renderTarget.height);
|
||||||
|
|
||||||
|
this.bindAndDraw(renderTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
|
||||||
|
function preload() {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
this.load.image("img", "assets/raptor-pma.png")
|
||||||
|
}
|
||||||
|
|
||||||
|
function create() {
|
||||||
|
this.renderer.pipelines.addPostPipeline('PlasmaPostFX', PlasmaPostFX);
|
||||||
|
|
||||||
|
// FIXME: Need a dummy sprite so the MultiPipeline sets up state
|
||||||
|
// so rendering the Spine sprite actually works. Unsure what state
|
||||||
|
// is needed.
|
||||||
|
var s = this.add.sprite(0, 0, 'img');
|
||||||
|
|
||||||
|
let spineboy = this.add.spine(400, 300, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
|
||||||
|
this.cameras.main.setPostPipeline("PlasmaPostFX");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
71
spine-ts/spine-phaser/example/control-bones-test.html
Normal file
71
spine-ts/spine-phaser/example/control-bones-test.html
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Control bones</h1>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineBinary("stretchyman-data", "assets/stretchyman-pro.skel");
|
||||||
|
this.load.spineAtlas("stretchyman-atlas", "assets/stretchyman-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
let stretchyman = this.add.spine(400, 550, 'stretchyman-data', "stretchyman-atlas");
|
||||||
|
stretchyman.scale = 0.8;
|
||||||
|
stretchyman.skeleton.updateWorldTransform();
|
||||||
|
|
||||||
|
var controlBones = ["back-arm-ik-target", "back-leg-ik-target", "front-arm-ik-target", "front-leg-ik-target"];
|
||||||
|
for (var i = 0; i < controlBones.length; i++)
|
||||||
|
{
|
||||||
|
var bone = stretchyman.skeleton.findBone(controlBones[i]);
|
||||||
|
let point = {x: bone.worldX, y: bone.worldY};
|
||||||
|
stretchyman.skeletonToPhaserWorldCoordinates(point);
|
||||||
|
|
||||||
|
var control = this.add.circle(point.x, point.y, 4, 0xff00ff).setData('bone', bone);
|
||||||
|
|
||||||
|
control.setInteractive();
|
||||||
|
this.input.setDraggable(control);
|
||||||
|
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
|
||||||
|
|
||||||
|
gameObject.x = dragX;
|
||||||
|
gameObject.y = dragY;
|
||||||
|
|
||||||
|
var bone = gameObject.getData('bone');
|
||||||
|
let point = { x: dragX, y: dragY };
|
||||||
|
stretchyman.phaserWorldCoordinatesToBone(point, bone);
|
||||||
|
|
||||||
|
bone.x = point.x;
|
||||||
|
bone.y = point.y;
|
||||||
|
bone.update();
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
spine-ts/spine-phaser/example/index.html
Normal file
24
spine-ts/spine-phaser/example/index.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Spine Phaser</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a href="./basic-example.html">Basic example</a></li>
|
||||||
|
<li><a href="./batching-test.html">Batching test</a></li>
|
||||||
|
<li><a href="./multi-scene-test.html">Multi-scene test</a></li>
|
||||||
|
<li><a href="./bounds-test.html">Bounds test</a></li>
|
||||||
|
<li><a href="./visibility-test.html">Visibility test</a></li>
|
||||||
|
<li><a href="./arcade-physics-test.html">Arcade physics example</a></li>
|
||||||
|
<li><a href="./blend-test.html">Blend test</a></li>
|
||||||
|
<li><a href="./camera-pipeline-test.html">Camera pipeline test</a></li>
|
||||||
|
<li><a href="./control-bones-test.html">Control bones</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
65
spine-ts/spine-phaser/example/multi-scene-test.html
Normal file
65
spine-ts/spine-phaser/example/multi-scene-test.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Multi-scene test</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
class Scene1 extends Phaser.Scene {
|
||||||
|
constructor () {
|
||||||
|
super({key: "Scene1"})
|
||||||
|
}
|
||||||
|
|
||||||
|
preload() {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
let spineboy = this.add.spine(400, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
this.input.once('pointerdown', () => this.scene.start('Scene2'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Scene2 extends Phaser.Scene {
|
||||||
|
constructor () {
|
||||||
|
super({key: "Scene2"})
|
||||||
|
}
|
||||||
|
|
||||||
|
preload() {
|
||||||
|
this.load.spineJson("raptor-data", "assets/raptor-pro.json");
|
||||||
|
this.load.spineAtlas("raptor-atlas", "assets/raptor-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
let raptor = this.add.spine(300, 600, 'raptor-data', "raptor-atlas");
|
||||||
|
raptor.scale = 0.5;
|
||||||
|
raptor.animationState.setAnimation(0, "walk", true);
|
||||||
|
this.input.once('pointerdown', () => this.scene.start('Scene1'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: [ Scene1, Scene2 ],
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
BIN
spine-ts/spine-phaser/example/nyan.png
Normal file
BIN
spine-ts/spine-phaser/example/nyan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 563 B |
50
spine-ts/spine-phaser/example/visibility-test.html
Normal file
50
spine-ts/spine-phaser/example/visibility-test.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<!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/phaser@3.55.2/dist/phaser.js"></script>
|
||||||
|
<script src="../dist/iife/spine-phaser.js"></script>
|
||||||
|
<title>Spine Phaser Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Basic example</h1>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
type: Phaser.WEBGL,
|
||||||
|
scene: {
|
||||||
|
preload: preload,
|
||||||
|
create: create,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
scene: [
|
||||||
|
{ key: "spine.SpinePlugin", plugin: spine.SpinePlugin, mapping: "spine" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let game = new Phaser.Game(config);
|
||||||
|
|
||||||
|
function preload () {
|
||||||
|
this.load.spineBinary("spineboy-data", "assets/spineboy-pro.skel");
|
||||||
|
this.load.spineAtlas("spineboy-atlas", "assets/spineboy-pma.atlas");
|
||||||
|
}
|
||||||
|
|
||||||
|
function create () {
|
||||||
|
let spineboy = this.add.spine(250, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy.scale = 0.5;
|
||||||
|
spineboy.animationState.setAnimation(0, "walk", true);
|
||||||
|
|
||||||
|
let spineboy2 = this.add.spine(550, 500, 'spineboy-data', "spineboy-atlas");
|
||||||
|
spineboy2.scale = 0.5;
|
||||||
|
spineboy2.animationState.setAnimation(0, "run", true);
|
||||||
|
|
||||||
|
this.input.on('pointerdown', () => spineboy2.visible = !spineboy2.visible);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
38
spine-ts/spine-phaser/package.json
Normal file
38
spine-ts/spine-phaser/package.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"name": "@esotericsoftware/spine-phaser",
|
||||||
|
"version": "4.2.10",
|
||||||
|
"description": "The official Spine Runtimes for the Phaser.",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"files": [
|
||||||
|
"dist/**/*",
|
||||||
|
"README.md",
|
||||||
|
"LICENSE"
|
||||||
|
],
|
||||||
|
"scripts": {},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/esotericsoftware/spine-runtimes.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"gamedev",
|
||||||
|
"animations",
|
||||||
|
"2d",
|
||||||
|
"spine",
|
||||||
|
"game-dev",
|
||||||
|
"runtimes",
|
||||||
|
"skeletal"
|
||||||
|
],
|
||||||
|
"author": "Esoteric Software LLC",
|
||||||
|
"license": "LicenseRef-LICENSE",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/esotericsoftware/spine-runtimes/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/esotericsoftware/spine-runtimes#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"@esotericsoftware/spine-core": "^4.2.10",
|
||||||
|
"@esotericsoftware/spine-webgl": "^4.2.10",
|
||||||
|
"@esotericsoftware/spine-canvas": "^4.2.10",
|
||||||
|
"phaser": "^3.55.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
255
spine-ts/spine-phaser/src/SpineGameObject.ts
Normal file
255
spine-ts/spine-phaser/src/SpineGameObject.ts
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
import { SPINE_GAME_OBJECT_TYPE } from "./keys";
|
||||||
|
import { SpinePlugin } from "./SpinePlugin";
|
||||||
|
import { ComputedSizeMixin, DepthMixin, FlipMixin, ScrollFactorMixin, TransformMixin, VisibleMixin } from "./mixins";
|
||||||
|
import { AnimationState, AnimationStateData, Bone, MathUtils, Skeleton, Skin, Vector2 } from "@esotericsoftware/spine-core";
|
||||||
|
import { Vector3 } from "@esotericsoftware/spine-webgl";
|
||||||
|
|
||||||
|
class BaseSpineGameObject extends Phaser.GameObjects.GameObject {
|
||||||
|
constructor(scene: Phaser.Scene, type: string) {
|
||||||
|
super(scene, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SpineGameObjectBoundsProvider {
|
||||||
|
calculateBounds(gameObject: SpineGameObject): { x: number, y: number, width: number, height: number };
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SetupPoseBoundsProvider implements SpineGameObjectBoundsProvider {
|
||||||
|
calculateBounds(gameObject: SpineGameObject) {
|
||||||
|
if (!gameObject.skeleton) return { x: 0, y: 0, width: 0, height: 0 };
|
||||||
|
// Make a copy of animation state and skeleton as this might be called while
|
||||||
|
// the skeleton in the GameObject has already been heavily modified. We can not
|
||||||
|
// reconstruct that state.
|
||||||
|
const skeleton = new Skeleton(gameObject.skeleton.data);
|
||||||
|
skeleton.setToSetupPose();
|
||||||
|
skeleton.updateWorldTransform();
|
||||||
|
return skeleton.getBoundsRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SkinsAndAnimationBoundsProvider implements SpineGameObjectBoundsProvider {
|
||||||
|
constructor(private animation: string, private skins: string[] = [], private timeStep: number = 0.05) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateBounds(gameObject: SpineGameObject): { x: number; y: number; width: number; height: number; } {
|
||||||
|
if (!gameObject.skeleton || !gameObject.animationState) return { x: 0, y: 0, width: 0, height: 0 };
|
||||||
|
// Make a copy of animation state and skeleton as this might be called while
|
||||||
|
// the skeleton in the GameObject has already been heavily modified. We can not
|
||||||
|
// reconstruct that state.
|
||||||
|
const animationState = new AnimationState(gameObject.animationState.data);
|
||||||
|
const skeleton = new Skeleton(gameObject.skeleton.data);
|
||||||
|
const data = skeleton.data;
|
||||||
|
if (this.skins.length > 0) {
|
||||||
|
let customSkin = new Skin("custom-skin");
|
||||||
|
for (const skinName of this.skins) {
|
||||||
|
const skin = data.findSkin(skinName);
|
||||||
|
if (skin == null) continue;
|
||||||
|
customSkin.addSkin(skin);
|
||||||
|
}
|
||||||
|
skeleton.setSkin(customSkin);
|
||||||
|
}
|
||||||
|
skeleton.setToSetupPose();
|
||||||
|
|
||||||
|
const animation = this.animation != null ? data.findAnimation(this.animation!) : null;
|
||||||
|
if (animation == null) {
|
||||||
|
skeleton.updateWorldTransform();
|
||||||
|
return skeleton.getBoundsRect();
|
||||||
|
} else {
|
||||||
|
let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
|
||||||
|
animationState.clearTracks();
|
||||||
|
animationState.setAnimationWith(0, animation, false);
|
||||||
|
const steps = Math.max(animation.duration / this.timeStep, 1.0);
|
||||||
|
for (let i = 0; i < steps; i++) {
|
||||||
|
animationState.update(i > 0 ? this.timeStep : 0);
|
||||||
|
animationState.apply(skeleton);
|
||||||
|
skeleton.updateWorldTransform();
|
||||||
|
|
||||||
|
const bounds = skeleton.getBoundsRect();
|
||||||
|
minX = Math.min(minX, bounds.x);
|
||||||
|
minY = Math.min(minY, bounds.y);
|
||||||
|
maxX = Math.max(maxX, minX + bounds.width);
|
||||||
|
maxY = Math.max(maxY, minY + bounds.height);
|
||||||
|
}
|
||||||
|
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SpineGameObject extends ComputedSizeMixin(DepthMixin(FlipMixin(ScrollFactorMixin(TransformMixin(VisibleMixin(BaseSpineGameObject)))))) {
|
||||||
|
blendMode = -1;
|
||||||
|
skeleton: Skeleton | null = null;
|
||||||
|
animationStateData: AnimationStateData | null = null;
|
||||||
|
animationState: AnimationState | null = null;
|
||||||
|
private premultipliedAlpha = false;
|
||||||
|
private _displayOriginX = 0;
|
||||||
|
private _displayOriginY = 0;
|
||||||
|
private _scaleX = 1;
|
||||||
|
private _scaleY = 1;
|
||||||
|
|
||||||
|
constructor(scene: Phaser.Scene, private plugin: SpinePlugin, x: number, y: number, dataKey: string, atlasKey: string, public boundsProvider: SpineGameObjectBoundsProvider = new SetupPoseBoundsProvider()) {
|
||||||
|
super(scene, SPINE_GAME_OBJECT_TYPE);
|
||||||
|
this.setPosition(x, y); x
|
||||||
|
this.setSkeleton(dataKey, atlasKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSkeleton(dataKey: string, atlasKey: string) {
|
||||||
|
if (dataKey && atlasKey) {
|
||||||
|
this.premultipliedAlpha = this.plugin.isAtlasPremultiplied(atlasKey);
|
||||||
|
this.skeleton = this.plugin.createSkeleton(dataKey, atlasKey);
|
||||||
|
this.animationStateData = new AnimationStateData(this.skeleton.data);
|
||||||
|
this.animationState = new AnimationState(this.animationStateData);
|
||||||
|
this.updateSize();
|
||||||
|
} else {
|
||||||
|
this.skeleton = null;
|
||||||
|
this.animationStateData = null;
|
||||||
|
this.animationState = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get displayOriginX() {
|
||||||
|
return this._displayOriginX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set displayOriginX(value: number) {
|
||||||
|
this._displayOriginX = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get displayOriginY() {
|
||||||
|
return this._displayOriginY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set displayOriginY(value: number) {
|
||||||
|
this._displayOriginY = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get scaleX() {
|
||||||
|
return this._scaleX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set scaleX(value: number) {
|
||||||
|
this._scaleX = value;
|
||||||
|
this.updateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get scaleY() {
|
||||||
|
return this._scaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set scaleY(value: number) {
|
||||||
|
this._scaleY = value;
|
||||||
|
this.updateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSize() {
|
||||||
|
if (!this.skeleton) return;
|
||||||
|
let bounds = this.boundsProvider.calculateBounds(this);
|
||||||
|
// For some reason the TS compiler and the ComputedSize mixin don't work well together...
|
||||||
|
let self = this as any;
|
||||||
|
self.width = bounds.width;
|
||||||
|
self.height = bounds.height;
|
||||||
|
this.displayOriginX = -bounds.x;
|
||||||
|
this.displayOriginY = -bounds.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
skeletonToPhaserWorldCoordinates(point: {x: number, y: number}) {
|
||||||
|
let transform = this.getWorldTransformMatrix();
|
||||||
|
let a = transform.a, b = transform.b, c = transform.c, d = transform.d, tx = transform.tx, ty = transform.ty;
|
||||||
|
let x = point.x
|
||||||
|
let y = point.y
|
||||||
|
point.x = x * a + y * c + tx;
|
||||||
|
point.y = x * b + y * d + ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
phaserWorldCoordinatesToSkeleton(point: {x: number, y: number}) {
|
||||||
|
let transform = this.getWorldTransformMatrix();
|
||||||
|
transform = transform.invert();
|
||||||
|
let a = transform.a, b = transform.b, c = transform.c, d = transform.d, tx = transform.tx, ty = transform.ty;
|
||||||
|
let x = point.x
|
||||||
|
let y = point.y
|
||||||
|
point.x = x * a + y * c + tx;
|
||||||
|
point.y = x * b + y * d + ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
phaserWorldCoordinatesToBone(point: {x: number, y: number}, bone: Bone) {
|
||||||
|
this.phaserWorldCoordinatesToSkeleton(point);
|
||||||
|
if (bone.parent) {
|
||||||
|
bone.parent.worldToLocal(point as Vector2);
|
||||||
|
} else {
|
||||||
|
bone.worldToLocal(point as Vector2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preUpdate(time: number, delta: number) {
|
||||||
|
if (!this.skeleton || !this.animationState) return;
|
||||||
|
|
||||||
|
this.animationState.update(delta / 1000);
|
||||||
|
this.animationState.apply(this.skeleton);
|
||||||
|
this.skeleton.updateWorldTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
preDestroy() {
|
||||||
|
this.skeleton = null;
|
||||||
|
this.animationState = null;
|
||||||
|
// FIXME tear down any event emitters
|
||||||
|
}
|
||||||
|
|
||||||
|
willRender(camera: Phaser.Cameras.Scene2D.Camera) {
|
||||||
|
if (!this.visible) return false;
|
||||||
|
|
||||||
|
var GameObjectRenderMask = 0xf;
|
||||||
|
var result = (!this.skeleton || !(GameObjectRenderMask !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderWebGL(renderer: Phaser.Renderer.WebGL.WebGLRenderer, src: SpineGameObject, camera: Phaser.Cameras.Scene2D.Camera, parentMatrix: Phaser.GameObjects.Components.TransformMatrix) {
|
||||||
|
if (!this.skeleton || !this.animationState || !this.plugin.webGLRenderer) return;
|
||||||
|
|
||||||
|
let sceneRenderer = this.plugin.webGLRenderer;
|
||||||
|
if (renderer.newType) {
|
||||||
|
renderer.pipelines.clear();
|
||||||
|
sceneRenderer.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.addToRenderList(src);
|
||||||
|
let transform = Phaser.GameObjects.GetCalcMatrix(src, camera, parentMatrix).calc;
|
||||||
|
let a = transform.a, b = transform.b, c = transform.c, d = transform.d, tx = transform.tx, ty = transform.ty;
|
||||||
|
sceneRenderer.drawSkeleton(this.skeleton, this.premultipliedAlpha, -1, -1, (vertices, numVertices, stride) => {
|
||||||
|
for (let i = 0; i < numVertices; i += stride) {
|
||||||
|
let vx = vertices[i];
|
||||||
|
let vy = vertices[i + 1];
|
||||||
|
vertices[i] = vx * a + vy * c + tx;
|
||||||
|
vertices[i + 1] = vx * b + vy * d + ty;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!renderer.nextTypeMatch) {
|
||||||
|
sceneRenderer.end();
|
||||||
|
renderer.pipelines.rebind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCanvas(renderer: Phaser.Renderer.Canvas.CanvasRenderer, src: SpineGameObject, camera: Phaser.Cameras.Scene2D.Camera, parentMatrix: Phaser.GameObjects.Components.TransformMatrix) {
|
||||||
|
if (!this.skeleton || !this.animationState || !this.plugin.canvasRenderer) return;
|
||||||
|
|
||||||
|
let context = renderer.currentContext;
|
||||||
|
let skeletonRenderer = this.plugin.canvasRenderer;
|
||||||
|
(skeletonRenderer as any).ctx = context;
|
||||||
|
|
||||||
|
camera.addToRenderList(src);
|
||||||
|
let transform = Phaser.GameObjects.GetCalcMatrix(src, camera, parentMatrix).calc;
|
||||||
|
let skeleton = this.skeleton;
|
||||||
|
skeleton.x = transform.tx;
|
||||||
|
skeleton.y = transform.ty;
|
||||||
|
skeleton.scaleX = transform.scaleX;
|
||||||
|
skeleton.scaleY = transform.scaleY;
|
||||||
|
let root = skeleton.getRootBone()!;
|
||||||
|
root.rotation = -MathUtils.radiansToDegrees * transform.rotationNormalized;
|
||||||
|
this.skeleton.updateWorldTransform();
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
skeletonRenderer.draw(skeleton);
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
315
spine-ts/spine-phaser/src/SpinePlugin.ts
Normal file
315
spine-ts/spine-phaser/src/SpinePlugin.ts
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated September 24, 2021. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2021, Esoteric Software LLC
|
||||||
|
*
|
||||||
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||||
|
* http://esotericsoftware.com/spine-editor-license
|
||||||
|
*
|
||||||
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
* "Products"), provided that each user of the Products must obtain their own
|
||||||
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
|
* include this license and copyright notice.
|
||||||
|
*
|
||||||
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { SPINE_ATLAS_CACHE_KEY, SPINE_CONTAINER_TYPE, SPINE_GAME_OBJECT_TYPE, SPINE_ATLAS_TEXTURE_CACHE_KEY, SPINE_SKELETON_DATA_FILE_TYPE, SPINE_ATLAS_FILE_TYPE, SPINE_SKELETON_FILE_CACHE_KEY as SPINE_SKELETON_DATA_CACHE_KEY } from "./keys";
|
||||||
|
import { AtlasAttachmentLoader, Bone, GLTexture, SceneRenderer, Skeleton, SkeletonBinary, SkeletonData, SkeletonJson, TextureAtlas } from "@esotericsoftware/spine-webgl"
|
||||||
|
import { SpineGameObject, SpineGameObjectBoundsProvider } from "./SpineGameObject";
|
||||||
|
import { CanvasTexture, SkeletonRenderer } from "@esotericsoftware/spine-canvas";
|
||||||
|
|
||||||
|
export class SpinePlugin extends Phaser.Plugins.ScenePlugin {
|
||||||
|
game: Phaser.Game;
|
||||||
|
isWebGL: boolean;
|
||||||
|
gl: WebGLRenderingContext | null;
|
||||||
|
textureManager: Phaser.Textures.TextureManager;
|
||||||
|
phaserRenderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer | null;
|
||||||
|
webGLRenderer: SceneRenderer | null;
|
||||||
|
canvasRenderer: SkeletonRenderer | null;
|
||||||
|
skeletonDataCache: Phaser.Cache.BaseCache;
|
||||||
|
atlasCache: Phaser.Cache.BaseCache;
|
||||||
|
|
||||||
|
constructor (scene: Phaser.Scene, pluginManager: Phaser.Plugins.PluginManager, pluginKey: string) {
|
||||||
|
super(scene, pluginManager, pluginKey);
|
||||||
|
var game = this.game = pluginManager.game;
|
||||||
|
this.isWebGL = this.game.config.renderType === 2;
|
||||||
|
this.gl = this.isWebGL ? (this.game.renderer as Phaser.Renderer.WebGL.WebGLRenderer).gl : null;
|
||||||
|
this.textureManager = this.game.textures;
|
||||||
|
this.phaserRenderer = this.game.renderer;
|
||||||
|
this.webGLRenderer = null;
|
||||||
|
this.canvasRenderer = null;
|
||||||
|
this.skeletonDataCache = this.game.cache.addCustom(SPINE_SKELETON_DATA_CACHE_KEY);
|
||||||
|
this.atlasCache = this.game.cache.addCustom(SPINE_ATLAS_CACHE_KEY);
|
||||||
|
|
||||||
|
if (!this.phaserRenderer) {
|
||||||
|
this.phaserRenderer = {
|
||||||
|
width: game.scale.width,
|
||||||
|
height: game.scale.height,
|
||||||
|
preRender: () => { },
|
||||||
|
postRender: () => { },
|
||||||
|
render: () => { },
|
||||||
|
destroy: () => { }
|
||||||
|
} as unknown as Phaser.Renderer.Canvas.CanvasRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let skeletonJsonFileCallback = function (this: any, key: string,
|
||||||
|
url: string,
|
||||||
|
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
|
let file = new SpineSkeletonDataFile(this as any, key, url, SpineSkeletonDataFileType.json, xhrSettings);
|
||||||
|
this.addFile(file.files);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
pluginManager.registerFileType("spineJson", skeletonJsonFileCallback, scene);
|
||||||
|
|
||||||
|
|
||||||
|
let skeletonBinaryFileCallback = function (this: any, key: string,
|
||||||
|
url: string,
|
||||||
|
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
|
let file = new SpineSkeletonDataFile(this as any, key, url, SpineSkeletonDataFileType.binary, xhrSettings);
|
||||||
|
this.addFile(file.files);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
pluginManager.registerFileType("spineBinary", skeletonBinaryFileCallback, scene);
|
||||||
|
|
||||||
|
|
||||||
|
let atlasFileCallback = function (this: any, key: string,
|
||||||
|
url: string,
|
||||||
|
premultipliedAlpha: boolean,
|
||||||
|
xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
|
let file = new SpineAtlasFile(this as any, key, url, premultipliedAlpha, xhrSettings);
|
||||||
|
this.addFile(file.files);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
pluginManager.registerFileType("spineAtlas", atlasFileCallback, scene);
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
let addSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, x: number, y: number, dataKey: string, atlasKey: string, boundsProvider: SpineGameObjectBoundsProvider) {
|
||||||
|
let gameObject = new SpineGameObject(scene, self, x, y, dataKey, atlasKey, boundsProvider);
|
||||||
|
this.displayList.add(gameObject);
|
||||||
|
this.updateList.add(gameObject);
|
||||||
|
return gameObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
let makeSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, config: any, addToScene: boolean) {
|
||||||
|
let dataKey = config.dataKey ? config.dataKey : null;
|
||||||
|
let atlasKey = config.atlasKey ? config.atlasKey : null;
|
||||||
|
let gameObject = new SpineGameObject(this.scene, self, 0, 0, dataKey, atlasKey);
|
||||||
|
if (addToScene !== undefined) {
|
||||||
|
config.add = addToScene;
|
||||||
|
}
|
||||||
|
Phaser.GameObjects.BuildGameObject(this.scene, gameObject, config);
|
||||||
|
}
|
||||||
|
pluginManager.registerGameObject(SPINE_GAME_OBJECT_TYPE, addSpineGameObject, makeSpineGameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
boot () {
|
||||||
|
Skeleton.yDown = true;
|
||||||
|
if (this.isWebGL) {
|
||||||
|
if (!this.webGLRenderer) {
|
||||||
|
this.webGLRenderer = new SceneRenderer((this.phaserRenderer! as Phaser.Renderer.WebGL.WebGLRenderer).canvas, this.gl!, true);
|
||||||
|
}
|
||||||
|
this.game.scale.on(Phaser.Scale.Events.RESIZE, this.onResize, this);
|
||||||
|
} else {
|
||||||
|
if (!this.canvasRenderer) {
|
||||||
|
this.canvasRenderer = new SkeletonRenderer(this.scene.sys.context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var eventEmitter = this.systems.events;
|
||||||
|
eventEmitter.once('shutdown', this.shutdown, this);
|
||||||
|
eventEmitter.once('destroy', this.destroy, this);
|
||||||
|
this.game.events.once('destroy', this.gameDestroy, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onResize () {
|
||||||
|
var phaserRenderer = this.phaserRenderer;
|
||||||
|
var sceneRenderer = this.webGLRenderer;
|
||||||
|
|
||||||
|
if (phaserRenderer && sceneRenderer) {
|
||||||
|
var viewportWidth = phaserRenderer.width;
|
||||||
|
var viewportHeight = phaserRenderer.height;
|
||||||
|
sceneRenderer.camera.position.x = viewportWidth / 2;
|
||||||
|
sceneRenderer.camera.position.y = viewportHeight / 2;
|
||||||
|
sceneRenderer.camera.up.y = -1;
|
||||||
|
sceneRenderer.camera.direction.z = 1;
|
||||||
|
sceneRenderer.camera.setViewport(viewportWidth, viewportHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown () {
|
||||||
|
this.systems.events.off("shutdown", this.shutdown, this);
|
||||||
|
if (this.isWebGL) {
|
||||||
|
this.game.scale.off(Phaser.Scale.Events.RESIZE, this.onResize, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy () {
|
||||||
|
this.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
gameDestroy () {
|
||||||
|
this.pluginManager.removeGameObject(SPINE_GAME_OBJECT_TYPE, true, true);
|
||||||
|
this.pluginManager.removeGameObject(SPINE_CONTAINER_TYPE, true, true);
|
||||||
|
if (this.webGLRenderer) this.webGLRenderer.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
isAtlasPremultiplied(atlasKey: string) {
|
||||||
|
let atlasFile = this.game.cache.text.get(atlasKey);
|
||||||
|
if (!atlasFile) return false;
|
||||||
|
return atlasFile.premultipliedAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
createSkeleton (dataKey: string, atlasKey: string) {
|
||||||
|
let atlas: TextureAtlas;
|
||||||
|
if (this.atlasCache.exists(atlasKey)) {
|
||||||
|
atlas = this.atlasCache.get(atlasKey);
|
||||||
|
} else {
|
||||||
|
let atlasFile = this.game.cache.text.get(atlasKey) as { data: string, premultipliedAlpha: boolean };
|
||||||
|
atlas = new TextureAtlas(atlasFile.data);
|
||||||
|
if (this.isWebGL) {
|
||||||
|
let gl = this.gl!;
|
||||||
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
||||||
|
for (let atlasPage of atlas.pages) {
|
||||||
|
atlasPage.setTexture(new GLTexture(gl, this.textureManager.get(atlasKey + "!" + atlasPage.name).getSourceImage() as HTMLImageElement | ImageBitmap, false));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let atlasPage of atlas.pages) {
|
||||||
|
atlasPage.setTexture(new CanvasTexture(this.textureManager.get(atlasKey + "!" + atlasPage.name).getSourceImage() as HTMLImageElement | ImageBitmap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.atlasCache.add(atlasKey, atlas);
|
||||||
|
}
|
||||||
|
|
||||||
|
let skeletonData: SkeletonData;
|
||||||
|
if (this.skeletonDataCache.exists(dataKey)) {
|
||||||
|
skeletonData = this.skeletonDataCache.get(dataKey);
|
||||||
|
} else {
|
||||||
|
if (this.game.cache.json.exists(dataKey)) {
|
||||||
|
let jsonFile = this.game.cache.json.get(dataKey) as any;
|
||||||
|
let json = new SkeletonJson(new AtlasAttachmentLoader(atlas));
|
||||||
|
skeletonData = json.readSkeletonData(jsonFile);
|
||||||
|
} else {
|
||||||
|
let binaryFile = this.game.cache.binary.get(dataKey) as ArrayBuffer;
|
||||||
|
let binary = new SkeletonBinary(new AtlasAttachmentLoader(atlas));
|
||||||
|
skeletonData = binary.readSkeletonData(new Uint8Array(binaryFile));
|
||||||
|
}
|
||||||
|
this.skeletonDataCache.add(dataKey, skeletonData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Skeleton(skeletonData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SpineSkeletonDataFileType {
|
||||||
|
json,
|
||||||
|
binary
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SpineSkeletonDataFile extends Phaser.Loader.MultiFile {
|
||||||
|
constructor (loader: Phaser.Loader.LoaderPlugin, key: string, url: string, public fileType: SpineSkeletonDataFileType, xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
|
let file = null;
|
||||||
|
let isJson = fileType == SpineSkeletonDataFileType.json;
|
||||||
|
if (isJson) {
|
||||||
|
file = new Phaser.Loader.FileTypes.JSONFile(loader, {
|
||||||
|
key: key,
|
||||||
|
url: url,
|
||||||
|
extension: "json",
|
||||||
|
xhrSettings: xhrSettings,
|
||||||
|
} as Phaser.Types.Loader.FileTypes.JSONFileConfig);
|
||||||
|
} else {
|
||||||
|
file = new Phaser.Loader.FileTypes.BinaryFile(loader, {
|
||||||
|
key: key,
|
||||||
|
url: url,
|
||||||
|
extension: "skel",
|
||||||
|
xhrSettings: xhrSettings,
|
||||||
|
} as Phaser.Types.Loader.FileTypes.BinaryFileConfig);
|
||||||
|
}
|
||||||
|
super(loader, SPINE_SKELETON_DATA_FILE_TYPE, key, [file]);
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileComplete (file: Phaser.Loader.File) {
|
||||||
|
this.pending--;
|
||||||
|
}
|
||||||
|
|
||||||
|
addToCache () {
|
||||||
|
if (this.isReadyToProcess()) this.files[0].addToCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SpineAtlasFile extends Phaser.Loader.MultiFile {
|
||||||
|
constructor (loader: Phaser.Loader.LoaderPlugin, key: string, url: string, public premultipliedAlpha: boolean = true, xhrSettings: Phaser.Types.Loader.XHRSettingsObject) {
|
||||||
|
super(loader, SPINE_ATLAS_FILE_TYPE, key, [
|
||||||
|
new Phaser.Loader.FileTypes.TextFile(loader, {
|
||||||
|
key: key,
|
||||||
|
url: url,
|
||||||
|
xhrSettings: xhrSettings,
|
||||||
|
extension: "atlas"
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileComplete (file: Phaser.Loader.File) {
|
||||||
|
if (this.files.indexOf(file) != -1) {
|
||||||
|
this.pending--;
|
||||||
|
|
||||||
|
if (file.type == "text") {
|
||||||
|
var lines = file.data.split('\n');
|
||||||
|
let textures = [];
|
||||||
|
textures.push(lines[0]);
|
||||||
|
for (var t = 1; t < lines.length; t++) {
|
||||||
|
var line = lines[t];
|
||||||
|
if (line.trim() === '' && t < lines.length - 1) {
|
||||||
|
line = lines[t + 1];
|
||||||
|
textures.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let basePath = file.src.match(/^.*\//);
|
||||||
|
for (var i = 0; i < textures.length; i++) {
|
||||||
|
var url = basePath + textures[i];
|
||||||
|
var key = file.key + "!" + textures[i];
|
||||||
|
var image = new Phaser.Loader.FileTypes.ImageFile(this.loader, key, url);
|
||||||
|
|
||||||
|
if (!this.loader.keyExists(image)) {
|
||||||
|
this.addToMultiFile(image);
|
||||||
|
this.loader.addFile(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addToCache () {
|
||||||
|
if (this.isReadyToProcess()) {
|
||||||
|
let textureManager = this.loader.textureManager;
|
||||||
|
for (let file of this.files) {
|
||||||
|
if (file.type == "image") {
|
||||||
|
if (!textureManager.exists(file.key)) {
|
||||||
|
textureManager.addImage(file.key, file.data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file.data = {
|
||||||
|
data: file.data,
|
||||||
|
premultipliedAlpha: this.premultipliedAlpha || file.data.indexOf("pma: true") >= 0
|
||||||
|
};
|
||||||
|
file.addToCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
spine-ts/spine-phaser/src/index.ts
Normal file
8
spine-ts/spine-phaser/src/index.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export * from "./require-shim"
|
||||||
|
export * from "./SpinePlugin"
|
||||||
|
export * from "./SpineGameObject"
|
||||||
|
export * from "./mixins"
|
||||||
|
export * from "@esotericsoftware/spine-core";
|
||||||
|
export * from "@esotericsoftware/spine-webgl";
|
||||||
|
import { SpinePlugin } from "./SpinePlugin";
|
||||||
|
(window as any).spine = { SpinePlugin: SpinePlugin };
|
||||||
8
spine-ts/spine-phaser/src/keys.ts
Normal file
8
spine-ts/spine-phaser/src/keys.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export const SPINE_SKELETON_FILE_CACHE_KEY = "esotericsoftware.spine.skeletonFile.cache";
|
||||||
|
export const SPINE_ATLAS_CACHE_KEY = "esotericsoftware.spine.atlas.cache";
|
||||||
|
export const SPINE_ATLAS_TEXTURE_CACHE_KEY = "esotericsoftware.spine.atlas.texture.cache";
|
||||||
|
export const SPINE_LOADER_TYPE = "spine";
|
||||||
|
export const SPINE_SKELETON_DATA_FILE_TYPE = "spineSkeletonData";
|
||||||
|
export const SPINE_ATLAS_FILE_TYPE = "spineAtlasData";
|
||||||
|
export const SPINE_GAME_OBJECT_TYPE = "spine";
|
||||||
|
export const SPINE_CONTAINER_TYPE = "spineContainer";
|
||||||
77
spine-ts/spine-phaser/src/mixins.ts
Normal file
77
spine-ts/spine-phaser/src/mixins.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2021-present AgogPixel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Adapted from https://github.com/agogpixel/phaser3-ts-utils/tree/main
|
||||||
|
|
||||||
|
let components = (Phaser.GameObjects.Components as any);
|
||||||
|
export const ComputedSize = components.ComputedSize;
|
||||||
|
export const Depth = components.Depth;
|
||||||
|
export const Flip = components.Flip;
|
||||||
|
export const ScrollFactor = components.ScrollFactor;
|
||||||
|
export const Transform = components.Transform;
|
||||||
|
export const Visible = components.Visible;
|
||||||
|
|
||||||
|
export interface Type<
|
||||||
|
T,
|
||||||
|
P extends any[] = any[]
|
||||||
|
> extends Function {
|
||||||
|
new(...args: P): T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Mixin<GameObjectComponent, GameObjectConstraint extends Phaser.GameObjects.GameObject> = <
|
||||||
|
GameObjectType extends Type<GameObjectConstraint>
|
||||||
|
>(
|
||||||
|
BaseGameObject: GameObjectType
|
||||||
|
) => GameObjectType & Type<GameObjectComponent>;
|
||||||
|
|
||||||
|
export function createMixin<
|
||||||
|
GameObjectComponent,
|
||||||
|
GameObjectConstraint extends Phaser.GameObjects.GameObject = Phaser.GameObjects.GameObject
|
||||||
|
> (
|
||||||
|
...component: GameObjectComponent[]
|
||||||
|
): Mixin<GameObjectComponent, GameObjectConstraint> {
|
||||||
|
return (BaseGameObject) => {
|
||||||
|
(Phaser as any).Class.mixin(BaseGameObject, component);
|
||||||
|
return BaseGameObject as any;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComputedSizeMixin = Mixin<Phaser.GameObjects.Components.Transform, Phaser.GameObjects.GameObject>;
|
||||||
|
export const ComputedSizeMixin: ComputedSizeMixin = createMixin<Phaser.GameObjects.Components.ComputedSize>(ComputedSize);
|
||||||
|
|
||||||
|
type DepthMixin = Mixin<Phaser.GameObjects.Components.Depth, Phaser.GameObjects.GameObject>;
|
||||||
|
export const DepthMixin: DepthMixin = createMixin<Phaser.GameObjects.Components.Depth>(Depth);
|
||||||
|
|
||||||
|
type FlipMixin = Mixin<Phaser.GameObjects.Components.Flip, Phaser.GameObjects.GameObject>;
|
||||||
|
export const FlipMixin: FlipMixin = createMixin<Phaser.GameObjects.Components.Flip>(Flip);
|
||||||
|
|
||||||
|
type ScrollFactorMixin = Mixin<Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.GameObject>;
|
||||||
|
export const ScrollFactorMixin: ScrollFactorMixin = createMixin<Phaser.GameObjects.Components.ScrollFactor>(ScrollFactor);
|
||||||
|
|
||||||
|
type TransformMixin = Mixin<Phaser.GameObjects.Components.Transform, Phaser.GameObjects.GameObject>;
|
||||||
|
export const TransformMixin: TransformMixin = createMixin<Phaser.GameObjects.Components.Transform>(Transform);
|
||||||
|
|
||||||
|
type VisibleMixin = Mixin<Phaser.GameObjects.Components.Visible, Phaser.GameObjects.GameObject>;
|
||||||
|
export const VisibleMixin: VisibleMixin = createMixin<Phaser.GameObjects.Components.Visible>(Visible);
|
||||||
|
|
||||||
11
spine-ts/spine-phaser/src/require-shim.ts
Normal file
11
spine-ts/spine-phaser/src/require-shim.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
declare global {
|
||||||
|
var require: any;
|
||||||
|
}
|
||||||
|
if (window.Phaser) {
|
||||||
|
let prevRequire = window.require;
|
||||||
|
window.require = (x: string) => {
|
||||||
|
if (prevRequire) return prevRequire(x);
|
||||||
|
else if (x === "Phaser") return window.Phaser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { }
|
||||||
36
spine-ts/spine-phaser/tsconfig.json
Normal file
36
spine-ts/spine-phaser/tsconfig.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"paths": {
|
||||||
|
"@esotericsoftware/spine-core": [
|
||||||
|
"../spine-core/src"
|
||||||
|
],
|
||||||
|
"@esotericsoftware/spine-canvas": [
|
||||||
|
"../spine-canvas/src"
|
||||||
|
],
|
||||||
|
"@esotericsoftware/spine-webgl": [
|
||||||
|
"../spine-webgl/src"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.ts",
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"dist/**/*.d.ts"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../spine-core"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../spine-canvas"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../spine-webgl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -36,6 +36,7 @@ import { ManagedWebGLRenderingContext } from "./WebGL";
|
|||||||
export class PolygonBatcher implements Disposable {
|
export class PolygonBatcher implements Disposable {
|
||||||
private context: ManagedWebGLRenderingContext;
|
private context: ManagedWebGLRenderingContext;
|
||||||
private drawCalls = 0;
|
private drawCalls = 0;
|
||||||
|
private static globalDrawCalls = 0;
|
||||||
private isDrawing = false;
|
private isDrawing = false;
|
||||||
private mesh: Mesh;
|
private mesh: Mesh;
|
||||||
private shader: Shader | null = null;
|
private shader: Shader | null = null;
|
||||||
@ -120,6 +121,7 @@ export class PolygonBatcher implements Disposable {
|
|||||||
this.mesh.setVerticesLength(0);
|
this.mesh.setVerticesLength(0);
|
||||||
this.mesh.setIndicesLength(0);
|
this.mesh.setIndicesLength(0);
|
||||||
this.drawCalls++;
|
this.drawCalls++;
|
||||||
|
PolygonBatcher.globalDrawCalls++;
|
||||||
}
|
}
|
||||||
|
|
||||||
end () {
|
end () {
|
||||||
@ -138,6 +140,12 @@ export class PolygonBatcher implements Disposable {
|
|||||||
return this.drawCalls;
|
return this.drawCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getAndResetGlobalDrawCalls () {
|
||||||
|
let result = PolygonBatcher.globalDrawCalls;
|
||||||
|
PolygonBatcher.globalDrawCalls = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
dispose () {
|
dispose () {
|
||||||
this.mesh.dispose();
|
this.mesh.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import { PolygonBatcher } from "./PolygonBatcher";
|
|||||||
import { Shader } from "./Shader";
|
import { Shader } from "./Shader";
|
||||||
import { ShapeRenderer } from "./ShapeRenderer";
|
import { ShapeRenderer } from "./ShapeRenderer";
|
||||||
import { SkeletonDebugRenderer } from "./SkeletonDebugRenderer";
|
import { SkeletonDebugRenderer } from "./SkeletonDebugRenderer";
|
||||||
import { SkeletonRenderer } from "./SkeletonRenderer";
|
import { SkeletonRenderer, VertexTransformer } from "./SkeletonRenderer";
|
||||||
import { ManagedWebGLRenderingContext } from "./WebGL";
|
import { ManagedWebGLRenderingContext } from "./WebGL";
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -86,10 +86,10 @@ export class SceneRenderer implements Disposable {
|
|||||||
this.enableRenderer(this.batcher);
|
this.enableRenderer(this.batcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawSkeleton (skeleton: Skeleton, premultipliedAlpha = false, slotRangeStart = -1, slotRangeEnd = -1) {
|
drawSkeleton (skeleton: Skeleton, premultipliedAlpha = false, slotRangeStart = -1, slotRangeEnd = -1, transform: VertexTransformer | null = null) {
|
||||||
this.enableRenderer(this.batcher);
|
this.enableRenderer(this.batcher);
|
||||||
this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
|
this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
|
||||||
this.skeletonRenderer.draw(this.batcher, skeleton, slotRangeStart, slotRangeEnd);
|
this.skeletonRenderer.draw(this.batcher, skeleton, slotRangeStart, slotRangeEnd, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawSkeletonDebug (skeleton: Skeleton, premultipliedAlpha = false, ignoredBones?: Array<string>) {
|
drawSkeletonDebug (skeleton: Skeleton, premultipliedAlpha = false, ignoredBones?: Array<string>) {
|
||||||
|
|||||||
@ -37,6 +37,8 @@ class Renderable {
|
|||||||
constructor (public vertices: NumberArrayLike, public numVertices: number, public numFloats: number) { }
|
constructor (public vertices: NumberArrayLike, public numVertices: number, public numFloats: number) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type VertexTransformer = (vertices: NumberArrayLike, numVertices: number, stride: number) => void;
|
||||||
|
|
||||||
export class SkeletonRenderer {
|
export class SkeletonRenderer {
|
||||||
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ export class SkeletonRenderer {
|
|||||||
this.vertices = Utils.newFloatArray(this.vertexSize * 1024);
|
this.vertices = Utils.newFloatArray(this.vertexSize * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw (batcher: PolygonBatcher, skeleton: Skeleton, slotRangeStart: number = -1, slotRangeEnd: number = -1) {
|
draw (batcher: PolygonBatcher, skeleton: Skeleton, slotRangeStart: number = -1, slotRangeEnd: number = -1, transformer: VertexTransformer | null = null) {
|
||||||
let clipper = this.clipper;
|
let clipper = this.clipper;
|
||||||
let premultipliedAlpha = this.premultipliedAlpha;
|
let premultipliedAlpha = this.premultipliedAlpha;
|
||||||
let twoColorTint = this.twoColorTint;
|
let twoColorTint = this.twoColorTint;
|
||||||
@ -174,6 +176,7 @@ export class SkeletonRenderer {
|
|||||||
clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
|
clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
|
||||||
let clippedVertices = new Float32Array(clipper.clippedVertices);
|
let clippedVertices = new Float32Array(clipper.clippedVertices);
|
||||||
let clippedTriangles = clipper.clippedTriangles;
|
let clippedTriangles = clipper.clippedTriangles;
|
||||||
|
if (transformer) transformer(renderable.vertices, renderable.numFloats, vertexSize);
|
||||||
batcher.draw(texture, clippedVertices, clippedTriangles);
|
batcher.draw(texture, clippedVertices, clippedTriangles);
|
||||||
} else {
|
} else {
|
||||||
let verts = renderable.vertices;
|
let verts = renderable.vertices;
|
||||||
@ -201,6 +204,7 @@ export class SkeletonRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let view = (renderable.vertices as Float32Array).subarray(0, renderable.numFloats);
|
let view = (renderable.vertices as Float32Array).subarray(0, renderable.numFloats);
|
||||||
|
if (transformer) transformer(renderable.vertices, renderable.numFloats, vertexSize);
|
||||||
batcher.draw(texture, view, triangles);
|
batcher.draw(texture, view, triangles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
"DOM",
|
"DOM",
|
||||||
"ES2015"
|
"ES2015",
|
||||||
|
"ScriptHost"
|
||||||
],
|
],
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"composite": true,
|
"composite": true,
|
||||||
|
|||||||
@ -10,6 +10,9 @@
|
|||||||
{
|
{
|
||||||
"path": "./spine-webgl"
|
"path": "./spine-webgl"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "./spine-phaser"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "./spine-player"
|
"path": "./spine-player"
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user