Files
pobounty/characters.go

148 lines
3.1 KiB
Go

package main
import (
"bytes"
_ "embed"
"image"
_ "image/png"
"math/rand"
"github.com/hajimehoshi/ebiten/v2"
)
type CharacterType uint
const (
WhiteCharacter CharacterType = 0
PinkCharacter CharacterType = 1
BlueCharacter CharacterType = 2
GreenCharacter CharacterType = 3
BlackCharacter CharacterType = 4
OrangeCharacter CharacterType = 5
RedCharacter CharacterType = 6
)
func (c CharacterType) IsValid() bool {
result := false
switch c {
case WhiteCharacter, PinkCharacter, BlueCharacter, GreenCharacter, BlackCharacter, OrangeCharacter, RedCharacter:
result = true
}
return result
}
const (
CHARACTER_NUMTYPES = 7
CHARACTER_WIDTH = 50
CHARACTER_HEIGHT = 50
CHARACTER_ANIMATION_CYCLES = 6
CHARACTER_WINIMATION_CYCLES = 8
)
var (
//go:embed resources/images/idle.png
assets_png []byte
assetsImage *ebiten.Image
//go:embed resources/images/win.png
winnerAssets_png []byte
assetsWinner *ebiten.Image
)
type CharacterPosition struct {
X float64
Y float64
}
type Character struct {
Sprite *ebiten.Image //our principle sprite representing the character
chartype CharacterType //character type, determines offset position to use from asset image
cycle int //current animation cycle for the character
targetcycles int //specified animation cycle
pos CharacterPosition //character coordinates
}
func (c *Character) RandomizeCycleStart() {
c.cycle = rand.Int() % c.targetcycles
}
func NewCharacter(t CharacterType) *Character {
c := &Character{
Sprite: ebiten.NewImage(CHARACTER_WIDTH, CHARACTER_HEIGHT),
pos: CharacterPosition{X: 0, Y: 0},
targetcycles: CHARACTER_ANIMATION_CYCLES,
}
if t.IsValid() {
c.chartype = t
} else {
c.chartype = WhiteCharacter
}
return c
}
func (c *Character) SetTargetCycles(cycles int) {
c.targetcycles = cycles
}
func (c *Character) CycleUpdate() {
c.cycle = (c.cycle + 1) % c.targetcycles
}
func (c *Character) Animate() {
c.AnimateFromTarget(assetsImage)
}
func (c *Character) AnimateWinner() {
c.AnimateFromTarget(assetsWinner)
}
func (c *Character) AnimateFromTarget(source *ebiten.Image) {
//compute start and end location of asset to use for animation frame cycle
sx := CHARACTER_WIDTH * c.cycle
sy := CHARACTER_HEIGHT * int(c.chartype)
ex := CHARACTER_WIDTH * (c.cycle + 1)
ey := CHARACTER_HEIGHT * (int(c.chartype) + 1)
c.Sprite.Clear()
c.Sprite.DrawImage(source.SubImage(image.Rect(sx, sy, ex, ey)).(*ebiten.Image), nil)
c.CycleUpdate()
}
func (c *Character) SetPosition(p CharacterPosition) {
c.pos = p
}
func (c *Character) Position() CharacterPosition {
return c.pos
}
func (c *Character) GetWidth() int {
return c.Sprite.Bounds().Dx()
}
func (c *Character) GetHeight() int {
return c.Sprite.Bounds().Dy()
}
func (c *Character) GetType() CharacterType {
return c.chartype
}
func init() {
img, _, err := image.Decode(bytes.NewReader(assets_png))
if err != nil {
DashLogger.Fatal(err)
}
assetsImage = ebiten.NewImageFromImage(img)
img, _, err = image.Decode(bytes.NewReader(winnerAssets_png))
if err != nil {
DashLogger.Fatal(err)
}
assetsWinner = ebiten.NewImageFromImage(img)
}