package systems import ( "image" . "openquell/components" "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.Filter2[Position, Particle] Cellsize int } func NewParticleSystem(world *ecs.World, cellsize int) *ParticleSystem { system := &ParticleSystem{ Selector: generic.NewFilter2[Position, Particle](), World: world, Cellsize: cellsize, } return system } func (system *ParticleSystem) Update(detonate bool, position *image.Point) { // display debris after collecting query := system.Selector.Query(system.World) for query.Next() { // we loop, but it's only one anyway ptposition, particle := query.Get() if detonate { // particle appears ptposition.Update( position.X-(system.Cellsize/2), position.Y-(system.Cellsize/2), 64, ) particle.Index = 0 // start displaying the particle } else { switch { // particle shows from earlier tick, animate case particle.Index > -1 && particle.Index < len(particle.Particles)-1: particle.Index++ default: // last sprite reached, remove it particle.Index = -1 } } } } 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.Index > -1 { op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(particle.Particles[particle.Index], op) } } }