package systems import ( . "openquell/components" "github.com/hajimehoshi/ebiten/v2" "github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/generic" ) type GridSystem struct { World *ecs.World Selector *generic.Filter3[Renderable, Position, Solid] UseCache bool Cache *ebiten.Image Count int // register tile count, invalidates cache Background *ebiten.Image Width, Height, Tilesize int } func NewGridSystem(world *ecs.World, width, height, tilesize int, background *ebiten.Image) System { cache := ebiten.NewImage(width, height) system := &GridSystem{ Selector: generic.NewFilter3[Renderable, Position, Solid](), UseCache: false, Cache: cache, Width: width, Height: height, Tilesize: tilesize, Background: background, World: world, } return system } func (system *GridSystem) Update() error { return nil } func (system *GridSystem) Draw(screen *ebiten.Image) { op := &ebiten.DrawImageOptions{} query := system.Selector.Query(system.World) if !system.UseCache || query.Count() != system.Count { // map not cached or cacheable, write it to the cache system.Cache.DrawImage(system.Background, op) system.Count = query.Count() counter := 0 for query.Next() { sprite, pos, _ := query.Get() counter++ op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y)) system.Cache.DrawImage(sprite.Image, op) } op.GeoM.Reset() screen.DrawImage(system.Cache, op) system.UseCache = true } else { // use the cached map op.GeoM.Reset() screen.DrawImage(system.Cache, op) query.Close() } }