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.Filter3[Position, Animation, Timer] Cellsize int } func NewAnimationSystem(world *ecs.World, cellsize int) System { system := &AnimationSystem{ Selector: generic.NewFilter3[Position, Animation, Timer](), World: world, Cellsize: cellsize, } return system } func (system *AnimationSystem) Update() error { // display debris after collecting EntitiesToRemove := []ecs.Entity{} query := system.Selector.Query(system.World) for query.Next() { // we loop, but it's only one anyway _, animation, timer := query.Get() animation.Show = true if timer.IsReady() { switch { // animation shows from earlier tick, animate case animation.Index > -1 && animation.Index < len(animation.Tiles)-1: animation.Index++ timer.Start(config.ANIMATION_LOOPWAIT) default: // last sprite reached, remove it EntitiesToRemove = append(EntitiesToRemove, query.Entity()) } } else { 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, animation, _ := query.Get() if animation.Show { op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(animation.Tiles[animation.Index], op) } } }