Skip to content

Instantly share code, notes, and snippets.

@yi
Forked from lardratboy/bpt.scale9.ts
Created September 30, 2015 18:59
Show Gist options
  • Save yi/18f4b853add84a5f8042 to your computer and use it in GitHub Desktop.
Save yi/18f4b853add84a5f8042 to your computer and use it in GitHub Desktop.
Phaser Scale9 sprite supports tiled or basic scaling
// 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