Jump to content

Sprite Crop


Recommended Posts

I'm trying to dynamically crop an image many times. Imagine many jigsaw pieces made from a single source image.


Initially I reached for Sprite.crop but it seems that all sprites using the same image will render with the same cropping rather than unique cropping. It seems to end up being a property of the image rather than the sprite.


I tried changing the Sprite.textureRegion without effect.


I thought I could dynamically create a texture atlas to represent the different pieces... but I'm not sure how.


To be clear I need this to be dynamic so the user can select the complexity of the jigsaw and I can build the pieces at run time.


Link to comment
Share on other sites

Ok I finally figured it out but it's not nice.


Basically I followed the "local json object.js" example to load in a texture with enough frames to cope with the maximum number of jigsaw pieces I might need. At this stage it doesn't matter what the position or size of each frame is because it's just a buffer. Then just before I create my sprites for each jigsaw piece I pick the next available frame from Phaser's framedata and fiddle the x/y/width/height as well as Pixi's texture cache (using Phaser's framedata.uuid).


Nasty but it works. If anyone wants code just let me know.


BTW thanks for the awesome engine!

Link to comment
Share on other sites

Ok here goes. At load time I load the texture with many blank frames like this...

var BaseName = "Test";var MaxNumFrames = 100;var ImageFileName = "assets/Images/Test.png"var NewJSON = {};NewJSON.frames = [];for( var i = 0;i < MaxNumFrames;i += 1 ){    var NewObject = {        filename : BaseName + i,        frame : {x:0,y:0,w:1,h:1},        rotated: false,        trimmed: true,        spriteSourceSize: {x:0,y:0,w:1,h:1},        sourceSize: {w:1,h:1}    }    NewJSON.frames.push(NewObject);}Game.Phaser.load.atlas(BaseName, ImageFileName, null, NewJSON);

Next I add a new function to the Phaser.cache like this...

changeFrame = function (Texture, key, x, y, Width, Height) {    var Frames = this._images[Texture].frameData._frames;    for( var i = 0;i < Frames.length;i += 1 )    {        if( Frames[i].name === key )        {            break;        }    }    var Index = i;    var Data = this._images[Texture].frameData._frames[Index];    Data.x = x;    Data.y = y;    Data.centerX = Width / 2;    Data.centerY = Height / 2;    Data.distance = Math.sqrt(Width * Width + Height * Height);    Data.width = Width;    Data.height = Height;    Data.sourceSizeW = Width;    Data.sourceSizeH = Height;    Data.spriteSourceSizeW = Width;    Data.spriteSourceSizeH = Height;        var Frame = Phaser.PIXI.TextureCache[Data.uuid];    Frame.width = Width;    Frame.height = Height;    Frame.frame.width = Width;    Frame.frame.height = Height;    Frame.frame.x = x;    Frame.frame.y = y;};Game.Phaser.cache.changeFrame = changeFrame;

Note I wasn't sure how get access to PIXI properly so I had to expose it by adding "PIXI: PIXI," to line 60 of phaser.js. Shame on me.

Finally I populate the frames each time start a new puzzle like this...

var BaseName = "Test"var NumPieces = 5;var PieceWidth = 10;var PieceHeight = 10;var NewSprites = [];for( var i = 0;i < NumPieces;i += 1 ){    var Name = BaseName + i;        // fiddle the frame    Game.Phaser.cache.changeFrame(BaseName, Name, i * PieceWidth, 0, PieceWidth, PieceHeight );        // create the sprite using the new frame    NewSprites[i] = Game.Phaser.add.sprite(i * PieceWidth, 0, BaseName, Name);} 

The result should be 5 sprites at 10x10 pixels in size.



Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...