package systems import ( . "openquell/components" "openquell/config" "github.com/hajimehoshi/ebiten/v2" "github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/generic" ) type AnimationSystem struct { World *ecs.World Selector *generic.Filter2[Position, Renderable] Cellsize int } func NewAnimationSystem(world *ecs.World, cellsize int) System { system := &AnimationSystem{ Selector: generic.NewFilter2[Position, Renderable](), World: world, Cellsize: cellsize, } return system } func (system *AnimationSystem) Update() error { EntitiesToRemove := []ecs.Entity{} query := system.Selector.Query(system.World) for query.Next() { _, render := query.Get() if render.Animate.Active { if render.Animate.Timer.IsReady() { switch { // animation shows from earlier tick, animate case render.Animate.Index > -1 && render.Animate.Index < len(render.Animate.Tiles)-1: render.Animate.Index += 1 render.Animate.Timer.Start(config.ANIMATION_LOOPWAIT) default: // last sprite reached if render.Animate.Loop { render.Animate.Index = 0 } else { EntitiesToRemove = append(EntitiesToRemove, query.Entity()) } } } else { render.Animate.Timer.Update() } } } for _, entity := range EntitiesToRemove { system.World.RemoveEntity(entity) } return nil } func (system *AnimationSystem) Draw(screen *ebiten.Image) { // write animations (these are no tiles!) op := &ebiten.DrawImageOptions{} query := system.Selector.Query(system.World) for query.Next() { pos, render := query.Get() if render.Animate.Active { op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(render.Animate.Tiles[render.Animate.Index], op) } } }