package assetstore import ( "fmt" "log" "path/filepath" "strings" "github.com/hajimehoshi/ebiten" "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 ID string XOffset int YOffset int Width int Height int Image *ebiten.Image } func (a *AssetStore) Object(name string) (*Object, error) { name = canonical(name) if obj, ok := a.objs[name]; ok { return obj, nil } log.Printf("Loading object %v", name) filename, err := a.lookup(name, "obj", "Obj") 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 } func (o *Object) Sprite(idx int) (*Sprite, error) { if sprite := o.sprites[idx]; sprite != nil { return sprite, nil } log.Printf("Loading sprite %v:%v", o.raw.Name, idx) if o.raw.Sprites[idx] == nil { if err := o.raw.LoadSprite(idx); err != nil { return nil, err } } raw := o.raw.Sprites[idx] img, err := ebiten.NewImageFromImage(raw.ToImage(), ebiten.FilterDefault) if err != nil { return nil, err } sprite := &Sprite{ ID: fmt.Sprintf("%v:%v", o.raw.Name, idx), obj: o, Width: int(raw.Width), Height: int(raw.Width), XOffset: int(raw.XOffset), YOffset: int(raw.YOffset), Image: img, } o.sprites[idx] = sprite return sprite, nil }