diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e6ac397..99b8205c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,9 @@ are returned ### Fixed +- Fixed issue where `ex.ColliderComponent` was not deeply cloning the stored `ex.Collider` causing them to be shared across clones. +- Fixed issue where `ex.GraphicsComponent` was not deeploy cloning the +stored `ex.Graphics` causing them to be shared across clones. - Fixed issue where `Actor.clone()` and `Entity.clone()` crashed. - Fixed issue where zero mtv collisions cause erroneous precollision events to be fired in the `ArcadeSolver` and `RealisticSolver` - Fixed issue where calling `.kill()` on a child entity would not remove it from the parent `Entity` diff --git a/sandbox/index.html b/sandbox/index.html index e2668111..efa580c3 100644 --- a/sandbox/index.html +++ b/sandbox/index.html @@ -10,6 +10,7 @@
The clones should be 2 separate colors and no collision handler should fire in the console.
+ + + + \ No newline at end of file diff --git a/sandbox/tests/clonebehavior/index.ts b/sandbox/tests/clonebehavior/index.ts new file mode 100644 index 00000000..3248387f --- /dev/null +++ b/sandbox/tests/clonebehavior/index.ts @@ -0,0 +1,32 @@ +var game = new ex.Engine({ + width: 800, + height: 600, +}); + +game.start(); + +var paddle = new ex.Actor({ + x: 150, y: 40, + width: 200, height: 20, + color: ex.Color.Chartreuse, + collisionType: ex.CollisionType.Active, +}); +game.add(paddle); + +var paddle2 = paddle.clone(); + +paddle2.pos.x = 400; +paddle2.color = ex.Color.Red; +paddle2.on('collisionstart', (ev)=>{console.log(ev);}); +game.add(paddle2); + +ex.Physics.useRealisticPhysics(); +ex.Physics.gravity = ex.vec(0,60); + +const wall = new ex.Actor({ + x: 100, y: 400, + width: 200, height: 20, + color: ex.Color.Black, + collisionType: ex.CollisionType.Fixed +}); +game.add(wall); \ No newline at end of file diff --git a/src/engine/Collision/ColliderComponent.ts b/src/engine/Collision/ColliderComponent.ts index 9e49c7db..6650930f 100644 --- a/src/engine/Collision/ColliderComponent.ts +++ b/src/engine/Collision/ColliderComponent.ts @@ -70,6 +70,12 @@ export class ColliderComponent extends Component<'ex.collider'> { } } + public clone(): ColliderComponent { + const clone = new ColliderComponent(this._collider.clone()); + + return clone; + } + /** * Return world space bounds */ diff --git a/src/engine/Graphics/GraphicsComponent.ts b/src/engine/Graphics/GraphicsComponent.ts index 2f681dbb..8ec8fc3a 100644 --- a/src/engine/Graphics/GraphicsComponent.ts +++ b/src/engine/Graphics/GraphicsComponent.ts @@ -179,7 +179,7 @@ export class GraphicsLayer { public clone(graphicsComponent: GraphicsComponent): GraphicsLayer { const layer = new GraphicsLayer({...this._options}, graphicsComponent); - layer.graphics = [...this.graphics.map(g => ({graphic: g.graphic, options: {...g.options}}))]; + layer.graphics = [...this.graphics.map(g => ({graphic: g.graphic.clone(), options: {...g.options}}))]; return layer; } } diff --git a/src/spec/ColliderComponentSpec.ts b/src/spec/ColliderComponentSpec.ts index 94925437..7f54ed12 100644 --- a/src/spec/ColliderComponentSpec.ts +++ b/src/spec/ColliderComponentSpec.ts @@ -21,8 +21,14 @@ describe('A ColliderComponent', () => { const collider = new ex.ColliderComponent(ex.Shape.Circle(50)); const owner = new ex.Entity([collider]); + const originalCollisionHandler = jasmine.createSpy(); + owner.on('collisionstart', originalCollisionHandler); + const clone = owner.clone(); + const cloneCollisionHandler = jasmine.createSpy(); + clone.on('collisionstart', cloneCollisionHandler); + const sut = clone.get(ex.ColliderComponent); // Should be same value @@ -34,6 +40,16 @@ describe('A ColliderComponent', () => { // Should have a new owner expect(sut.owner).toBe(clone); + + // Original handler should fire not the clone + collider.get().events.emit('collisionstart', + new ex.CollisionStartEvent