Name change

This commit is contained in:
2025-11-24 12:18:32 -07:00
parent cd6c1a78b0
commit 175479da69
65 changed files with 624 additions and 191 deletions

View File

@@ -1,65 +1,151 @@
package hero
import (
"fmt"
"image"
"image/color"
_ "image/gif"
_ "image/png"
"os"
"path/filepath"
"sort"
"github.com/hajimehoshi/ebiten/v2"
)
const (
heroDir = "assets/hero"
)
type animState int
const (
animIdle animState = iota
animMove
)
type animationKey struct {
direction Direction
state animState
}
var (
spriteBack1 *ebiten.Image
spriteBack2 *ebiten.Image
spriteFront1 *ebiten.Image
spriteFront2 *ebiten.Image
spriteLeft1 *ebiten.Image
spriteLeft2 *ebiten.Image
spriteRight1 *ebiten.Image
spriteRight2 *ebiten.Image
knightAnimations map[animationKey][]*ebiten.Image
)
func init() {
spriteBack1 = loadSprite("assets/hero/avt1_bk1.gif")
spriteBack2 = loadSprite("assets/hero/avt1_bk2.gif")
spriteFront1 = loadSprite("assets/hero/avt1_fr1.gif")
spriteFront2 = loadSprite("assets/hero/avt1_fr2.gif")
spriteLeft1 = loadSprite("assets/hero/avt1_lf1.gif")
spriteLeft2 = loadSprite("assets/hero/avt1_lf2.gif")
spriteRight1 = loadSprite("assets/hero/avt1_rt1.gif")
spriteRight2 = loadSprite("assets/hero/avt1_rt2.gif")
knightAnimations = make(map[animationKey][]*ebiten.Image)
if err := loadKnightAnimations(); err != nil {
panic(err)
}
}
func loadSprite(path string) *ebiten.Image {
file, err := os.Open(path)
if err != nil {
panic(err)
func getKnightSprite(direction Direction, moving bool, frameIndex int) *ebiten.Image {
state := animIdle
if moving {
state = animMove
}
defer file.Close()
return frameFromSet(direction, state, frameIndex)
}
img, _, err := image.Decode(file)
func loadKnightAnimations() error {
frames, err := loadAnimationFrames(heroDir)
if err != nil {
panic(err)
return err
}
bounds := img.Bounds()
rgba := image.NewRGBA(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, a := img.At(x, y).RGBA()
if r > 0xf000 && g > 0xf000 && b > 0xf000 {
rgba.Set(x, y, color.RGBA{0, 0, 0, 0})
} else {
rgba.Set(x, y, color.RGBA{
R: uint8(r >> 8),
G: uint8(g >> 8),
B: uint8(b >> 8),
A: uint8(a >> 8),
})
}
knightAnimations[animationKey{DirLeft, animMove}] = frames
knightAnimations[animationKey{DirLeft, animIdle}] = frames
flippedFrames := make([]*ebiten.Image, len(frames))
for i, frame := range frames {
flippedFrames[i] = flipImageHorizontally(frame)
}
knightAnimations[animationKey{DirRight, animMove}] = flippedFrames
knightAnimations[animationKey{DirRight, animIdle}] = flippedFrames
return nil
}
func loadAnimationFrames(dir string) ([]*ebiten.Image, error) {
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
var files []string
for _, entry := range entries {
if entry.IsDir() {
continue
}
name := entry.Name()
if filepath.Ext(name) == ".png" {
files = append(files, filepath.Join(dir, name))
}
}
return ebiten.NewImageFromImage(rgba)
sort.Strings(files)
var frames []*ebiten.Image
for _, file := range files {
img, err := loadImage(file)
if err != nil {
return nil, fmt.Errorf("load frame %s: %w", file, err)
}
frames = append(frames, img)
}
return frames, nil
}
func loadImage(path string) (*ebiten.Image, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return nil, err
}
return ebiten.NewImageFromImage(img), nil
}
func flipImageHorizontally(img *ebiten.Image) *ebiten.Image {
bounds := img.Bounds()
w, h := bounds.Dx(), bounds.Dy()
flipped := ebiten.NewImage(w, h)
op := &ebiten.DrawImageOptions{}
op.GeoM.Scale(-1, 1)
op.GeoM.Translate(float64(w), 0)
flipped.DrawImage(img, op)
return flipped
}
func frameFromSet(direction Direction, state animState, frameIndex int) *ebiten.Image {
if frameIndex < 0 {
frameIndex = 0
}
if frames := knightAnimations[animationKey{direction, state}]; len(frames) > 0 {
return frames[frameIndex%len(frames)]
}
if state == animMove {
if frames := knightAnimations[animationKey{direction, animIdle}]; len(frames) > 0 {
return frames[frameIndex%len(frames)]
}
} else {
if frames := knightAnimations[animationKey{direction, animMove}]; len(frames) > 0 {
return frames[frameIndex%len(frames)]
}
}
return nil
}