@@ -62,22 +62,8 @@ Phaser.Image = function (game, x, y, key, frame) {
6262 */
6363 this . key = key ;
6464
65- /**
66- * @property {number } _frame - Internal cache var.
67- * @private
68- */
69- this . _frame = 0 ;
70-
71- /**
72- * @property {string } _frameName - Internal cache var.
73- * @private
74- */
75- this . _frameName = '' ;
76-
7765 PIXI . Sprite . call ( this , PIXI . TextureCache [ '__default' ] ) ;
7866
79- this . loadTexture ( key , frame ) ;
80-
8167 this . position . set ( x , y ) ;
8268
8369 /**
@@ -100,11 +86,23 @@ Phaser.Image = function (game, x, y, key, frame) {
10086 */
10187 this . input = null ;
10288
89+ /**
90+ * @property {boolean } debug - Handy flag to use with Game.enableStep
91+ * @default
92+ */
93+ this . debug = false ;
94+
10395 /**
10496 * @property {Phaser.Point } cameraOffset - If this object is fixedToCamera then this stores the x/y offset that its drawn at, from the top-left of the camera view.
10597 */
10698 this . cameraOffset = new Phaser . Point ( ) ;
10799
100+ /**
101+ * @property {Phaser.Rectangle } cropRect - The Rectangle used to crop the texture. Set this via Sprite.crop. Any time you modify this property directly you must call Sprite.updateCrop.
102+ * @default
103+ */
104+ this . cropRect = null ;
105+
108106 /**
109107 * A small internal cache:
110108 * 0 = previous position.x
@@ -121,6 +119,26 @@ Phaser.Image = function (game, x, y, key, frame) {
121119 */
122120 this . _cache = [ 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 ] ;
123121
122+ /**
123+ * @property {Phaser.Rectangle } _crop - Internal cache var.
124+ * @private
125+ */
126+ this . _crop = null ;
127+
128+ /**
129+ * @property {Phaser.Rectangle } _frame - Internal cache var.
130+ * @private
131+ */
132+ this . _frame = null ;
133+
134+ /**
135+ * @property {Phaser.Rectangle } _bounds - Internal cache var.
136+ * @private
137+ */
138+ this . _bounds = new Phaser . Rectangle ( ) ;
139+
140+ this . loadTexture ( key , frame ) ;
141+
124142} ;
125143
126144Phaser . Image . prototype = Object . create ( PIXI . Sprite . prototype ) ;
@@ -146,8 +164,10 @@ Phaser.Image.prototype.preUpdate = function() {
146164
147165 if ( this . autoCull )
148166 {
167+ this . _bounds . copyFrom ( this . getBounds ( ) ) ;
168+
149169 // Won't get rendered but will still get its transform updated
150- this . renderable = this . game . world . camera . screenView . intersects ( this . getBounds ( ) ) ;
170+ this . renderable = this . game . world . camera . screenView . intersects ( this . _bounds ) ;
151171 }
152172
153173 this . world . setTo ( this . game . camera . x + this . worldTransform . tx , this . game . camera . y + this . worldTransform . ty ) ;
@@ -218,55 +238,118 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
218238
219239 frame = frame || 0 ;
220240
241+ this . key = key ;
242+
243+ var smoothed = this . smoothed ;
244+
221245 if ( key instanceof Phaser . RenderTexture )
222246 {
223247 this . key = key . key ;
224248 this . setTexture ( key ) ;
225- return ;
226249 }
227250 else if ( key instanceof Phaser . BitmapData )
228251 {
229- this . key = key ;
230252 this . setTexture ( key . texture ) ;
231- return ;
232253 }
233254 else if ( key instanceof PIXI . Texture )
234255 {
235- this . key = key ;
236256 this . setTexture ( key ) ;
237- return ;
238257 }
239258 else
240259 {
241260 if ( key === null || typeof key === 'undefined' )
242261 {
243262 this . key = '__default' ;
244263 this . setTexture ( PIXI . TextureCache [ this . key ] ) ;
245- return ;
246264 }
247265 else if ( typeof key === 'string' && ! this . game . cache . checkImageKey ( key ) )
248266 {
267+ console . warn ( "Texture with key '" + key + "' not found." ) ;
249268 this . key = '__missing' ;
250269 this . setTexture ( PIXI . TextureCache [ this . key ] ) ;
251- return ;
252270 }
271+ else
272+ {
273+ this . setTexture ( new PIXI . Texture ( PIXI . BaseTextureCache [ key ] ) ) ;
274+ }
275+ }
276+
277+ this . _frame = Phaser . Rectangle . clone ( this . texture . frame ) ;
278+
279+ if ( ! smoothed )
280+ {
281+ this . smoothed = false ;
282+ }
283+
284+ } ;
285+
286+ /**
287+ * Sets the Texture frame the Sprite uses for rendering.
288+ * This is primarily an internal method used by Sprite.loadTexture, although you may call it directly.
289+ *
290+ * @method Phaser.Sprite#setFrame
291+ * @memberof Phaser.Sprite
292+ * @param {Phaser.Frame } frame - The Frame to be used by the Sprite texture.
293+ */
294+ Phaser . Image . prototype . setFrame = function ( frame ) {
295+
296+ this . _frame = frame ;
253297
254- this . key = key ;
298+ this . texture . frame . x = frame . x ;
299+ this . texture . frame . y = frame . y ;
300+ this . texture . frame . width = frame . width ;
301+ this . texture . frame . height = frame . height ;
255302
256- var frameData = this . game . cache . getFrameData ( key ) ;
303+ this . texture . crop . x = frame . x ;
304+ this . texture . crop . y = frame . y ;
305+ this . texture . crop . width = frame . width ;
306+ this . texture . crop . height = frame . height ;
257307
258- if ( typeof frame === 'string' )
308+ if ( frame . trimmed )
309+ {
310+ if ( this . texture . trim )
259311 {
260- this . _frame = 0 ;
261- this . _frameName = frame ;
262- this . setTexture ( PIXI . TextureCache [ frameData . getFrameByName ( frame ) . uuid ] ) ;
312+ this . texture . trim . x = frame . spriteSourceSizeX ;
313+ this . texture . trim . y = frame . spriteSourceSizeY ;
314+ this . texture . trim . width = frame . sourceSizeW ;
315+ this . texture . trim . height = frame . sourceSizeH ;
263316 }
264317 else
265318 {
266- this . _frame = frame ;
267- this . _frameName = '' ;
268- this . setTexture ( PIXI . TextureCache [ frameData . getFrame ( frame ) . uuid ] ) ;
319+ this . texture . trim = { x : frame . spriteSourceSizeX , y : frame . spriteSourceSizeY , width : frame . sourceSizeW , height : frame . sourceSizeH } ;
269320 }
321+
322+ this . texture . width = frame . sourceSizeW ;
323+ this . texture . height = frame . sourceSizeH ;
324+ this . texture . frame . width = frame . sourceSizeW ;
325+ this . texture . frame . height = frame . sourceSizeH ;
326+ }
327+
328+ if ( this . cropRect )
329+ {
330+ this . updateCrop ( ) ;
331+ }
332+ else
333+ {
334+ if ( this . game . renderType === Phaser . WEBGL )
335+ {
336+ PIXI . WebGLRenderer . updateTextureFrame ( this . texture ) ;
337+ }
338+ }
339+
340+ } ;
341+
342+ /**
343+ * Resets the Texture frame dimensions that the Sprite uses for rendering.
344+ *
345+ * @method Phaser.Sprite#resetFrame
346+ * @memberof Phaser.Sprite
347+ */
348+ Phaser . Image . prototype . resetFrame = function ( ) {
349+
350+ if ( this . _frame )
351+ {
352+ this . setFrame ( this . _frame ) ;
270353 }
271354
272355} ;
@@ -284,39 +367,72 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
284367*/
285368Phaser . Image . prototype . crop = function ( rect ) {
286369
287- if ( typeof rect === 'undefined' || rect === null )
370+ if ( typeof copy === 'undefined' ) { copy = false ; }
371+
372+ if ( rect )
288373 {
289- // Clear any crop that may be set
290- if ( this . texture . hasOwnProperty ( 'sourceWidth' ) )
374+ if ( copy && this . cropRect !== null )
375+ {
376+ this . cropRect . setTo ( rect . x , rect . y , rect . width , rect . height ) ;
377+ }
378+ else if ( copy && this . cropRect === null )
379+ {
380+ this . cropRect = new Phaser . Rectangle ( rect . x , rect . y , rect . width , rect . height ) ;
381+ }
382+ else
291383 {
292- this . texture . setFrame ( new Phaser . Rectangle ( 0 , 0 , this . texture . sourceWidth , this . texture . sourceHeight ) ) ;
384+ this . cropRect = rect ;
293385 }
386+
387+ this . updateCrop ( ) ;
294388 }
295389 else
296390 {
297- // Do we need to clone the PIXI.Texture object?
298- if ( this . texture instanceof PIXI . Texture )
299- {
300- // Yup, let's rock it ...
301- var local = { } ;
391+ this . _crop = null ;
392+ this . cropRect = null ;
302393
303- Phaser . Utils . extend ( true , local , this . texture ) ;
394+ this . resetFrame ( ) ;
395+ }
304396
305- local . sourceWidth = local . width ;
306- local . sourceHeight = local . height ;
307- local . frame = rect ;
308- local . width = rect . width ;
309- local . height = rect . height ;
397+ } ;
310398
311- this . texture = local ;
399+ /**
400+ * If you have set a crop rectangle on this Sprite via Sprite.crop and since modified the Sprite.cropRect property (or the rectangle it references)
401+ * then you need to update the crop frame by calling this method.
402+ *
403+ * @method Phaser.Sprite#updateCrop
404+ * @memberof Phaser.Sprite
405+ */
406+ Phaser . Image . prototype . updateCrop = function ( ) {
312407
313- this . texture . updateFrame = true ;
314- PIXI . Texture . frameUpdates . push ( this . texture ) ;
315- }
316- else
317- {
318- this . texture . setFrame ( rect ) ;
319- }
408+ if ( ! this . cropRect )
409+ {
410+ return ;
411+ }
412+
413+ this . _crop = Phaser . Rectangle . clone ( this . cropRect , this . _crop ) ;
414+ this . _crop . x += this . _frame . x ;
415+ this . _crop . y += this . _frame . y ;
416+
417+ var cx = Math . max ( this . _frame . x , this . _crop . x ) ;
418+ var cy = Math . max ( this . _frame . y , this . _crop . y ) ;
419+ var cw = Math . min ( this . _frame . right , this . _crop . right ) - cx ;
420+ var ch = Math . min ( this . _frame . bottom , this . _crop . bottom ) - cy ;
421+
422+ this . texture . crop . x = cx ;
423+ this . texture . crop . y = cy ;
424+ this . texture . crop . width = cw ;
425+ this . texture . crop . height = ch ;
426+
427+ this . texture . frame . width = Math . min ( cw , this . cropRect . width ) ;
428+ this . texture . frame . height = Math . min ( ch , this . cropRect . height ) ;
429+
430+ this . texture . width = this . texture . frame . width ;
431+ this . texture . height = this . texture . frame . height ;
432+
433+ if ( this . game . renderType === Phaser . WEBGL )
434+ {
435+ PIXI . WebGLRenderer . updateTextureFrame ( this . texture ) ;
320436 }
321437
322438} ;
0 commit comments