88 lines
2.0 KiB
Go
88 lines
2.0 KiB
Go
package pncdsl
|
|
|
|
import (
|
|
"hash/fnv"
|
|
"image"
|
|
"image/color"
|
|
_ "image/jpeg"
|
|
_ "image/png"
|
|
"os"
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
)
|
|
|
|
type AssetManager = Manager[Asset]
|
|
|
|
// loadedAssets is the runtime cache for decoded image/audio resources.
|
|
// The Asset structs in the manager remain immutable spec; this is where
|
|
// the actual *ebiten.Image bytes live, lazily decoded on first access.
|
|
type loadedAssets struct {
|
|
images map[string]*ebiten.Image
|
|
placeholders map[string]bool
|
|
defaultW, defaultH int
|
|
}
|
|
|
|
func newLoadedAssets(w, h int) *loadedAssets {
|
|
return &loadedAssets{
|
|
images: make(map[string]*ebiten.Image),
|
|
placeholders: make(map[string]bool),
|
|
defaultW: w,
|
|
defaultH: h,
|
|
}
|
|
}
|
|
|
|
func (la *loadedAssets) image(am *AssetManager, name string) *ebiten.Image {
|
|
if img, ok := la.images[name]; ok {
|
|
return img
|
|
}
|
|
a, ok := am.Get(name)
|
|
if !ok {
|
|
img := placeholderImage(name, la.defaultW, la.defaultH)
|
|
la.images[name] = img
|
|
la.placeholders[name] = true
|
|
return img
|
|
}
|
|
img := loadImageFile(a.Path)
|
|
if img == nil {
|
|
img = placeholderImage(name, la.defaultW, la.defaultH)
|
|
la.placeholders[name] = true
|
|
}
|
|
la.images[name] = img
|
|
return img
|
|
}
|
|
|
|
func (la *loadedAssets) isPlaceholder(name string) bool {
|
|
_, _ = la.images[name], la.placeholders[name] // ensure populated via image()
|
|
return la.placeholders[name]
|
|
}
|
|
|
|
func loadImageFile(path string) *ebiten.Image {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer f.Close()
|
|
src, _, err := image.Decode(f)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return ebiten.NewImageFromImage(src)
|
|
}
|
|
|
|
// placeholderImage creates a deterministic colored rectangle for missing
|
|
// assets so the game still runs without art on disk.
|
|
func placeholderImage(seed string, w, h int) *ebiten.Image {
|
|
img := ebiten.NewImage(w, h)
|
|
h32 := fnv.New32a()
|
|
_, _ = h32.Write([]byte(seed))
|
|
sum := h32.Sum32()
|
|
c := color.RGBA{
|
|
R: 60 + uint8(sum&0x7F),
|
|
G: 60 + uint8((sum>>8)&0x7F),
|
|
B: 60 + uint8((sum>>16)&0x7F),
|
|
A: 255,
|
|
}
|
|
img.Fill(c)
|
|
return img
|
|
}
|