-
Notifications
You must be signed in to change notification settings - Fork 4
Texture Sprite Packer
This tool is a runtime texture packer. You can load and provide sprites to this during your games loading and it'll combine them into a single texture for more efficient drawing.
sPacker := packer.NewPacker(100, 100, 0) // creates a packer with a 100x100 internal texture
// load a sprite with Pixel
var sprite *pixel.Sprite
var err error
if sprite, err = pixelutils.LoadSprite("sprite.png"); err != nil {
log.Fatal(err) // failed to load sprite
}
// insert the sprite into the packer
spriteId := sPacker.GenerateId()
if err := sPacker.Insert(spriteId, sprite); err != nil {
// there was not enough space to insert the sprite.
log.Fatal(err)
}
- AllowGrowth: Will grow the internal texture size if the sprite can't fit; you can create the packer with w=0, h=0 and this flag if you want the starting size as small as possible.
- DebugDraw: When the packer.Draw() routine is called, draw the emptyspaces with red rectangles.
if err := sPacker.InsertV(spriteId, sprite, flags); err != nil {
log.Fatal(err)
}
- OptimizeOnInsert: Will run the packer.Optimize routine before inserting the sprite
- InsertFlipped: Will insert the sprite data upside-down into the packer's internal texture
There is a shortcut provided to give you access to the sprite's bounds at a given id.
spriteBounds := sPacker.BoundsOf(spriteId)
If you need to get the sprite back out of the packer; this will create a new sprite with a copy of the sprite data:
sprite := sPacker.SpriteFrom(spriteId)
If you need to replace a sprite with another one (can be of different size): NOTE: To allow for replacing sprites with different sizes, optimize will be run
newSprite, _ := pixelutils.LoadSprite("another-sprite.png") // for brevity, ignoring the returned err
err := sPacker.Replace(spriteId, newSprite)
This is basically a defragment operation; pull everything out of the packer's texture, sort them largest to smallest, and reinsert them. This should limit the amount of wasted space.
sPacker.Optimize()
// returns the center point of the internal texture
center := sPacker.Center()
// returns the bounds of the internal texture
bounds := sPacker.Bounds()
// returns the pixel.Picture (actually a *pixelgl.GLPicture)
picture := sPacker.Picture()
For debug purposes, I've included the ability to draw the packer's internal texture so you can see its makeup and see any issues you might have.
// this will draw the internal texture centered on the window
sPacker.Draw(win, pixel.IM.Moved(sPacker.Center()))