Files
ordoor/internal/assetstore/object.go

144 lines
2.5 KiB
Go
Raw Normal View History

package assetstore
import (
2020-03-21 10:59:07 +00:00
"fmt"
2020-03-21 18:50:26 +00:00
"image"
2020-03-20 00:02:27 +00:00
"log"
"path/filepath"
"strings"
2020-03-20 00:02:27 +00:00
2020-11-21 19:27:09 +00:00
"github.com/hajimehoshi/ebiten/v2"
"code.ur.gs/lupine/ordoor/internal/data"
)
type Object struct {
assets *AssetStore
sprites []*Sprite
raw *data.Object
NumSprites int
Name string
}
type Sprite struct {
obj *Object
2020-03-21 18:50:26 +00:00
XOffset int // TODO: replace these everywhere with Rect
YOffset int
Width int
Height int
2020-03-21 18:50:26 +00:00
ID string
Rect image.Rectangle
Image *ebiten.Image
}
func (a *AssetStore) Object(name string) (*Object, error) {
name = canonical(name)
if obj, ok := a.objs[name]; ok {
return obj, nil
}
2020-03-20 00:02:27 +00:00
log.Printf("Loading object %v", name)
filename, err := a.lookup(name, "obj", "Obj", "spr")
if err != nil {
return nil, err
}
obj, err := a.ObjectByPath(filename)
if err != nil {
return nil, err
}
a.objs[name] = obj
return obj, nil
}
// FIXME: Objects loaded by path are not cached
func (a *AssetStore) ObjectByPath(path string) (*Object, error) {
name := filepath.Base(path)
name = strings.Replace(name, filepath.Ext(name), "", -1)
name = canonical(name)
raw, err := data.LoadObjectLazily(path)
if err != nil {
return nil, err
}
obj := &Object{
assets: a,
sprites: make([]*Sprite, int(raw.NumSprites)),
raw: raw,
NumSprites: int(raw.NumSprites),
Name: canonical(name),
}
return obj, nil
}
// Loads all sprites in the object eagerly
func (o *Object) LoadSprites() error {
for i := 0; i < o.NumSprites; i++ {
if _, err := o.Sprite(i); err != nil {
return err
}
}
return nil
}
2020-04-16 15:30:47 +01:00
func (o *Object) Sprites(start, count int) ([]*Sprite, error) {
out := make([]*Sprite, count)
for i := start; i < start+count; i++ {
sprite, err := o.Sprite(i)
if err != nil {
return nil, err
}
out[i-start] = sprite
}
return out, nil
}
func (o *Object) Sprite(idx int) (*Sprite, error) {
if sprite := o.sprites[idx]; sprite != nil {
return sprite, nil
}
if o.raw.Sprites[idx] == nil {
if err := o.raw.LoadSprite(idx); err != nil {
return nil, err
}
}
raw := o.raw.Sprites[idx]
2020-11-21 19:27:09 +00:00
img := ebiten.NewImageFromImage(raw.ToImage(o.assets.Palette))
2020-03-21 18:50:26 +00:00
rect := image.Rect(
int(raw.XOffset),
int(raw.YOffset),
int(raw.XOffset+raw.Width),
int(raw.YOffset+raw.Height),
)
sprite := &Sprite{
2020-03-21 10:59:07 +00:00
ID: fmt.Sprintf("%v:%v", o.raw.Name, idx),
obj: o,
2020-03-21 18:50:26 +00:00
Width: rect.Dx(),
Height: rect.Dy(),
XOffset: rect.Min.X,
YOffset: rect.Min.Y,
Rect: rect,
Image: img,
}
o.sprites[idx] = sprite
return sprite, nil
}