Skip to content

Commit 7c7d915

Browse files
committed
Sprite.crop (and Image.crop) has been completely overhauled. You can now crop animated sprites (sprite sheet and texture atlas), you can define the x/y crop offset and the crop rectangle is exposed in the Sprite.cropRect property.
Sprite.updateCrop is available if you wish to update an externally referenced crop rectangle. Sprites and Images now have their own textures objects, they are no longer references to those stored in the global Pixi.TextureCache. This allows you to redefine the texture frame dynamically without messing up any other Sprites in your game, such as via cropping. They still share global Base Textures, so image references are kept to a minimum. Sprite.resetFrame will revert the Sprites texture frame back to its defaults dimensions. This is called when you call Sprite.crop with no rectangle, to reset the crop effect, but can be userful in other situations so we've left it as a public method.
1 parent 6d10be6 commit 7c7d915

9 files changed

Lines changed: 385 additions & 308 deletions

File tree

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ By Richard Davey, [Photon Storm](http://www.photonstorm.com)
1616
* Read the [documentation online](http://docs.phaser.io)
1717
* Join our [#phaserio IRC channel](http://www.html5gamedevs.com/topic/4470-official-phaserio-irc-channel-phaserio-on-freenode/) on freenode
1818
* Subscribe to the [Phaser Newsletter](https://confirmsubscription.com/h/r/369DE48E3E86AF1E) and we'll email you when new versions are released.
19+
* Please help support our work via [Gittip](https://www.gittip.com/photonstorm/)
1920

2021
![div](http://phaser.io/images/div4.png)
2122

@@ -66,6 +67,8 @@ Version 2.0.6 - "Jornhill" - -in development-
6667
* Emitter.start has a new parameter: forceQuantity which will force the quantity of a flow of particles to be the given value (request #853)
6768
* Sound.pause will no longer fire a Sound.onStop signal, and the pause values are set before the onPause signal is dispatched (thanks @AnderbergE, fix #868)
6869
* Swapped to using escaped Unicode characters for the console output.
70+
* Frame.setTrim no longer modifies the Frame width and height values.
71+
* AnimationParser doesn't populate the Pixi.TextureCache for every frame any longer. Each display object has its own texture property instead.
6972

7073
### CocoonJS Specific Updates
7174

@@ -93,6 +96,10 @@ Version 2.0.6 - "Jornhill" - -in development-
9396
* Loader.totalLoadedPacks returns the number of Asset Packs already loaded.
9497
* Emitter.explode is a new short-cut for exploding a fixed quantity of particles at once.
9598
* Emitter.flow is a new short-cut for creating a flow of particles based on the given frequency.
99+
* Sprite.crop (and Image.crop) has been completely overhauled. You can now crop animated sprites (sprite sheet and texture atlas), you can define the x/y crop offset and the crop rectangle is exposed in the Sprite.cropRect property.
100+
* Sprite.updateCrop is available if you wish to update an externally referenced crop rectangle.
101+
* Sprites and Images now have their own textures objects, they are no longer references to those stored in the global Pixi.TextureCache. This allows you to redefine the texture frame dynamically without messing up any other Sprites in your game, such as via cropping. They still share global Base Textures, so image references are kept to a minimum.
102+
* Sprite.resetFrame will revert the Sprites texture frame back to its defaults dimensions. This is called when you call Sprite.crop with no rectangle, to reset the crop effect, but can be userful in other situations so we've left it as a public method.
96103

97104

98105
### Bug Fixes
@@ -284,14 +291,18 @@ Here are some of the features planned for future releases:
284291

285292
### Version 2.1 ("Shienar")
286293

294+
* Scene Manager - json scene parser.
287295
* Comprehensive testing across Firefox OS devices, CocoonJS and Ejecta.
288296
* Ability to control DOM elements from the core game and layer them into the game.
289297
* Touch Gestures.
298+
* Optimised global Animation manager to cut down on object creation.
299+
* Swapping to using a RenderTexture for the Tilemaps and implementing Tilemap slicing.
300+
* Enhance the State Management, so you can perform non-destructive State swaps and persistence.
301+
* Support for parallel asset loading.
290302

291303
### Version 2.2 ("Tarabon")
292304

293-
* Enhance the State Management, so you can perform non-destructive State swaps and persistence.
294-
* Support for parallel asset loading.
305+
* Look carefully at the internal structure of Phaser to avoid method repetition (such as Sprite.crop and Image.crop), investigate using mixins to help reduce overall codebase size.
295306
* Flash CC HTML5 export integration.
296307
* Massively enhance the audio side of Phaser. Take more advantage of Web Audio: echo effects, positional sound, etc.
297308

build/phaser.d.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,6 +2240,7 @@ declare module Phaser {
22402240
anchor: Phaser.Point;
22412241
autoCull: boolean;
22422242
cameraOffset: Phaser.Point;
2243+
cropRect: Phaser.Rectangle;
22432244
deltaX: number;
22442245
deltaY: number;
22452246
deltaZ: number;
@@ -2264,16 +2265,18 @@ declare module Phaser {
22642265
z: number;
22652266

22662267
bringToTop(): Phaser.Image;
2267-
crop(rect: Phaser.Rectangle): void;
2268-
crop(rect: Object): void;
2268+
crop(rect: Phaser.Rectangle, copy: boolean): void;
22692269
destroy(destroyChildren?: boolean): void;
22702270
kill(): Phaser.Image;
22712271
loadTexture(key: any, frame: any): void;
22722272
postUpdate(): void;
22732273
preUpdate(): void;
22742274
reset(x: number, y: number): Phaser.Image;
2275+
resetFrame(): void;
22752276
revive(): Phaser.Image;
2277+
setFrame(frame: Phaser.Frame): void;
22762278
update(): void;
2279+
updateCrop(): void;
22772280

22782281
}
22792282

@@ -4295,6 +4298,7 @@ declare module Phaser {
42954298
body: any;
42964299
cameraOffset: Phaser.Point;
42974300
checkWorldBounds: boolean;
4301+
cropRect: Phaser.Rectangle;
42984302
debug: boolean;
42994303
deltaX: number;
43004304
deltaY: number;
@@ -4327,7 +4331,7 @@ declare module Phaser {
43274331
z: number;
43284332

43294333
bringToTop(): Phaser.Sprite;
4330-
crop(rect: Phaser.Rectangle): void;
4334+
crop(rect: Phaser.Rectangle, copy: boolean): void;
43314335
damage(amount: number): Phaser.Sprite;
43324336
destroy(destroyChildren?: boolean): void;
43334337
drawPolygon(): void;
@@ -4338,8 +4342,11 @@ declare module Phaser {
43384342
postUpdate(): void;
43394343
preUpdate(): void;
43404344
reset(x: number, y: number, health?: number): Phaser.Sprite;
4345+
resetFrame(): void;
43414346
revive(health?: number): Phaser.Sprite;
4347+
setFrame(frame: Phaser.Frame): void;
43424348
update(): void;
4349+
updateCrop(): void;
43434350

43444351
}
43454352

src/animation/Animation.js

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,7 @@ Phaser.Animation.prototype = {
185185

186186
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
187187

188-
this._parent.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
189-
190-
// this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
188+
this._parent.setFrame(this.currentFrame);
191189

192190
// TODO: Double check if required
193191
if (this._parent.__tilePattern)
@@ -197,6 +195,7 @@ Phaser.Animation.prototype = {
197195
}
198196

199197
this._parent.events.onAnimationStart.dispatch(this._parent, this);
198+
200199
this.onStart.dispatch(this._parent, this);
201200

202201
return this;
@@ -222,6 +221,8 @@ Phaser.Animation.prototype = {
222221

223222
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
224223

224+
this._parent.setFrame(this.currentFrame);
225+
225226
this.onStart.dispatch(this._parent, this);
226227

227228
},
@@ -304,6 +305,7 @@ Phaser.Animation.prototype = {
304305
if (resetFrame)
305306
{
306307
this.currentFrame = this._frameData.getFrame(this._frames[0]);
308+
this._parent.setFrame(this.currentFrame);
307309
}
308310

309311
if (dispatchComplete)
@@ -367,7 +369,6 @@ Phaser.Animation.prototype = {
367369
{
368370
// We need to skip a frame, work out how many
369371
this._frameSkip = Math.floor(this._frameDiff / this.delay);
370-
371372
this._frameDiff -= (this._frameSkip * this.delay);
372373
}
373374

@@ -382,21 +383,7 @@ Phaser.Animation.prototype = {
382383
{
383384
this._frameIndex %= this._frames.length;
384385
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
385-
386-
// if (this.currentFrame)
387-
// {
388-
// this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
389-
// this._parent.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
390-
391-
// if (this._parent.__tilePattern)
392-
// {
393-
// this._parent.__tilePattern = false;
394-
// this._parent.tilingTexture = false;
395-
// }
396-
// }
397-
398386
this.loopCount++;
399-
// console.log('loop', this.loopCount);
400387
this._parent.events.onAnimationLoop.dispatch(this._parent, this);
401388
this.onLoop.dispatch(this._parent, this);
402389
}
@@ -405,20 +392,13 @@ Phaser.Animation.prototype = {
405392
this.complete();
406393
}
407394
}
408-
// else
409-
// {
410-
// }
411395

412396
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
413397

414398
if (this.currentFrame)
415399
{
416-
// this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
417-
// this._parent.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
418400
this._parent.setFrame(this.currentFrame);
419401

420-
// console.log('a1', this._parent.texture.frame, PIXI.TextureCache[this.currentFrame.uuid].frame);
421-
422402
if (this._parent.__tilePattern)
423403
{
424404
this._parent.__tilePattern = false;
@@ -556,9 +536,7 @@ Object.defineProperty(Phaser.Animation.prototype, 'frame', {
556536
if (this.currentFrame !== null)
557537
{
558538
this._frameIndex = value;
559-
// this._parent.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
560539
this._parent.setFrame(this.currentFrame);
561-
// this._parent.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
562540
}
563541

564542
}

src/animation/AnimationManager.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,6 @@ Phaser.AnimationManager.prototype = {
160160
this.currentFrame = this.currentAnim.currentFrame;
161161

162162
this.sprite.setFrame(this.currentFrame);
163-
// this.sprite.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
164-
// this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
165163

166164
if (this.sprite.__tilePattern)
167165
{
@@ -447,8 +445,6 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frame', {
447445
this._frameIndex = value;
448446

449447
this.sprite.setFrame(this.currentFrame);
450-
// this.sprite.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
451-
// this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
452448

453449
if (this.sprite.__tilePattern)
454450
{
@@ -486,9 +482,8 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frameName', {
486482
if (this.currentFrame)
487483
{
488484
this._frameIndex = this.currentFrame.index;
485+
489486
this.sprite.setFrame(this.currentFrame);
490-
// this.sprite.setFrame(this.currentFrame.x, this.currentFrame.y, this.currentFrame.width, this.currentFrame.height);
491-
// this.sprite.setTexture(PIXI.TextureCache[this.currentFrame.uuid]);
492487

493488
if (this.sprite.__tilePattern)
494489
{

src/animation/AnimationParser.js

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,6 @@ Phaser.AnimationParser = {
7575
// uuid needed?
7676
data.addFrame(new Phaser.Frame(i, x, y, frameWidth, frameHeight, '', uuid));
7777

78-
// PIXI.TextureCache[uuid] = new PIXI.Texture(PIXI.BaseTextureCache[key], {
79-
// x: x,
80-
// y: y,
81-
// width: frameWidth,
82-
// height: frameHeight
83-
// });
84-
8578
x += frameWidth + spacing;
8679

8780
if (x + frameWidth > width)
@@ -135,27 +128,8 @@ Phaser.AnimationParser = {
135128
uuid
136129
));
137130

138-
// PIXI.TextureCache[uuid] = new PIXI.Texture(PIXI.BaseTextureCache[cacheKey], {
139-
// x: frames[i].frame.x,
140-
// y: frames[i].frame.y,
141-
// width: frames[i].frame.w,
142-
// height: frames[i].frame.h
143-
// });
144-
145-
/*
146-
"filename": "octopus0000",
147-
"frame": {"x":888,"y":1399,"w":82,"h":88},
148-
"rotated": false,
149-
"trimmed": true,
150-
"spriteSourceSize": {"x":0,"y":0,"w":82,"h":95},
151-
"sourceSize": {"w":82,"h":95}
152-
153-
*/
154-
155131
if (frames[i].trimmed)
156132
{
157-
// setTrim: function (trimmed, actualWidth, actualHeight, destX, destY, destWidth, destHeight) {
158-
159133
newFrame.setTrim(
160134
frames[i].trimmed,
161135
frames[i].sourceSize.w,
@@ -165,11 +139,7 @@ Phaser.AnimationParser = {
165139
frames[i].spriteSourceSize.w,
166140
frames[i].spriteSourceSize.h
167141
);
168-
169-
170-
// PIXI.TextureCache[uuid].trim = new Phaser.Rectangle(frames[i].spriteSourceSize.x, frames[i].spriteSourceSize.y, frames[i].sourceSize.w, frames[i].sourceSize.h);
171142
}
172-
173143
}
174144

175145
return data;
@@ -217,13 +187,6 @@ Phaser.AnimationParser = {
217187
uuid
218188
));
219189

220-
PIXI.TextureCache[uuid] = new PIXI.Texture(PIXI.BaseTextureCache[cacheKey], {
221-
x: frames[key].frame.x,
222-
y: frames[key].frame.y,
223-
width: frames[key].frame.w,
224-
height: frames[key].frame.h
225-
});
226-
227190
if (frames[key].trimmed)
228191
{
229192
newFrame.setTrim(
@@ -235,8 +198,6 @@ Phaser.AnimationParser = {
235198
frames[key].spriteSourceSize.w,
236199
frames[key].spriteSourceSize.h
237200
);
238-
239-
PIXI.TextureCache[uuid].trim = new Phaser.Rectangle(frames[key].spriteSourceSize.x, frames[key].spriteSourceSize.y, frames[key].sourceSize.w, frames[key].sourceSize.h);
240201
}
241202

242203
i++;
@@ -306,19 +267,10 @@ Phaser.AnimationParser = {
306267

307268
newFrame = data.addFrame(new Phaser.Frame(i, x, y, width, height, name, uuid));
308269

309-
PIXI.TextureCache[uuid] = new PIXI.Texture(PIXI.BaseTextureCache[cacheKey], {
310-
x: x,
311-
y: y,
312-
width: width,
313-
height: height
314-
});
315-
316270
// Trimmed?
317271
if (frameX !== null || frameY !== null)
318272
{
319273
newFrame.setTrim(true, width, height, frameX, frameY, frameWidth, frameHeight);
320-
321-
PIXI.TextureCache[uuid].trim = new Phaser.Rectangle(frameX, frameY, width, height);
322274
}
323275
}
324276

src/animation/Frame.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ Phaser.Frame.prototype = {
143143

144144
if (trimmed)
145145
{
146-
// this.width = actualWidth;
147-
// this.height = actualHeight;
148146
this.sourceSizeW = actualWidth;
149147
this.sourceSizeH = actualHeight;
150148
this.centerX = Math.floor(actualWidth / 2);

0 commit comments

Comments
 (0)