refactored recursive systems out of player_system => game/levels.go
This commit is contained in:
parent
c93070883a
commit
ab07bc23e3
15
game/game.go
15
game/game.go
@ -11,13 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Bounds image.Rectangle
|
Bounds image.Rectangle
|
||||||
ScreenWidth, ScreenHeight int
|
ScreenWidth, ScreenHeight, Cellsize int
|
||||||
Scenes map[SceneName]Scene
|
Scenes map[SceneName]Scene
|
||||||
CurrentScene SceneName
|
CurrentScene SceneName
|
||||||
Observer *observers.GameObserver
|
Observer *observers.GameObserver
|
||||||
Levels []*Level // needed to feed select_scene
|
Levels []*Level // needed to feed select_scene
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Game {
|
func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Game {
|
||||||
@ -29,6 +29,7 @@ func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Gam
|
|||||||
ScreenWidth: width,
|
ScreenWidth: width,
|
||||||
ScreenHeight: height,
|
ScreenHeight: height,
|
||||||
Scenes: map[SceneName]Scene{},
|
Scenes: map[SceneName]Scene{},
|
||||||
|
Cellsize: cellsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
observers.NewPlayerObserver(&world)
|
observers.NewPlayerObserver(&world)
|
||||||
|
|||||||
@ -21,40 +21,53 @@ type Level struct {
|
|||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
Mapslice map[image.Point]*assets.Tile
|
Mapslice map[image.Point]*assets.Tile
|
||||||
|
GridContainer *grid.GridContainer
|
||||||
Player *systems.PlayerSystem
|
Systems []systems.System
|
||||||
GridSystem *systems.GridSystem
|
Grid *grid.Grid
|
||||||
|
|
||||||
Grid *grid.Grid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
|
func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
|
||||||
gridsystem := systems.NewGridSystem(game.World, game.ScreenWidth,
|
systemlist := []systems.System{}
|
||||||
game.ScreenHeight, cellsize, plan.Background)
|
|
||||||
|
|
||||||
playersystem := systems.NewPlayerSystem(game.World, gridsystem)
|
gridcontainer := &grid.GridContainer{}
|
||||||
|
|
||||||
|
systemlist = append(systemlist,
|
||||||
|
systems.NewGridSystem(game.World, game.ScreenWidth, game.ScreenHeight, cellsize, plan.Background))
|
||||||
|
|
||||||
|
systemlist = append(systemlist, systems.NewCollectibleSystem(game.World))
|
||||||
|
|
||||||
|
systemlist = append(systemlist,
|
||||||
|
systems.NewPlayerSystem(game.World, gridcontainer))
|
||||||
|
|
||||||
|
systemlist = append(systemlist, systems.NewParticleSystem(game.World, game.Cellsize))
|
||||||
|
|
||||||
|
systemlist = append(systemlist, systems.NewObstacleSystem(game.World, gridcontainer))
|
||||||
|
|
||||||
|
systemlist = append(systemlist, systems.NewTransientSystem(game.World, gridcontainer))
|
||||||
|
|
||||||
return &Level{
|
return &Level{
|
||||||
Mapslice: LevelToSlice(game, plan, cellsize),
|
Mapslice: LevelToSlice(game, plan, cellsize),
|
||||||
Cellsize: cellsize,
|
Cellsize: cellsize,
|
||||||
World: game.World,
|
World: game.World,
|
||||||
Width: game.ScreenWidth,
|
Width: game.ScreenWidth,
|
||||||
Height: game.ScreenHeight,
|
Height: game.ScreenHeight,
|
||||||
Description: plan.Description,
|
Description: plan.Description,
|
||||||
Name: plan.Name,
|
Name: plan.Name,
|
||||||
GridSystem: gridsystem,
|
GridContainer: gridcontainer,
|
||||||
Player: playersystem,
|
Systems: systemlist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (level *Level) Update() {
|
func (level *Level) Update() {
|
||||||
level.GridSystem.Update()
|
for _, sys := range level.Systems {
|
||||||
level.Player.Update()
|
sys.Update()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (level *Level) Draw(screen *ebiten.Image) {
|
func (level *Level) Draw(screen *ebiten.Image) {
|
||||||
level.GridSystem.Draw(screen)
|
for _, sys := range level.Systems {
|
||||||
level.Player.Draw(screen)
|
sys.Draw(screen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (level *Level) Position2Point(position *components.Position) image.Point {
|
func (level *Level) Position2Point(position *components.Position) image.Point {
|
||||||
@ -80,7 +93,7 @@ func (level *Level) SetupGrid(game *Game) {
|
|||||||
playerobserver.RemoveEntities()
|
playerobserver.RemoveEntities()
|
||||||
|
|
||||||
// setup world
|
// setup world
|
||||||
level.GridSystem.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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
82
grid/collider.go
Normal file
82
grid/collider.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package grid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"openquell/components"
|
||||||
|
. "openquell/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (grid *Grid) GetSolidNeighborPosition(
|
||||||
|
position *components.Position,
|
||||||
|
velocity *components.Velocity,
|
||||||
|
solid bool) (bool, *components.Position) {
|
||||||
|
|
||||||
|
if !solid {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// set to true, if we are already on the last tile in the current
|
||||||
|
// direction, i.e. on the edge of the grid
|
||||||
|
edge := true
|
||||||
|
neighborpos := position.Point()
|
||||||
|
|
||||||
|
switch velocity.Direction {
|
||||||
|
case East:
|
||||||
|
if neighborpos.X < grid.TilesX {
|
||||||
|
neighborpos.X++
|
||||||
|
edge = false
|
||||||
|
}
|
||||||
|
case West:
|
||||||
|
if neighborpos.X > 0 {
|
||||||
|
neighborpos.X--
|
||||||
|
edge = false
|
||||||
|
}
|
||||||
|
case South:
|
||||||
|
if neighborpos.Y < grid.TilesY {
|
||||||
|
neighborpos.Y++
|
||||||
|
edge = false
|
||||||
|
}
|
||||||
|
case North:
|
||||||
|
if neighborpos.Y > 0 {
|
||||||
|
neighborpos.Y--
|
||||||
|
edge = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newpos := components.NewPosition(neighborpos, grid.Tilesize)
|
||||||
|
|
||||||
|
if !edge && grid.Map[neighborpos].Solid {
|
||||||
|
return true, newpos
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grid *Grid) BumpEdge(
|
||||||
|
pos *components.Position,
|
||||||
|
velocity *components.Velocity) (bool, *components.Position) {
|
||||||
|
|
||||||
|
x := pos.X + velocity.Data.X
|
||||||
|
y := pos.Y + velocity.Data.Y
|
||||||
|
|
||||||
|
if x < 0 || x > grid.Width-grid.Tilesize || y < 0 || y > grid.Height-grid.Tilesize {
|
||||||
|
newpos := &components.Position{}
|
||||||
|
X := pos.X
|
||||||
|
Y := pos.Y
|
||||||
|
|
||||||
|
switch velocity.Direction {
|
||||||
|
case East:
|
||||||
|
X = 0
|
||||||
|
case West:
|
||||||
|
X = grid.Width - grid.Tilesize
|
||||||
|
case South:
|
||||||
|
Y = 0
|
||||||
|
case North:
|
||||||
|
Y = grid.Height - grid.Tilesize
|
||||||
|
}
|
||||||
|
|
||||||
|
newpos.Update(X, Y, grid.Tilesize)
|
||||||
|
return true, newpos
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
9
grid/container.go
Normal file
9
grid/container.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package grid
|
||||||
|
|
||||||
|
type GridContainer struct {
|
||||||
|
Grid *Grid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (container *GridContainer) SetGrid(grid *Grid) {
|
||||||
|
container.Grid = grid
|
||||||
|
}
|
||||||
15
grid/grid.go
15
grid/grid.go
@ -13,12 +13,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Grid struct {
|
type Grid struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
Size int
|
Size int
|
||||||
Tilesize int
|
Tilesize int
|
||||||
Map map[image.Point]*assets.Tile
|
TilesX, TilesY int
|
||||||
|
Map map[image.Point]*assets.Tile
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: put component addition into extra callable function, to be called
|
// FIXME: put component addition into extra callable function, to be called
|
||||||
@ -123,6 +124,8 @@ func NewGrid(world *ecs.World,
|
|||||||
Height: height,
|
Height: height,
|
||||||
Map: mapslice,
|
Map: mapslice,
|
||||||
World: world,
|
World: world,
|
||||||
|
TilesX: width / tilesize,
|
||||||
|
TilesY: height / tilesize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ type CollectibleSystem struct {
|
|||||||
Selector *generic.Filter3[Position, Collectible, Renderable]
|
Selector *generic.Filter3[Position, Collectible, Renderable]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCollectibleSystem(world *ecs.World) *CollectibleSystem {
|
func NewCollectibleSystem(world *ecs.World) System {
|
||||||
system := &CollectibleSystem{
|
system := &CollectibleSystem{
|
||||||
Selector: generic.NewFilter3[Position, Collectible, Renderable](),
|
Selector: generic.NewFilter3[Position, Collectible, Renderable](),
|
||||||
World: world,
|
World: world,
|
||||||
@ -28,7 +28,7 @@ func NewCollectibleSystem(world *ecs.World) *CollectibleSystem {
|
|||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *CollectibleSystem) Update() {
|
func (system *CollectibleSystem) Update() error {
|
||||||
playerobserver := observers.GetPlayerObserver(system.World)
|
playerobserver := observers.GetPlayerObserver(system.World)
|
||||||
gameobserver := observers.GetGameObserver(system.World)
|
gameobserver := observers.GetGameObserver(system.World)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ func (system *CollectibleSystem) Update() {
|
|||||||
|
|
||||||
if numcollectibles == 0 || gameobserver.Lost {
|
if numcollectibles == 0 || gameobserver.Lost {
|
||||||
query.Close()
|
query.Close()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for query.Next() {
|
for query.Next() {
|
||||||
@ -78,6 +78,8 @@ func (system *CollectibleSystem) Update() {
|
|||||||
timer.Start(LEVEL_END_WAIT)
|
timer.Start(LEVEL_END_WAIT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *CollectibleSystem) Draw(screen *ebiten.Image) {
|
func (system *CollectibleSystem) Draw(screen *ebiten.Image) {
|
||||||
|
|||||||
@ -3,10 +3,7 @@ package systems
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"openquell/components"
|
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
. "openquell/config"
|
|
||||||
"openquell/grid"
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/mlange-42/arche/ecs"
|
"github.com/mlange-42/arche/ecs"
|
||||||
@ -14,18 +11,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type GridSystem struct {
|
type GridSystem struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Selector *generic.Filter3[Renderable, Position, Solid]
|
Selector *generic.Filter3[Renderable, Position, Solid]
|
||||||
UseCache bool
|
UseCache bool
|
||||||
Cache *ebiten.Image
|
Cache *ebiten.Image
|
||||||
Count int // register tile count, invalidates cache
|
Count int // register tile count, invalidates cache
|
||||||
Background *ebiten.Image
|
Background *ebiten.Image
|
||||||
Width, Height, TilesX, TilesY, Tilesize int
|
Width, Height, Tilesize int
|
||||||
Grid *grid.Grid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGridSystem(world *ecs.World, width, height,
|
func NewGridSystem(world *ecs.World, width, height,
|
||||||
tilesize int, background *ebiten.Image) *GridSystem {
|
tilesize int, background *ebiten.Image) System {
|
||||||
|
|
||||||
cache := ebiten.NewImage(width, height)
|
cache := ebiten.NewImage(width, height)
|
||||||
|
|
||||||
@ -35,8 +31,6 @@ func NewGridSystem(world *ecs.World, width, height,
|
|||||||
Cache: cache,
|
Cache: cache,
|
||||||
Width: width,
|
Width: width,
|
||||||
Height: height,
|
Height: height,
|
||||||
TilesX: width / tilesize,
|
|
||||||
TilesY: height / tilesize,
|
|
||||||
Tilesize: tilesize,
|
Tilesize: tilesize,
|
||||||
Background: background,
|
Background: background,
|
||||||
World: world,
|
World: world,
|
||||||
@ -45,11 +39,7 @@ func NewGridSystem(world *ecs.World, width, height,
|
|||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *GridSystem) SetGrid(grid *grid.Grid) {
|
func (system *GridSystem) Update() error { return nil }
|
||||||
system.Grid = grid
|
|
||||||
}
|
|
||||||
|
|
||||||
func (system *GridSystem) Update() {}
|
|
||||||
|
|
||||||
func (system *GridSystem) Draw(screen *ebiten.Image) {
|
func (system *GridSystem) Draw(screen *ebiten.Image) {
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
@ -81,79 +71,3 @@ func (system *GridSystem) Draw(screen *ebiten.Image) {
|
|||||||
query.Close()
|
query.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *GridSystem) GetSolidNeighborPosition(
|
|
||||||
position *components.Position,
|
|
||||||
velocity *components.Velocity,
|
|
||||||
solid bool) (bool, *components.Position) {
|
|
||||||
|
|
||||||
if !solid {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// set to true, if we are already on the last tile in the current
|
|
||||||
// direction, i.e. on the edge of the grid
|
|
||||||
edge := true
|
|
||||||
neighborpos := position.Point()
|
|
||||||
|
|
||||||
switch velocity.Direction {
|
|
||||||
case East:
|
|
||||||
if neighborpos.X < system.TilesX {
|
|
||||||
neighborpos.X++
|
|
||||||
edge = false
|
|
||||||
}
|
|
||||||
case West:
|
|
||||||
if neighborpos.X > 0 {
|
|
||||||
neighborpos.X--
|
|
||||||
edge = false
|
|
||||||
}
|
|
||||||
case South:
|
|
||||||
if neighborpos.Y < system.TilesY {
|
|
||||||
neighborpos.Y++
|
|
||||||
edge = false
|
|
||||||
}
|
|
||||||
case North:
|
|
||||||
if neighborpos.Y > 0 {
|
|
||||||
neighborpos.Y--
|
|
||||||
edge = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newpos := components.NewPosition(neighborpos, system.Tilesize)
|
|
||||||
|
|
||||||
if !edge && system.Grid.Map[neighborpos].Solid {
|
|
||||||
return true, newpos
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (system *GridSystem) BumpEdge(
|
|
||||||
pos *components.Position,
|
|
||||||
velocity *components.Velocity) (bool, *components.Position) {
|
|
||||||
|
|
||||||
x := pos.X + velocity.Data.X
|
|
||||||
y := pos.Y + velocity.Data.Y
|
|
||||||
|
|
||||||
if x < 0 || x > system.Width-system.Tilesize || y < 0 || y > system.Height-system.Tilesize {
|
|
||||||
newpos := &components.Position{}
|
|
||||||
X := pos.X
|
|
||||||
Y := pos.Y
|
|
||||||
|
|
||||||
switch velocity.Direction {
|
|
||||||
case East:
|
|
||||||
X = 0
|
|
||||||
case West:
|
|
||||||
X = system.Width - system.Tilesize
|
|
||||||
case South:
|
|
||||||
Y = 0
|
|
||||||
case North:
|
|
||||||
Y = system.Height - system.Tilesize
|
|
||||||
}
|
|
||||||
|
|
||||||
newpos.Update(X, Y, system.Tilesize)
|
|
||||||
return true, newpos
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"openquell/components"
|
"openquell/components"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
. "openquell/config"
|
. "openquell/config"
|
||||||
|
"openquell/grid"
|
||||||
"openquell/observers"
|
"openquell/observers"
|
||||||
"openquell/util"
|
"openquell/util"
|
||||||
|
|
||||||
@ -15,28 +16,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ObstacleSystem struct {
|
type ObstacleSystem struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Selector *generic.Filter5[Position, Velocity, Obstacle, Renderable, Speed]
|
Selector *generic.Filter5[Position, Velocity, Obstacle, Renderable, Speed]
|
||||||
Grid *GridSystem
|
GridContainer *grid.GridContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewObstacleSystem(world *ecs.World, grid *GridSystem) *ObstacleSystem {
|
func NewObstacleSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
|
||||||
system := &ObstacleSystem{
|
system := &ObstacleSystem{
|
||||||
Selector: generic.NewFilter5[Position, Velocity, Obstacle, Renderable, Speed](),
|
Selector: generic.NewFilter5[Position, Velocity, Obstacle, Renderable, Speed](),
|
||||||
World: world,
|
World: world,
|
||||||
Grid: grid,
|
GridContainer: gridcontainer,
|
||||||
}
|
}
|
||||||
|
|
||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *ObstacleSystem) Update() {
|
func (system *ObstacleSystem) Update() error {
|
||||||
playerobserver := observers.GetPlayerObserver(system.World)
|
playerobserver := observers.GetPlayerObserver(system.World)
|
||||||
gameobserver := observers.GetGameObserver(system.World)
|
gameobserver := observers.GetGameObserver(system.World)
|
||||||
obstacleobserver := observers.GetObstacleObserver(system.World)
|
obstacleobserver := observers.GetObstacleObserver(system.World)
|
||||||
|
|
||||||
if gameobserver.Lost {
|
if gameobserver.Lost {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
posID := ecs.ComponentID[components.Position](system.World)
|
posID := ecs.ComponentID[components.Position](system.World)
|
||||||
@ -94,7 +95,7 @@ func (system *ObstacleSystem) Update() {
|
|||||||
// FIXME: this is the same loop as in player_system, unite the
|
// FIXME: this is the same loop as in player_system, unite the
|
||||||
// two, just iterate over all entities with pos,vel,render, dammit
|
// two, just iterate over all entities with pos,vel,render, dammit
|
||||||
if obsvelocity.Moving() {
|
if obsvelocity.Moving() {
|
||||||
ok, tilepos := system.Grid.GetSolidNeighborPosition(obsposition, obsvelocity, true)
|
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(obsposition, obsvelocity, true)
|
||||||
if ok {
|
if ok {
|
||||||
intersects, newpos := tilepos.Intersects(obsposition, obsvelocity)
|
intersects, newpos := tilepos.Intersects(obsposition, obsvelocity)
|
||||||
if intersects {
|
if intersects {
|
||||||
@ -125,6 +126,8 @@ func (system *ObstacleSystem) Update() {
|
|||||||
|
|
||||||
gameobserver.Gameover()
|
gameobserver.Gameover()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *ObstacleSystem) Draw(screen *ebiten.Image) {
|
func (system *ObstacleSystem) Draw(screen *ebiten.Image) {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ type ParticleSystem struct {
|
|||||||
Cellsize int
|
Cellsize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewParticleSystem(world *ecs.World, cellsize int) *ParticleSystem {
|
func NewParticleSystem(world *ecs.World, cellsize int) System {
|
||||||
system := &ParticleSystem{
|
system := &ParticleSystem{
|
||||||
Selector: generic.NewFilter3[Position, Particle, Timer](),
|
Selector: generic.NewFilter3[Position, Particle, Timer](),
|
||||||
World: world,
|
World: world,
|
||||||
@ -25,7 +25,7 @@ func NewParticleSystem(world *ecs.World, cellsize int) *ParticleSystem {
|
|||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *ParticleSystem) Update() {
|
func (system *ParticleSystem) Update() error {
|
||||||
// display debris after collecting
|
// display debris after collecting
|
||||||
EntitiesToRemove := []ecs.Entity{}
|
EntitiesToRemove := []ecs.Entity{}
|
||||||
|
|
||||||
@ -56,6 +56,8 @@ func (system *ParticleSystem) Update() {
|
|||||||
for _, entity := range EntitiesToRemove {
|
for _, entity := range EntitiesToRemove {
|
||||||
system.World.RemoveEntity(entity)
|
system.World.RemoveEntity(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *ParticleSystem) Draw(screen *ebiten.Image) {
|
func (system *ParticleSystem) Draw(screen *ebiten.Image) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
. "openquell/config"
|
. "openquell/config"
|
||||||
|
"openquell/grid"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
@ -12,24 +13,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PlayerSystem struct {
|
type PlayerSystem struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Selector *generic.Filter5[Position, Velocity, Player, Renderable, Speed]
|
Selector *generic.Filter5[Position, Velocity, Player, Renderable, Speed]
|
||||||
Particle *ParticleSystem
|
GridContainer *grid.GridContainer
|
||||||
Collectible *CollectibleSystem
|
|
||||||
Obstacle *ObstacleSystem
|
|
||||||
Transient *TransientSystem
|
|
||||||
Grid *GridSystem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlayerSystem(world *ecs.World, grid *GridSystem) *PlayerSystem {
|
func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
|
||||||
system := &PlayerSystem{
|
system := &PlayerSystem{
|
||||||
Selector: generic.NewFilter5[Position, Velocity, Player, Renderable, Speed](),
|
Selector: generic.NewFilter5[Position, Velocity, Player, Renderable, Speed](),
|
||||||
Particle: NewParticleSystem(world, grid.Tilesize),
|
GridContainer: gridcontainer,
|
||||||
Collectible: NewCollectibleSystem(world),
|
World: world,
|
||||||
Obstacle: NewObstacleSystem(world, grid),
|
|
||||||
Transient: NewTransientSystem(world, grid),
|
|
||||||
Grid: grid,
|
|
||||||
World: world,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return system
|
return system
|
||||||
@ -87,12 +80,12 @@ func (system PlayerSystem) Update() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if velocity.Moving() {
|
if velocity.Moving() {
|
||||||
ok, newpos := system.Grid.BumpEdge(playerposition, velocity)
|
ok, newpos := system.GridContainer.Grid.BumpEdge(playerposition, velocity)
|
||||||
if ok {
|
if ok {
|
||||||
//slog.Debug("falling off the edge", "newpos", newpos)
|
//slog.Debug("falling off the edge", "newpos", newpos)
|
||||||
playerposition.Set(newpos)
|
playerposition.Set(newpos)
|
||||||
} else {
|
} else {
|
||||||
ok, tilepos := system.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
||||||
if ok {
|
if ok {
|
||||||
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
||||||
if intersects {
|
if intersects {
|
||||||
@ -107,11 +100,6 @@ func (system PlayerSystem) Update() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
system.Particle.Update() // may set player position
|
|
||||||
system.Obstacle.Update()
|
|
||||||
system.Collectible.Update()
|
|
||||||
system.Transient.Update()
|
|
||||||
|
|
||||||
query = system.Selector.Query(system.World)
|
query = system.Selector.Query(system.World)
|
||||||
for query.Next() {
|
for query.Next() {
|
||||||
// move player after obstacle or collectible updates
|
// move player after obstacle or collectible updates
|
||||||
@ -135,9 +123,4 @@ func (system *PlayerSystem) Draw(screen *ebiten.Image) {
|
|||||||
|
|
||||||
screen.DrawImage(sprite.Image, op)
|
screen.DrawImage(sprite.Image, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
system.Collectible.Draw(screen)
|
|
||||||
system.Particle.Draw(screen)
|
|
||||||
system.Obstacle.Draw(screen)
|
|
||||||
system.Transient.Draw(screen)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
|
"openquell/grid"
|
||||||
"openquell/observers"
|
"openquell/observers"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
@ -13,10 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TransientSystem struct {
|
type TransientSystem struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Selector *generic.Filter3[Position, Renderable, Transient]
|
Selector *generic.Filter3[Position, Renderable, Transient]
|
||||||
Grid *GridSystem
|
GridContainer *grid.GridContainer
|
||||||
SolidMapper generic.Map4[ // needed for replacement
|
SolidMapper generic.Map4[ // needed for replacement
|
||||||
components.Position,
|
components.Position,
|
||||||
components.Renderable,
|
components.Renderable,
|
||||||
components.Tilish,
|
components.Tilish,
|
||||||
@ -29,7 +30,7 @@ type TransientToWall struct {
|
|||||||
Position components.Position
|
Position components.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransientSystem(world *ecs.World, grid *GridSystem) *TransientSystem {
|
func NewTransientSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
|
||||||
solidmapper := generic.NewMap4[
|
solidmapper := generic.NewMap4[
|
||||||
components.Position,
|
components.Position,
|
||||||
components.Renderable,
|
components.Renderable,
|
||||||
@ -37,16 +38,16 @@ func NewTransientSystem(world *ecs.World, grid *GridSystem) *TransientSystem {
|
|||||||
components.Solid](world)
|
components.Solid](world)
|
||||||
|
|
||||||
system := &TransientSystem{
|
system := &TransientSystem{
|
||||||
Selector: generic.NewFilter3[Position, Renderable, Transient](),
|
Selector: generic.NewFilter3[Position, Renderable, Transient](),
|
||||||
World: world,
|
World: world,
|
||||||
Grid: grid,
|
GridContainer: gridcontainer,
|
||||||
SolidMapper: solidmapper,
|
SolidMapper: solidmapper,
|
||||||
}
|
}
|
||||||
|
|
||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *TransientSystem) Update() {
|
func (system *TransientSystem) Update() error {
|
||||||
playerobserver := observers.GetPlayerObserver(system.World)
|
playerobserver := observers.GetPlayerObserver(system.World)
|
||||||
posID := ecs.ComponentID[components.Position](system.World)
|
posID := ecs.ComponentID[components.Position](system.World)
|
||||||
veloID := ecs.ComponentID[components.Velocity](system.World)
|
veloID := ecs.ComponentID[components.Velocity](system.World)
|
||||||
@ -94,11 +95,13 @@ func (system *TransientSystem) Update() {
|
|||||||
|
|
||||||
// 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.Grid.Grid.SetTile(
|
system.GridContainer.Grid.SetTile(
|
||||||
assets.NewTileBlock(convertible.NewSprite),
|
assets.NewTileBlock(convertible.NewSprite),
|
||||||
convertible.Position.Point(),
|
convertible.Position.Point(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *TransientSystem) Draw(screen *ebiten.Image) {
|
func (system *TransientSystem) Draw(screen *ebiten.Image) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user