openquell/game/levels.go

95 lines
2.5 KiB
Go
Raw Normal View History

2024-02-06 15:26:20 +01:00
package game
import (
"image"
"log"
"openquell/assets"
"openquell/components"
2024-02-10 19:45:06 +01:00
"openquell/grid"
"openquell/systems"
2024-02-06 15:26:20 +01:00
"strings"
"github.com/hajimehoshi/ebiten/v2"
"github.com/mlange-42/arche/ecs"
)
type Level struct {
Cellsize, Width, Height int
World *ecs.World
Name string
Description string
Mapslice map[image.Point]*assets.Tile
2024-02-07 18:01:58 +01:00
2024-02-10 19:45:06 +01:00
Player *systems.PlayerSystem
GridSystem *systems.GridSystem
2024-02-07 18:01:58 +01:00
2024-02-10 19:45:06 +01:00
Grid *grid.Grid
}
2024-02-07 18:01:58 +01:00
2024-02-10 19:45:06 +01:00
func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
gridsystem := systems.NewGridSystem(game.World, game.ScreenWidth,
game.ScreenHeight, cellsize, plan.Background)
playersystem := systems.NewPlayerSystem(game.World, gridsystem)
2024-02-07 18:01:58 +01:00
2024-02-06 15:26:20 +01:00
return &Level{
Mapslice: LevelToSlice(game, plan, cellsize),
Cellsize: cellsize,
World: game.World,
Width: game.ScreenWidth,
Height: game.ScreenHeight,
Description: plan.Description,
2024-02-10 19:45:06 +01:00
GridSystem: gridsystem,
Player: playersystem,
2024-02-06 15:26:20 +01:00
}
}
func (level *Level) Update() {
2024-02-10 19:45:06 +01:00
level.GridSystem.Update()
level.Player.Update()
}
2024-02-10 19:45:06 +01:00
func (level *Level) Draw(screen *ebiten.Image) {
level.GridSystem.Draw(screen)
level.Player.Draw(screen)
2024-02-06 15:26:20 +01:00
}
func (level *Level) Position2Point(position *components.Position) image.Point {
return image.Point{
int(position.X) / level.Cellsize,
int(position.Y) / level.Cellsize,
}
}
func (level *Level) SetupGrid(game *Game) {
2024-02-09 20:20:13 +01:00
// generic variant does not work here:
// selector := generic.NewFilter1[components.Position]()
// level.World.Batch().RemoveEntities(selector)
// missing argument in conversion to generic.Filter1[components.Position]
// erase all entities of previous level, if any
posID := ecs.ComponentID[components.Position](level.World)
selector := ecs.All(posID)
level.World.Batch().RemoveEntities(selector)
// setup world
2024-02-10 19:45:06 +01:00
level.GridSystem.SetGrid(grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice))
2024-02-06 15:26:20 +01:00
}
func LevelToSlice(game *Game, level *assets.RawLevel, tilesize int) map[image.Point]*assets.Tile {
size := game.ScreenWidth * game.ScreenHeight
mapslice := make(map[image.Point]*assets.Tile, size)
for y, line := range strings.Split(string(level.Data), "\n") {
if len(line) != game.ScreenWidth/tilesize && y < game.ScreenHeight/tilesize {
log.Fatalf("line %d doesn't contain %d tiles, but %d",
y, game.ScreenWidth/tilesize, len(line))
}
for x, char := range line {
mapslice[image.Point{x, y}] = assets.Tiles[byte(char)]
}
}
return mapslice
}