added hidden doors/destroyable walls, fixed game reloading (tile clone)
This commit is contained in:
parent
ab07bc23e3
commit
b0a8060d5b
8
TODO.md
8
TODO.md
@ -32,4 +32,10 @@ if inpututil.IsKeyJustPressed(ebiten.KeyS) {
|
|||||||
velocity and included snap in so that the player ends up right on
|
velocity and included snap in so that the player ends up right on
|
||||||
the edge of the obstacle and not inside as it is now
|
the edge of the obstacle and not inside as it is now
|
||||||
|
|
||||||
- Check player-player collisions!
|
- Check player-player collisions!
|
||||||
|
|
||||||
|
- Do all collision detections in ONE system
|
||||||
|
|
||||||
|
- do not use the map anymore for collision detection
|
||||||
|
|
||||||
|
- check swept AABB instead of my collision detection, to allow for higher speeds
|
||||||
|
|||||||
@ -4,7 +4,7 @@ Background: background-lila
|
|||||||
|
|
||||||
|
|
||||||
#######
|
#######
|
||||||
# #
|
#o #
|
||||||
# t #
|
# t #
|
||||||
#> S <#
|
#> S <#
|
||||||
# #
|
# #
|
||||||
|
|||||||
@ -4,13 +4,13 @@ Background: background-lila
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
##########
|
########W#
|
||||||
# v#
|
# v #
|
||||||
# #
|
# #
|
||||||
#S s#
|
#S s#
|
||||||
# #
|
############
|
||||||
#^ #
|
# o #
|
||||||
##########
|
######## #
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -25,18 +25,42 @@ type Tile struct {
|
|||||||
Id byte
|
Id byte
|
||||||
Sprite *ebiten.Image
|
Sprite *ebiten.Image
|
||||||
Class string
|
Class string
|
||||||
Solid bool
|
Solid bool // wall brick
|
||||||
Player bool
|
Player bool // player sphere
|
||||||
IsPrimary bool
|
IsPrimary bool // primary player sphere
|
||||||
Renderable bool
|
Renderable bool // visible, has sprite
|
||||||
Velocity bool
|
Velocity bool // movable
|
||||||
Collectible bool
|
Collectible bool // collectible, vanishes once collected
|
||||||
Transient bool
|
Transient bool // turns into brick wall when traversed
|
||||||
Particle int // -1=unused, 0-3 = show image of slice
|
Destroyable bool // turns into empty floor when bumped into twice
|
||||||
Tiles []*ebiten.Image
|
Particle int // -1=unused, 0-3 = show image of slice
|
||||||
TileNames []string // same thing, only the names
|
Tiles []*ebiten.Image // has N sprites
|
||||||
Obstacle bool
|
TileNames []string // same thing, only the names
|
||||||
Direction int // obstacles
|
Obstacle bool // is an obstacle/enemy
|
||||||
|
Direction int // obstacle business end shows into this direction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tile *Tile) Clone() *Tile {
|
||||||
|
newtile := &Tile{
|
||||||
|
Id: tile.Id,
|
||||||
|
Sprite: tile.Sprite,
|
||||||
|
Class: tile.Class,
|
||||||
|
Solid: tile.Solid,
|
||||||
|
Player: tile.Player,
|
||||||
|
IsPrimary: tile.IsPrimary,
|
||||||
|
Renderable: tile.Renderable,
|
||||||
|
Velocity: tile.Velocity,
|
||||||
|
Collectible: tile.Collectible,
|
||||||
|
Transient: tile.Transient,
|
||||||
|
Destroyable: tile.Destroyable,
|
||||||
|
Particle: tile.Particle,
|
||||||
|
Tiles: tile.Tiles,
|
||||||
|
TileNames: tile.TileNames,
|
||||||
|
Obstacle: tile.Obstacle,
|
||||||
|
Direction: tile.Direction,
|
||||||
|
}
|
||||||
|
|
||||||
|
return newtile
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -128,7 +152,7 @@ func NewTileTranswall(class []string) *Tile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Tile{
|
return &Tile{
|
||||||
Id: '*',
|
Id: 't',
|
||||||
Class: "transwall",
|
Class: "transwall",
|
||||||
Solid: false,
|
Solid: false,
|
||||||
Renderable: true,
|
Renderable: true,
|
||||||
@ -139,6 +163,27 @@ func NewTileTranswall(class []string) *Tile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTileHiddenDoor(class []string) *Tile {
|
||||||
|
sprites := []*ebiten.Image{}
|
||||||
|
names := []string{}
|
||||||
|
|
||||||
|
for _, sprite := range class {
|
||||||
|
sprites = append(sprites, Assets[sprite])
|
||||||
|
names = append(names, sprite)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Tile{
|
||||||
|
Id: 'W',
|
||||||
|
Class: "hiddendoor",
|
||||||
|
Solid: false,
|
||||||
|
Renderable: true,
|
||||||
|
Destroyable: true,
|
||||||
|
Tiles: sprites,
|
||||||
|
Sprite: sprites[0], // initially use the first
|
||||||
|
TileNames: names,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// used to map level data bytes to actual tiles
|
// used to map level data bytes to actual tiles
|
||||||
type TileRegistry map[byte]*Tile
|
type TileRegistry map[byte]*Tile
|
||||||
|
|
||||||
@ -164,7 +209,8 @@ type RawLevel struct {
|
|||||||
func InitTiles() TileRegistry {
|
func InitTiles() TileRegistry {
|
||||||
return TileRegistry{
|
return TileRegistry{
|
||||||
' ': {Id: ' ', Class: "floor", Renderable: false},
|
' ': {Id: ' ', Class: "floor", Renderable: false},
|
||||||
'#': NewTileBlock("block-grey32"),
|
//'#': NewTileBlock("block-grey32"),
|
||||||
|
'#': NewTileBlock("block-greycolored"),
|
||||||
'B': NewTileBlock("block-orange-32"),
|
'B': NewTileBlock("block-orange-32"),
|
||||||
'S': NewTilePlayer(Primary),
|
'S': NewTilePlayer(Primary),
|
||||||
's': NewTilePlayer(Secondary),
|
's': NewTilePlayer(Secondary),
|
||||||
@ -183,6 +229,7 @@ func InitTiles() TileRegistry {
|
|||||||
"particle-ring-6",
|
"particle-ring-6",
|
||||||
}),
|
}),
|
||||||
't': NewTileTranswall([]string{"transwall", "block-orange-32"}),
|
't': NewTileTranswall([]string{"transwall", "block-orange-32"}),
|
||||||
|
'W': NewTileHiddenDoor([]string{"block-greycolored", "block-greycolored-damaged"}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
assets/sprites/block-greycolored-damaged.png
Normal file
BIN
assets/sprites/block-greycolored-damaged.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/sprites/block-greycolored.png
Normal file
BIN
assets/sprites/block-greycolored.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
29
components/destroyable.go
Normal file
29
components/destroyable.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package components
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A hidden door in a wall. If the player bumps into it once, it shows
|
||||||
|
// damage and it vanishes the next time.
|
||||||
|
|
||||||
|
type Destroyable struct {
|
||||||
|
Activated bool
|
||||||
|
Sprites []*ebiten.Image
|
||||||
|
Current int // sprite index
|
||||||
|
}
|
||||||
|
|
||||||
|
func (door *Destroyable) GetNext() *ebiten.Image {
|
||||||
|
if len(door.Sprites) > door.Current {
|
||||||
|
door.Current++
|
||||||
|
return door.Sprites[door.Current]
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Fatalf("not enough sprites in transient tile, have %d sprites, index requested: %d",
|
||||||
|
len(door.Sprites), door.Current+1,
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -96,7 +96,6 @@ func (game *Game) Update() error {
|
|||||||
|
|
||||||
if next == Play {
|
if next == Play {
|
||||||
// fresh setup of actual level every time we enter the play scene
|
// fresh setup of actual level every time we enter the play scene
|
||||||
//game.Scenes[Play] = NewLevelScene(game, gameobserver.CurrentLevel)
|
|
||||||
game.Scenes[Play].SetLevel(gameobserver.CurrentLevel)
|
game.Scenes[Play].SetLevel(gameobserver.CurrentLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package game
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"log"
|
"log"
|
||||||
|
"log/slog"
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
"openquell/grid"
|
"openquell/grid"
|
||||||
@ -15,12 +16,16 @@ import (
|
|||||||
"github.com/mlange-42/arche/ecs"
|
"github.com/mlange-42/arche/ecs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Map map[image.Point]*assets.Tile
|
||||||
|
type BackupMap map[image.Point]assets.Tile
|
||||||
|
|
||||||
type Level struct {
|
type Level struct {
|
||||||
Cellsize, Width, Height int
|
Cellsize, Width, Height int
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
Mapslice map[image.Point]*assets.Tile
|
Mapslice Map
|
||||||
|
BackupMapslice Map
|
||||||
GridContainer *grid.GridContainer
|
GridContainer *grid.GridContainer
|
||||||
Systems []systems.System
|
Systems []systems.System
|
||||||
Grid *grid.Grid
|
Grid *grid.Grid
|
||||||
@ -45,16 +50,21 @@ func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
|
|||||||
|
|
||||||
systemlist = append(systemlist, systems.NewTransientSystem(game.World, gridcontainer))
|
systemlist = append(systemlist, systems.NewTransientSystem(game.World, gridcontainer))
|
||||||
|
|
||||||
|
systemlist = append(systemlist, systems.NewDestroyableSystem(game.World, gridcontainer))
|
||||||
|
|
||||||
|
mapslice, backupmap := LevelToSlice(game, plan, cellsize)
|
||||||
|
|
||||||
return &Level{
|
return &Level{
|
||||||
Mapslice: LevelToSlice(game, plan, cellsize),
|
Mapslice: mapslice,
|
||||||
Cellsize: cellsize,
|
BackupMapslice: backupmap,
|
||||||
World: game.World,
|
Cellsize: cellsize,
|
||||||
Width: game.ScreenWidth,
|
World: game.World,
|
||||||
Height: game.ScreenHeight,
|
Width: game.ScreenWidth,
|
||||||
Description: plan.Description,
|
Height: game.ScreenHeight,
|
||||||
Name: plan.Name,
|
Description: plan.Description,
|
||||||
GridContainer: gridcontainer,
|
Name: plan.Name,
|
||||||
Systems: systemlist,
|
GridContainer: gridcontainer,
|
||||||
|
Systems: systemlist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +87,12 @@ func (level *Level) Position2Point(position *components.Position) image.Point {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (level *Level) RestoreMap() {
|
||||||
|
for point, tile := range level.BackupMapslice {
|
||||||
|
level.Mapslice[point] = tile.Clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (level *Level) SetupGrid(game *Game) {
|
func (level *Level) SetupGrid(game *Game) {
|
||||||
// generic variant does not work here:
|
// generic variant does not work here:
|
||||||
// selector := generic.NewFilter1[components.Position]()
|
// selector := generic.NewFilter1[components.Position]()
|
||||||
@ -92,15 +108,20 @@ func (level *Level) SetupGrid(game *Game) {
|
|||||||
playerobserver := observers.GetPlayerObserver(level.World)
|
playerobserver := observers.GetPlayerObserver(level.World)
|
||||||
playerobserver.RemoveEntities()
|
playerobserver.RemoveEntities()
|
||||||
|
|
||||||
|
// get rid of possibly manipulated map
|
||||||
|
level.RestoreMap()
|
||||||
|
|
||||||
// setup world
|
// setup world
|
||||||
|
slog.Debug("new grid?")
|
||||||
level.GridContainer.SetGrid(
|
level.GridContainer.SetGrid(
|
||||||
grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice))
|
grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice))
|
||||||
}
|
}
|
||||||
|
|
||||||
// parses a RawLevel and generates a mapslice from it, which is being used as grid
|
// parses a RawLevel and generates a mapslice from it, which is being used as grid
|
||||||
func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) map[image.Point]*assets.Tile {
|
func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) (Map, Map) {
|
||||||
size := game.ScreenWidth * game.ScreenHeight
|
size := game.ScreenWidth * game.ScreenHeight
|
||||||
mapslice := make(map[image.Point]*assets.Tile, size)
|
mapslice := make(Map, size)
|
||||||
|
backupmap := make(Map, size)
|
||||||
|
|
||||||
for y, line := range strings.Split(string(level.Data), "\n") {
|
for y, line := range strings.Split(string(level.Data), "\n") {
|
||||||
if len(line) != game.ScreenWidth/tilesize && y < game.ScreenHeight/tilesize {
|
if len(line) != game.ScreenWidth/tilesize && y < game.ScreenHeight/tilesize {
|
||||||
@ -113,9 +134,11 @@ func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) map[image.Po
|
|||||||
log.Fatalf("unregistered tile type %c encountered", char)
|
log.Fatalf("unregistered tile type %c encountered", char)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapslice[image.Point{x, y}] = assets.Tiles[byte(char)]
|
tile := assets.Tiles[byte(char)]
|
||||||
|
mapslice[image.Point{x, y}] = tile
|
||||||
|
backupmap[image.Point{x, y}] = tile.Clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapslice
|
return mapslice, backupmap
|
||||||
}
|
}
|
||||||
|
|||||||
20
grid/grid.go
20
grid/grid.go
@ -61,12 +61,18 @@ func NewGrid(world *ecs.World,
|
|||||||
components.Renderable,
|
components.Renderable,
|
||||||
components.Transient](world)
|
components.Transient](world)
|
||||||
|
|
||||||
|
doormapper := generic.NewMap3[
|
||||||
|
components.Position,
|
||||||
|
components.Renderable,
|
||||||
|
components.Destroyable](world)
|
||||||
|
|
||||||
var pos *components.Position
|
var pos *components.Position
|
||||||
var vel *components.Velocity
|
var vel *components.Velocity
|
||||||
var render *components.Renderable
|
var render *components.Renderable
|
||||||
var speed *components.Speed
|
var speed *components.Speed
|
||||||
var transient *components.Transient
|
var transient *components.Transient
|
||||||
var player *components.Player
|
var player *components.Player
|
||||||
|
var destroyable *components.Destroyable
|
||||||
|
|
||||||
playerobserver := observers.GetPlayerObserver(world)
|
playerobserver := observers.GetPlayerObserver(world)
|
||||||
obstacleobserver := observers.GetObstacleObserver(world)
|
obstacleobserver := observers.GetObstacleObserver(world)
|
||||||
@ -99,6 +105,10 @@ func NewGrid(world *ecs.World,
|
|||||||
entity := transmapper.New()
|
entity := transmapper.New()
|
||||||
pos, render, transient = transmapper.Get(entity)
|
pos, render, transient = transmapper.Get(entity)
|
||||||
transient.Sprites = tile.TileNames
|
transient.Sprites = tile.TileNames
|
||||||
|
case tile.Destroyable:
|
||||||
|
entity := doormapper.New()
|
||||||
|
pos, render, destroyable = doormapper.Get(entity)
|
||||||
|
destroyable.Sprites = tile.Tiles
|
||||||
default:
|
default:
|
||||||
log.Fatalln("unsupported tile type encountered")
|
log.Fatalln("unsupported tile type encountered")
|
||||||
}
|
}
|
||||||
@ -143,7 +153,15 @@ func (grid *Grid) GetTile(
|
|||||||
return tile
|
return tile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (grid *Grid) SetTile(tile *assets.Tile, point image.Point) {
|
func (grid *Grid) RemoveTile(point image.Point) {
|
||||||
|
delete(grid.Map, point)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grid *Grid) SetFloorTile(point image.Point) {
|
||||||
|
grid.Map[point] = assets.Tiles[' ']
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grid *Grid) SetSolidTile(tile *assets.Tile, point image.Point) {
|
||||||
solidmapper := generic.NewMap4[
|
solidmapper := generic.NewMap4[
|
||||||
components.Position,
|
components.Position,
|
||||||
components.Renderable,
|
components.Renderable,
|
||||||
|
|||||||
BIN
src/block-grey-damage.xcf
Normal file
BIN
src/block-grey-damage.xcf
Normal file
Binary file not shown.
Binary file not shown.
108
systems/destroyable_system.go
Normal file
108
systems/destroyable_system.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package systems
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"openquell/components"
|
||||||
|
. "openquell/components"
|
||||||
|
. "openquell/config"
|
||||||
|
|
||||||
|
"openquell/grid"
|
||||||
|
"openquell/observers"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/mlange-42/arche/ecs"
|
||||||
|
"github.com/mlange-42/arche/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DestroyableSystem struct {
|
||||||
|
World *ecs.World
|
||||||
|
Selector *generic.Filter3[Position, Renderable, Destroyable]
|
||||||
|
GridContainer *grid.GridContainer
|
||||||
|
SolidMapper generic.Map4[ // needed for replacement
|
||||||
|
components.Position,
|
||||||
|
components.Renderable,
|
||||||
|
components.Tilish,
|
||||||
|
components.Solid]
|
||||||
|
}
|
||||||
|
|
||||||
|
type DoorToRemove struct {
|
||||||
|
Entity ecs.Entity
|
||||||
|
Position *components.Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDestroyableSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
|
||||||
|
solidmapper := generic.NewMap4[
|
||||||
|
components.Position,
|
||||||
|
components.Renderable,
|
||||||
|
components.Tilish,
|
||||||
|
components.Solid](world)
|
||||||
|
|
||||||
|
system := &DestroyableSystem{
|
||||||
|
Selector: generic.NewFilter3[Position, Renderable, Destroyable](),
|
||||||
|
World: world,
|
||||||
|
GridContainer: gridcontainer,
|
||||||
|
SolidMapper: solidmapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
return system
|
||||||
|
}
|
||||||
|
|
||||||
|
func (system *DestroyableSystem) Update() error {
|
||||||
|
playerobserver := observers.GetPlayerObserver(system.World)
|
||||||
|
posID := ecs.ComponentID[components.Position](system.World)
|
||||||
|
veloID := ecs.ComponentID[components.Velocity](system.World)
|
||||||
|
|
||||||
|
query := system.Selector.Query(system.World)
|
||||||
|
|
||||||
|
EntitiestoRemove := []*DoorToRemove{}
|
||||||
|
|
||||||
|
for query.Next() {
|
||||||
|
doorposition, renderable, door := query.Get()
|
||||||
|
|
||||||
|
for player := range playerobserver.Entities {
|
||||||
|
playerposition := (*Position)(system.World.Get(player, posID))
|
||||||
|
playervelocity := (*Velocity)(system.World.Get(player, veloID))
|
||||||
|
|
||||||
|
ok, newpos := doorposition.Intersects(playerposition, playervelocity)
|
||||||
|
if ok {
|
||||||
|
// player bumped into hidden wall, activate it, snap in player
|
||||||
|
slog.Debug("bump not die", "originalpos", playerposition)
|
||||||
|
playervelocity.Change(Stop)
|
||||||
|
playerposition.Set(newpos)
|
||||||
|
|
||||||
|
if door.Activated {
|
||||||
|
// player bumps into the door a second time, now hide it
|
||||||
|
EntitiestoRemove = append(EntitiestoRemove,
|
||||||
|
&DoorToRemove{Entity: query.Entity(), Position: doorposition})
|
||||||
|
} else {
|
||||||
|
slog.Debug("activating destroyable", "doorpos", doorposition)
|
||||||
|
door.Activated = true
|
||||||
|
renderable.Image = door.GetNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, door := range EntitiestoRemove {
|
||||||
|
slog.Debug("hiding destroyable", "doorpos", door.Position.Point())
|
||||||
|
|
||||||
|
// remove door entity
|
||||||
|
system.World.RemoveEntity(door.Entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (system *DestroyableSystem) Draw(screen *ebiten.Image) {
|
||||||
|
// write transients (these are no tiles!)
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
query := system.Selector.Query(system.World)
|
||||||
|
|
||||||
|
for query.Next() {
|
||||||
|
pos, render, _ := query.Get()
|
||||||
|
|
||||||
|
op.GeoM.Reset()
|
||||||
|
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
||||||
|
screen.DrawImage(render.Image, op)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ package systems
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
|
"log/slog"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
@ -44,8 +45,8 @@ func (system *GridSystem) Update() error { return nil }
|
|||||||
func (system *GridSystem) Draw(screen *ebiten.Image) {
|
func (system *GridSystem) Draw(screen *ebiten.Image) {
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
query := system.Selector.Query(system.World)
|
query := system.Selector.Query(system.World)
|
||||||
|
|
||||||
if !system.UseCache || query.Count() != system.Count {
|
if !system.UseCache || query.Count() != system.Count {
|
||||||
|
slog.Debug("entity number changes", "old", system.Count, "current", query.Count())
|
||||||
// map not cached or cacheable, write it to the cache
|
// map not cached or cacheable, write it to the cache
|
||||||
draw.Draw(system.Cache, system.Background.Bounds(), system.Background, image.ZP, draw.Src)
|
draw.Draw(system.Cache, system.Background.Bounds(), system.Background, image.ZP, draw.Src)
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ func (system *GridSystem) Draw(screen *ebiten.Image) {
|
|||||||
for query.Next() {
|
for query.Next() {
|
||||||
sprite, pos, _ := query.Get()
|
sprite, pos, _ := query.Get()
|
||||||
|
|
||||||
|
//slog.Debug("drawing sprite", "sprite", sprite, "point", pos.Point())
|
||||||
draw.Draw(
|
draw.Draw(
|
||||||
system.Cache,
|
system.Cache,
|
||||||
image.Rect(pos.X, pos.Y, pos.X+pos.Cellsize, pos.Y+pos.Cellsize),
|
image.Rect(pos.X, pos.Y, pos.X+pos.Cellsize, pos.Y+pos.Cellsize),
|
||||||
|
|||||||
@ -95,7 +95,7 @@ func (system *TransientSystem) Update() error {
|
|||||||
|
|
||||||
// also setup the grid tile with a new solid, so that
|
// also setup the grid tile with a new solid, so that
|
||||||
// collision detection works
|
// collision detection works
|
||||||
system.GridContainer.Grid.SetTile(
|
system.GridContainer.Grid.SetSolidTile(
|
||||||
assets.NewTileBlock(convertible.NewSprite),
|
assets.NewTileBlock(convertible.NewSprite),
|
||||||
convertible.Position.Point(),
|
convertible.Position.Point(),
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user