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 ParticleSystem struct { World *ecs.World Selector *generic.Filter3[Position, Particle, Timer] Cellsize int } func NewParticleSystem(world *ecs.World, cellsize int) *ParticleSystem { system := &ParticleSystem{ Selector: generic.NewFilter3[Position, Particle, Timer](), World: world, Cellsize: cellsize, } return system } func (system *ParticleSystem) Update() { // display debris after collecting EntitiesToRemove := []ecs.Entity{} query := system.Selector.Query(system.World) for query.Next() { // we loop, but it's only one anyway _, particle, timer := query.Get() particle.Show = true if timer.IsReady() { switch { // particle shows from earlier tick, animate case particle.Index > -1 && particle.Index < len(particle.Tiles)-1: particle.Index++ timer.Start(config.PARTICLE_LOOPWAIT) default: // last sprite reached, remove it EntitiesToRemove = append(EntitiesToRemove, query.Entity()) } } else { timer.Update() } } for _, entity := range EntitiesToRemove { system.World.RemoveEntity(entity) } } func (system *ParticleSystem) Draw(screen *ebiten.Image) { // write particles (these are no tiles!) op := &ebiten.DrawImageOptions{} query := system.Selector.Query(system.World) for query.Next() { pos, particle, _ := query.Get() if particle.Show { op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(particle.Tiles[particle.Index], op) } } }