浏览代码

[ts][phaser-v3][phaser-v4] Fixed gameobject position when it is rotated.

Davide Tantillo 4 月之前
父节点
当前提交
15766e8ef2

+ 59 - 1
spine-ts/spine-phaser-v3/example/move-origin.html

@@ -13,12 +13,15 @@
   <body class="p-4 flex flex-col items-center">
     <h1>Move origin</h1>
     <h2>Demonstrate moving origin of Spine Gameobject, behaves like a sprite</h2>
+    <h2>When you use matter physics, origin is reset, because the body always stays around the game object.
+      Change game object size only after the object has been added to matter.</h2>
   </body>
   <script>
     let cursors;
     let spineboy;
     const levelWidth = 800;
     const levelHeight = 600;
+    const gameobjects = []
 
     class BasicExample extends Phaser.Scene {
       preload() {
@@ -51,6 +54,7 @@
           }
         }
 
+        const physicsCells = cells.splice(cells.length - 2, 2);
 
         let animations = undefined;
         let prevWidth = 0;
@@ -80,6 +84,8 @@
             prevHeight = gameobject.displayHeight;
           }
 
+          gameobjects.push(gameobject)
+
           // moving origin at the center of the cell, we're still able to align spineboy and keep gameobject bounds align with the drawn skeleton
           const origin = 1 / (cells.length / 2 - 1) * Math.floor(i / 2)
 
@@ -122,10 +128,55 @@
           gameobject.on("pointerout", () => defaultGraphicsElements());
         })
 
+        const [physicsCell1, physicsCell2] = physicsCells;
+        const spineboy = this.add.spine(0, 0, "spineboy-data", "spineboy-atlas");
+
+        this.matter.add.gameObject(spineboy);
+
+        spineboy.displayWidth = (spineboy.width / spineboy.height) * height * .5;
+        spineboy.displayHeight = height * .5;
+
+        spineboy.x = physicsCell1.x + spineboy.displayWidth;
+        spineboy.y = physicsCell1.y + spineboy.displayHeight;
+
+        spineboy.setInteractive();
+        this.input.enableDebug(spineboy, 0xff00ff);
+        spineboy.on("pointerover", () => {
+          spineboy.y -= 50;
+          spineboy.x += 10;
+        });
+
+        const block = this.add.image(0, 0, "block");
+
+        this.matter.add.gameObject(block);
+
+        block.displayWidth = (block.width / block.height) * height * .5;
+        block.displayHeight = height * .5;
+
+        block.x = physicsCell2.x + block.displayWidth;
+        block.y = physicsCell2.y + block.displayHeight;
+
+        block.setInteractive();
+        this.input.enableDebug(block, 0xff00ff);
+        block.on("pointerover", () => {
+          block.y -= 50;
+          block.x += 10;
+        });
+
+        this.matter.add.rectangle(levelWidth - width, levelHeight - height, levelWidth, 1, { isStatic: true });
+        this.matter.add.rectangle(levelWidth - width, levelHeight - 2 * height, levelWidth, 1, { isStatic: true });
+        this.matter.add.rectangle(levelWidth - width, levelHeight, levelWidth, 1, { isStatic: true });
+        this.matter.add.rectangle(levelWidth - width, levelHeight - 2 * height, 1, height * 4, { isStatic: true });
+        this.matter.add.rectangle(levelWidth, levelHeight - 2 * height, 1, height * 4, { isStatic: true });
       }
 
-    }
+      update(params) {
+        gameobjects.forEach((go) => {
+          go.angle += 0.05;
+        })
+      }
 
+    }
 
     new Phaser.Game({
       type: Phaser.AUTO,
@@ -133,6 +184,13 @@
       height: levelHeight,
       type: Phaser.WEBGL,
       scene: [BasicExample],
+      physics: {
+        default: 'matter',
+        matter: {
+            debug: true,
+            gravity: { y: .15 },
+        },
+      },
       plugins: {
         scene: [
           {

+ 6 - 6
spine-ts/spine-phaser-v3/src/SpineGameObject.ts

@@ -369,8 +369,8 @@ export class SpineGameObject extends DepthMixin(
 			tx = transform.tx,
 			ty = transform.ty;
 
-		let offsetX = (src.offsetX - src.displayOriginX) * src.scaleX;
-		let offsetY = (src.offsetY - src.displayOriginY) * src.scaleY;
+		let offsetX = src.offsetX - src.displayOriginX;
+		let offsetY = src.offsetY - src.displayOriginY;
 
 		sceneRenderer.drawSkeleton(
 			src.skeleton,
@@ -379,10 +379,10 @@ export class SpineGameObject extends DepthMixin(
 			-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 + offsetX;
-					vertices[i + 1] = vx * b + vy * d + ty + offsetY;
+					let vx = vertices[i] + offsetX;
+					let vy = vertices[i + 1] + offsetY;
+					vertices[i] = vx * a + vy * c + tx;
+					vertices[i + 1] = vx * b + vy * d + ty;
 				}
 			}
 		);

+ 59 - 1
spine-ts/spine-phaser-v4/example/move-origin.html

@@ -13,12 +13,15 @@
   <body class="p-4 flex flex-col items-center">
     <h1>Move origin</h1>
     <h2>Demonstrate moving origin of Spine Gameobject, behaves like a sprite</h2>
+    <h2>When you use matter physics, origin is reset, because the body always stays around the game object.
+      Change game object size only after the object has been added to matter.</h2>
   </body>
   <script>
     let cursors;
     let spineboy;
     const levelWidth = 800;
     const levelHeight = 600;
+    const gameobjects = []
 
     class BasicExample extends Phaser.Scene {
       preload() {
@@ -51,6 +54,7 @@
           }
         }
 
+        const physicsCells = cells.splice(cells.length - 2, 2);
 
         let animations = undefined;
         let prevWidth = 0;
@@ -80,6 +84,8 @@
             prevHeight = gameobject.displayHeight;
           }
 
+          gameobjects.push(gameobject)
+
           // moving origin at the center of the cell, we're still able to align spineboy and keep gameobject bounds align with the drawn skeleton
           const origin = 1 / (cells.length / 2 - 1) * Math.floor(i / 2)
 
@@ -122,10 +128,55 @@
           gameobject.on("pointerout", () => defaultGraphicsElements());
         })
 
+        const [physicsCell1, physicsCell2] = physicsCells;
+        const spineboy = this.add.spine(0, 0, "spineboy-data", "spineboy-atlas");
+
+        this.matter.add.gameObject(spineboy);
+
+        spineboy.displayWidth = (spineboy.width / spineboy.height) * height * .5;
+        spineboy.displayHeight = height * .5;
+
+        spineboy.x = physicsCell1.x + spineboy.displayWidth;
+        spineboy.y = physicsCell1.y + spineboy.displayHeight;
+
+        spineboy.setInteractive();
+        this.input.enableDebug(spineboy, 0xff00ff);
+        spineboy.on("pointerover", () => {
+          spineboy.y -= 50;
+          spineboy.x += 10;
+        });
+
+        const block = this.add.image(0, 0, "block");
+
+        this.matter.add.gameObject(block);
+
+        block.displayWidth = (block.width / block.height) * height * .5;
+        block.displayHeight = height * .5;
+
+        block.x = physicsCell2.x + block.displayWidth;
+        block.y = physicsCell2.y + block.displayHeight;
+
+        block.setInteractive();
+        this.input.enableDebug(block, 0xff00ff);
+        block.on("pointerover", () => {
+          block.y -= 50;
+          block.x += 10;
+        });
+
+        this.matter.add.rectangle(levelWidth - width, levelHeight - height, levelWidth, 1, { isStatic: true });
+        this.matter.add.rectangle(levelWidth - width, levelHeight - 2 * height, levelWidth, 1, { isStatic: true });
+        this.matter.add.rectangle(levelWidth - width, levelHeight, levelWidth, 1, { isStatic: true });
+        this.matter.add.rectangle(levelWidth - width, levelHeight - 2 * height, 1, height * 4, { isStatic: true });
+        this.matter.add.rectangle(levelWidth, levelHeight - 2 * height, 1, height * 4, { isStatic: true });
       }
 
-    }
+      update(params) {
+        gameobjects.forEach((go) => {
+          go.angle += 0.05;
+        })
+      }
 
+    }
 
     new Phaser.Game({
       type: Phaser.AUTO,
@@ -133,6 +184,13 @@
       height: levelHeight,
       type: Phaser.WEBGL,
       scene: [BasicExample],
+      physics: {
+        default: 'matter',
+        matter: {
+            debug: true,
+            gravity: { y: .15 },
+        },
+      },
       plugins: {
         scene: [
           {

+ 6 - 6
spine-ts/spine-phaser-v4/src/SpineGameObject.ts

@@ -388,8 +388,8 @@ export class SpineGameObject extends DepthMixin(
 			tx = transform.tx,
 			ty = transform.ty;
 
-		let offsetX = (src.offsetX - src.displayOriginX) * src.scaleX;
-		let offsetY = (src.offsetY - src.displayOriginY) * src.scaleY;
+		let offsetX = src.offsetX - src.displayOriginX;
+		let offsetY = src.offsetY - src.displayOriginY;
 
 		sceneRenderer.drawSkeleton(
 			src.skeleton,
@@ -398,10 +398,10 @@ export class SpineGameObject extends DepthMixin(
 			-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 + offsetX;
-					vertices[i + 1] = vx * b + vy * d + ty + offsetY;
+					let vx = vertices[i] + offsetX;
+					let vy = vertices[i + 1] + offsetY;
+					vertices[i] = vx * a + vy * c + tx;
+					vertices[i + 1] = vx * b + vy * d + ty;
 				}
 			}
 		);