ImageRef implements Loader

This commit is contained in:
Josh Deprez 2021-08-20 17:05:47 +10:00
parent af89c01dbd
commit 245d939f2c
4 changed files with 33 additions and 12 deletions

View file

@ -20,7 +20,8 @@ var (
imageCache = make(map[string]*ebiten.Image)
// Ensure SceneRef does the same stuff as Scene.
// Ensure ref types satisfy interfaces.
_ Loader = &ImageRef{}
_ Scener = &SceneRef{}
)
@ -52,36 +53,43 @@ func (r *AnimRef) Anim() *Anim {
// ImageRef loads images from the AssetFS into *ebiten.Image form.
// It is your responsibility to import _ "image/..." for whatever
// format the files are in.
// format the files are in, and to load it (either return it as a
// subcomponent from Scan so that Game will Load it, or call Load
// yourself).
type ImageRef struct {
Path string
image *ebiten.Image
}
// Image returns the image. If it hasn't been loaded yet, it loads.
// Image returns the image, or nil if not loaded.
// Multiple distinct ImageRefs can use the same path.
// TODO: adopt Loader?
func (r *ImageRef) Image() *ebiten.Image {
if r.image != nil {
return r.image
}
// Load loads the image. Load is required before Image returns.
// Loading the same path multiple times uses a cache to return
// the same image.
func (r *ImageRef) Load() error {
// Fast path load from cache
r.image = imageCache[r.Path]
if r.image != nil {
return r.image
return nil
}
// Slow path
f, err := AssetFS.Open(r.Path)
if err != nil {
log.Fatalf("Couldn't open asset: %v", err)
return err
}
defer f.Close()
i, _, err := image.Decode(f)
if err != nil {
log.Fatalf("Couldn't decode asset: %v", err)
return err
}
r.image = ebiten.NewImageFromImage(i)
imageCache[r.Path] = r.image
return r.image
return nil
}
// SceneRef loads a gzipped, gob-encoded Scene from the asset FS.

View file

@ -13,6 +13,7 @@ var (
_ Drawer = &Image{}
_ DrawOrderer = &Image{}
_ ParallaxScaler = &Image{}
_ Scanner = &Image{}
)
func init() {
@ -36,3 +37,6 @@ func (i *Image) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
opts.GeoM = geom
screen.DrawImage(i.Src.Image(), &opts)
}
// Scan returns a slice containing Src.
func (i *Image) Scan() []interface{} { return []interface{}{&i.Src} }

View file

@ -51,7 +51,12 @@ func (s *Sprite) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
screen.DrawImage(src.SubImage(image.Rectangle{sp, sp.Add(s.FrameSize)}).(*ebiten.Image), &opts)
}
func (s *Sprite) Scan() []interface{} { return []interface{}{&s.Actor} }
func (s *Sprite) Scan() []interface{} {
return []interface{}{
&s.Actor,
&s.Src,
}
}
func (s *Sprite) SetAnim(a *Anim) {
if s.anim != a {

View file

@ -13,6 +13,7 @@ var (
_ Collider = &Tilemap{}
_ Drawer = &Tilemap{}
_ DrawOrderer = &Tilemap{}
_ Scanner = &Tilemap{}
_ Updater = &Tilemap{}
)
@ -86,6 +87,9 @@ func (t *Tilemap) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
}
}
// Scan returns a slice containing Src.
func (t *Tilemap) Scan() []interface{} { return []interface{}{&t.Src} }
// Update calls Update on any tiles that are Updaters, e.g. AnimatedTile.
func (t *Tilemap) Update() error {
if t.Disabled {