package systems import ( "fmt" "openquell/assets" "openquell/components" . "openquell/components" "openquell/config" . "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 Selector *generic.Filter3[Position, Collectible, Renderable] } func NewCollectibleSystem(world *ecs.World) *CollectibleSystem { system := &CollectibleSystem{ Selector: generic.NewFilter3[Position, Collectible, Renderable](), World: world, } return system } func (system *CollectibleSystem) Update() { playerobserver := observers.GetPlayerObserver(system.World) posID := ecs.ComponentID[components.Position](system.World) veloID := ecs.ComponentID[components.Velocity](system.World) particlepositions := []*components.Position{} EntitiesToRemove := []ecs.Entity{} query := system.Selector.Query(system.World) numcollectibles := query.Count() if numcollectibles == 0 { query.Close() return } for query.Next() { colposition, collectible, _ := query.Get() for player := range playerobserver.Entities { playerposition := (*Position)(system.World.Get(player, posID)) playervelocity := (*Velocity)(system.World.Get(player, veloID)) ok, _ := playerposition.Intersects(colposition, playervelocity) if ok { fmt.Printf("bumped into collectible %v\n", collectible) particlepositions = append(particlepositions, colposition) EntitiesToRemove = append(EntitiesToRemove, query.Entity()) } } } for _, pos := range particlepositions { system.AddParticle(pos) } for _, entity := range EntitiesToRemove { system.World.RemoveEntity(entity) numcollectibles-- } if numcollectibles == 0 { // winner, winner, chicken dinner! timer := observers.GetGameObserver(system.World).StopTimer if !timer.Running { timer.Start(LEVEL_END_WAIT) } } } 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() op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(sprite.Image, op) } } func (system *CollectibleSystem) AddParticle(position *components.Position) { particleobserver := observers.GetParticleObserver(system.World) ptmapper := generic.NewMap3[ components.Position, components.Particle, components.Timer, ](system.World) entity := ptmapper.New() pos, particle, timer := ptmapper.Get(entity) particleobserver.AddEntity(entity) particle.Index = assets.Tiles['*'].Particle particle.Particles = assets.Tiles['*'].Particles pos.Update( position.X-(16), // FIXME: use global tilesize! position.Y-(16), 64, ) timer.Start(config.PARTICLE_LOOPWAIT) }