package systems import ( "log/slog" "openquell/components" . "openquell/components" . "openquell/config" "openquell/observers" "github.com/hajimehoshi/ebiten/v2" "github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/generic" ) type CollectibleSystem struct { World *ecs.World Cellsize int Selector *generic.Filter3[Position, Collectible, Renderable] } func NewCollectibleSystem(world *ecs.World, cellsize int) System { system := &CollectibleSystem{ Selector: generic.NewFilter3[Position, Collectible, Renderable](), World: world, Cellsize: cellsize, } return system } func (system *CollectibleSystem) Update() error { observer := observers.GetGameObserver(system.World) posID := ecs.ComponentID[components.Position](system.World) veloID := ecs.ComponentID[components.Velocity](system.World) query := system.Selector.Query(system.World) numcollectibles := query.Count() if numcollectibles == 0 || observer.Lost { slog.Debug("WON") timer := observers.GetGameObserver(system.World).StopTimer if !timer.Running { timer.Start(LEVEL_END_WAIT) } query.Close() return nil } for query.Next() { colposition, collectible, render := query.Get() for _, player := range observer.GetPlayers() { if !system.World.Alive(player) { continue } playerposition := (*Position)(system.World.Get(player, posID)) playervelocity := (*Velocity)(system.World.Get(player, veloID)) ok, _ := colposition.Intersects(playerposition, playervelocity) if ok && !collectible.Hit { slog.Debug("bumped into collectible", "colpos", colposition) render.StartAnimation(components.Destruction) // position the animation relative to the middle of the current entity colposition.Update( colposition.X-(system.Cellsize/2), colposition.Y-(system.Cellsize/2), 64, ) collectible.Hit = true numcollectibles-- } } } return nil } func (system *CollectibleSystem) Draw(screen *ebiten.Image) { // write the movable tiles op := &ebiten.DrawImageOptions{} query := system.Selector.Query(system.World) for query.Next() { pos, _, sprite := query.Get() if !sprite.Hidden { op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(sprite.Image, op) } } }