package gfx import ( "image" "io/fs" "os" "path/filepath" "github.com/chompy/roguelike_rpg/internal/util" "github.com/hajimehoshi/ebiten/v2" ) type SpriteDef struct { Path string `yaml:"path"` TileSize [2]int `yaml:"size"` Frames []int `yaml:"frames"` FPS int `yaml:"fps"` Loop bool `yaml:"loop"` Effects []string `yaml:"effects"` } type SpriteLibrary map[string]*Sprite func LoadSpriteLibrary(assetFS fs.FS) (SpriteLibrary, error) { // load sprites.yaml spriteLibraryConf := make(map[string]SpriteDef) if err := util.ReadYAML(assetFS, filepath.Join("gfx", "sprites.yaml"), &spriteLibraryConf); err != nil { return nil, err } // preload all sprite images and visual effects spriteImages := make(map[string]image.Image) effects := make(map[string]Effect) for _, spriteDef := range spriteLibraryConf { if spriteImages[spriteDef.Path] == nil && spriteDef.Path != "" { spriteImage, err := LoadImage(assetFS, spriteDef.Path) if err != nil { return nil, err } spriteImages[spriteDef.Path] = spriteImage } for _, effectName := range spriteDef.Effects { if effects[effectName] == nil { luaEffect, err := LoadLuaEffect(assetFS, effectName) if err != nil && !os.IsNotExist(err) { return nil, err } if err == nil { effects[effectName] = luaEffect continue } shaderEffect, err := LoadShaderEffect(assetFS, effectName) if err != nil && !os.IsNotExist(err) { return nil, err } if err == nil { effects[effectName] = shaderEffect continue } } } } // load sprites in to library spriteLibrary := make(SpriteLibrary, 0) for name, spriteDef := range spriteLibraryConf { if spriteImages[spriteDef.Path] != nil { spriteLibrary[name] = &Sprite{ image: ebiten.NewImageFromImage(spriteImages[spriteDef.Path]), tileSize: spriteDef.TileSize, animationFrames: spriteDef.Frames, animationFPS: spriteDef.FPS, loop: spriteDef.Loop, effects: make([]Effect, 0), } for _, effectName := range spriteDef.Effects { if effects[effectName] != nil { spriteLibrary[name].effects = append(spriteLibrary[name].effects, effects[effectName]) } } } } return spriteLibrary, nil } func (l SpriteLibrary) Get(names ...string) ([]*Sprite, error) { out := make([]*Sprite, 0) for _, name := range names { if l[name] != nil { out = append(out, l[name]) } } if len(out) == 0 { return out, ErrSpriteNotDefined } return out, nil } func (l SpriteLibrary) GetOne(name string) (*Sprite, error) { if l[name] != nil { return l[name], nil } return nil, ErrSpriteNotDefined } func (l SpriteLibrary) GetFirst(names ...string) (*Sprite, error) { sprites, err := l.Get(names...) if err != nil { return nil, err } return sprites[0], nil }