Last active
September 30, 2015 18:59
-
-
Save lardratboy/7f23603d9047c2308ae2 to your computer and use it in GitHub Desktop.
Phaser Scale9 sprite supports tiled or basic scaling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Author Brad P. Taylor ([email protected]) license MIT | |
///<reference path="../../../../bower_components/phaser-official/build/phaser.d.ts"/> | |
///<reference path="./prefab.ts"/> | |
// TODO - support PIXI.Texture/BaseTexture/Atlas (if texture then use inner texture) | |
// TODO - error checking ? possibly correct bad snap requests (not multiple) | |
module bpt { | |
export class Scale9 extends Phaser.Group { | |
anchor:Phaser.Point = new Phaser.Point(0,0); | |
private rectangles:Phaser.Rectangle[] = []; | |
private textures:PIXI.Texture [] = []; | |
private baseTexture:PIXI.BaseTexture; | |
private row_sizes:number[] = []; | |
private col_sizes:number[] = []; | |
private displayObjects:any[] = []; | |
private pendingResize = false; | |
private virtualHeight_ = 0; | |
private virtualWidth_ = 0; | |
private minHeight = 0; | |
private minWidth = 0; | |
private tiled:boolean; | |
private xsnap = 1; | |
private ysnap = 1; | |
constructor( game, key, tiled?, xsnap?, ysnap?, sx?, sy?, sw?, sh?, width?, height?, x = 0, y = 0 ) { | |
super( game ); | |
this.init( key, tiled, xsnap, ysnap, sx, sy, sw, sh, width, height, x, y ); | |
} | |
private cleanup(removeChildren:boolean = true) { | |
for ( var i = this.textures.length; 0 <= --i; ) { | |
if ( removeChildren ) { | |
this.removeChild( this.displayObjects[i] ); | |
} | |
delete this.displayObjects[i]; | |
delete this.textures[i]; | |
delete this.rectangles[i]; | |
} | |
this.displayObjects.length = 0; | |
this.textures.length = 0; | |
this.rectangles.length = 0; | |
this.row_sizes.length = 0; | |
this.col_sizes.length = 0; | |
this.pendingResize = false; | |
this.virtualHeight_ = 0; | |
this.virtualWidth_ = 0; | |
this.minHeight = 0; | |
this.minWidth = 0; | |
this.xsnap = 0; | |
this.ysnap = 0; | |
delete this.baseTexture; | |
} | |
destroy( destroyChildren:boolean = true ) { | |
this.cleanup( false ); | |
super.destroy( destroyChildren ); | |
} | |
private init( key, tiled = false, xsnap?, ysnap?, sx?, sy?, sw?, sh?, width?, height?, x?, y? ) { | |
this.cleanup( true ); | |
if ( typeof xsnap === 'undefined' ) xsnap = 1; | |
if ( typeof ysnap === 'undefined' ) ysnap = 1; | |
this.xsnap = Math.max( 1, xsnap ); | |
this.ysnap = Math.max( 1, ysnap ); | |
if ( typeof x !== 'undefined' ) this.x = x; | |
if ( typeof y !== 'undefined' ) this.y = y; | |
var source:any = this.game.cache.getImage( key ) || this.game.cache.getCanvas( key ); | |
this.baseTexture = new PIXI.BaseTexture( source, undefined ); | |
this.tiled = tiled; | |
var w = this.baseTexture.width|0, | |
h = this.baseTexture.height|0, | |
ew = (w/3)|0, | |
eh = (h/3)|0; | |
sx = ('undefined' === typeof sx) ? ew : sx; | |
sy = ('undefined' === typeof sy) ? eh : sy; | |
sw = ('undefined' === typeof sw) ? w - Math.min(ew,sx)*2 : sw; | |
sh = ('undefined' === typeof sh) ? h - Math.min(eh,sy)*2 : sh; | |
if ( console && console.log && (this.tiled && (sw <= 64) && (sh <= 64)) ) | |
console.log( "WARNING", "you may get WebGL errors about this texture size...", sw, sh ) | |
var xs = [ 0, sx, sx + sw, w ]; | |
var ys = [ 0, sy, sy + sh, h ]; | |
for ( var row = 0; row < 3; ++row ) { | |
var top = ys[row], | |
bottom = ys[row+1], | |
rh = bottom - top; | |
this.row_sizes[row] = rh; | |
for ( var col = 0; col < 3; ++col ) { | |
var left = xs[col], | |
right = xs[col+1], | |
cw = right - left; | |
if ( 0 == row ) this.col_sizes[col] = cw; | |
var rect:any = new Phaser.Rectangle( left, top, cw, rh ); | |
this.rectangles.push( rect ); | |
var texture = new PIXI.Texture( this.baseTexture, rect ); | |
this.textures.push( texture ); | |
var displayObject:any = ( this.tiled ) | |
? new Phaser.TileSprite( this.game, left, top, cw, rh, texture) | |
: new Phaser.Image( this.game, left, top, texture, undefined ); | |
this.displayObjects.push( displayObject ); | |
this.addChild( displayObject ); | |
} | |
} | |
this.minHeight = this.col_sizes[0] + this.col_sizes[2] + this.xsnap; | |
this.minWidth = this.row_sizes[0] + this.row_sizes[2] + this.ysnap; | |
this.setVirtualSize( width || w, height || h ); | |
} | |
preUpdate() { | |
if ( !this.pendingResize ) return; | |
this.pendingResize = false; | |
var overlapFudgeFactorX = 0.333333/Math.abs(this.scale.x), | |
overlapFudgeFactorY = 0.333333/Math.abs(this.scale.y), | |
l = this.col_sizes[0], | |
r = this.col_sizes[2], | |
t = this.row_sizes[0], | |
b = this.row_sizes[2]; | |
var widths = [ l, Math.max(this.xsnap,overlapFudgeFactorX+this.virtualWidth_-(l+r)), r ], | |
heights = [ t, Math.max(this.ysnap,overlapFudgeFactorY+this.virtualHeight_-(t+b)), b ]; | |
var width = widths[0] + widths[1] + widths[2]; | |
var height = heights[0] + heights[1] + heights[2]; | |
var xorigin = -width*this.anchor.x, | |
yorigin = -height*this.anchor.y; | |
var idx = 0, | |
y = yorigin; | |
for ( var row = 0; row < 3; ++row ) { | |
var h = heights[row], | |
x = xorigin; | |
for ( var col = 0; col < 3; ++col ) { | |
this.displayObjects[ idx ].x = x; | |
this.displayObjects[ idx ].y = y; | |
var w = widths[col]; | |
if ( this.tiled ) { | |
this.displayObjects[ idx ].width = w; | |
this.displayObjects[ idx ].height = h; | |
} else { | |
this.displayObjects[ idx ].scale.set( | |
w / this.col_sizes[ col ], | |
h / this.row_sizes[ row ] ); | |
} | |
x += (w - overlapFudgeFactorX); | |
++idx; | |
} | |
y += (h - overlapFudgeFactorY); | |
} | |
} | |
private snap( value, overhead, snap ) { | |
if ( 1 >= snap ) return value; | |
var fixed = (overhead[0] + overhead[2]); | |
return fixed + Math.round( (value - fixed) / snap ) * snap; | |
} | |
get virtualHeight() { return this.virtualHeight_; } | |
set virtualHeight( h ) { | |
h = this.snap(h,this.row_sizes,this.ysnap); | |
if ( h < this.minHeight ) h = this.minHeight; | |
this.pendingResize = this.pendingResize || (h != this.virtualHeight_); | |
if ( this.pendingResize ) this.virtualHeight_ = h; | |
} | |
get virtualWidth() { return this.virtualWidth_; } | |
set virtualWidth( w ) { | |
w = this.snap(w,this.col_sizes,this.xsnap); | |
if ( w < this.minWidth ) w = this.minWidth; | |
this.pendingResize = this.pendingResize || (w != this.virtualWidth_); | |
if ( this.pendingResize ) this.virtualWidth_ = w; | |
} | |
setVirtualSize( width, height ) { | |
this.virtualHeight = height; | |
this.virtualWidth = width; | |
} | |
} | |
if ( bpt && bpt.prefab.Factory ) { | |
bpt.prefab.Factory.add( 'bpt.scale9', Scale9, | |
[ ["key"], ["tiled"], ["xsnap"], ["ysnap"], | |
["sx"], ["sy"], ["sw"], ["sh"], | |
["width"], ["height"], ["x"], ["y"] ], | |
bpt.prefab.helper_transformed_named_args_to_config ); | |
bpt.prefab.Factory.addAlias( 'scale9', 'bpt.scale9' ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment