From 65ddec3fa4562ccbb593da080060d98946271803 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Sun, 11 Feb 2024 14:24:30 +0100 Subject: [PATCH] fixed observers, added GameObserver --- assets/levels/0-own.lvl | 17 +++++++++++++ assets/levels/{gurke.lvl => 1-start.lvl} | 0 assets/levels/gen.sh | 11 +++++---- assets/levels/intro.lvl | 17 ------------- components/components.go | 14 +++++++---- components/position.go | 4 +-- components/velocity.go | 10 +++----- config/static.go | 2 ++ game/game.go | 6 ++--- game/levels.go | 5 ++++ game/levelscene.go | 12 +++++++-- grid/grid.go | 9 ++++--- main.go | 7 +++--- observers/game_observer.go | 31 ++++++++++++++++++++++++ observers/player_observer.go | 4 +++ systems/collectible_system.go | 14 +++++++++++ systems/grid_system.go | 2 -- systems/player_system.go | 10 ++++---- 18 files changed, 122 insertions(+), 53 deletions(-) create mode 100644 assets/levels/0-own.lvl rename assets/levels/{gurke.lvl => 1-start.lvl} (100%) delete mode 100644 assets/levels/intro.lvl create mode 100644 observers/game_observer.go diff --git a/assets/levels/0-own.lvl b/assets/levels/0-own.lvl new file mode 100644 index 0000000..a4dc0fb --- /dev/null +++ b/assets/levels/0-own.lvl @@ -0,0 +1,17 @@ +Description: win +Background: background-lila + + + + + ######## + # #o# + # S # # + # #### # + + + # #### # + # # + # o # + ######## + diff --git a/assets/levels/gurke.lvl b/assets/levels/1-start.lvl similarity index 100% rename from assets/levels/gurke.lvl rename to assets/levels/1-start.lvl diff --git a/assets/levels/gen.sh b/assets/levels/gen.sh index 8d57af4..705580e 100755 --- a/assets/levels/gen.sh +++ b/assets/levels/gen.sh @@ -1,6 +1,6 @@ -#!/bin/sh -width=$(grep "width int" ../main.go | awk '{print $4}') -height=$(grep "height int" ../main.go | awk '{print $4}') +#!/bin/bash +width=$(grep "width " ../../main.go | awk '{print $4}') +height=$(grep "height " ../../main.go | awk '{print $4}') read -p " Enter level name: " name read -p " Enter background: " background @@ -14,11 +14,12 @@ if test -z "$bbackground"; then background="background-lila" fi +w=$(($width/32)) +h=$(($height/32)) + ( echo "Description: $des" echo "Background: $background" - w=$(($width / 32)) - h=$(($height / 32)) for x in $(seq 1 $h); do for y in $(seq 1 $w); do diff --git a/assets/levels/intro.lvl b/assets/levels/intro.lvl deleted file mode 100644 index 8bc0a05..0000000 --- a/assets/levels/intro.lvl +++ /dev/null @@ -1,17 +0,0 @@ -Description: Introduction: collect the goods by moving the ball onto them -Background: background-lila -#################### -# # -# # -# # -# # -# # -# # -# ###### -# -# -# -# -# -# -#################### diff --git a/components/components.go b/components/components.go index 3fa72f8..3358571 100644 --- a/components/components.go +++ b/components/components.go @@ -10,14 +10,18 @@ type Renderable struct { Image *ebiten.Image } +type Particle struct { + Index int + Particles []*ebiten.Image +} + +type Speed struct { + Value int +} + // only tile entities will have those type Tilish struct{} type Solid struct{} type Floor struct{} type Player struct{} type Collectible struct{} - -type Particle struct { - Index int - Particles []*ebiten.Image -} diff --git a/components/position.go b/components/position.go index 2351e86..5a108d0 100644 --- a/components/position.go +++ b/components/position.go @@ -70,8 +70,8 @@ func (position *Position) String() string { ) } -func (position *Position) Move(velocity *Velocity) { - position.Update(position.X+velocity.Data.X, position.Y+velocity.Data.Y) +func (position *Position) Move(velocity *Velocity, speed *Speed) { + position.Update(position.X+(velocity.Data.X*speed.Value), position.Y+(velocity.Data.Y*speed.Value)) } func (position *Position) Set(newpos *Position) { diff --git a/components/velocity.go b/components/velocity.go index a3c1cd7..3881d78 100644 --- a/components/velocity.go +++ b/components/velocity.go @@ -11,21 +11,19 @@ type Velocity struct { } func (velocity *Velocity) Change(direction int) { - ticks := 4 - switch direction { case East: - velocity.Data.X = ticks + velocity.Data.X = 1 velocity.Data.Y = 0 case West: - velocity.Data.X = ticks - (ticks * 2) + velocity.Data.X = -1 velocity.Data.Y = 0 case South: velocity.Data.X = 0 - velocity.Data.Y = ticks + velocity.Data.Y = 1 case North: velocity.Data.X = 0 - velocity.Data.Y = ticks - (ticks * 2) + velocity.Data.Y = -1 case Stop: velocity.Data.X = 0 velocity.Data.Y = 0 diff --git a/config/static.go b/config/static.go index 0bd3ff6..02f9851 100644 --- a/config/static.go +++ b/config/static.go @@ -7,3 +7,5 @@ const ( South North ) + +const PLAYERSPEED int = 4 diff --git a/game/game.go b/game/game.go index 9da877d..ef47297 100644 --- a/game/game.go +++ b/game/game.go @@ -13,16 +13,15 @@ type Game struct { World *ecs.World Bounds image.Rectangle ScreenWidth, ScreenHeight int - CurrentLevel int Scenes map[int]Scene + Observer *observers.GameObserver } -func NewGame(width, height, startlevel int, startscene int) *Game { +func NewGame(width, height, cellsize, startlevel int, startscene int) *Game { world := ecs.NewWorld() game := &Game{ Bounds: image.Rectangle{}, - CurrentLevel: startlevel, World: &world, ScreenWidth: width, ScreenHeight: height, @@ -31,6 +30,7 @@ func NewGame(width, height, startlevel int, startscene int) *Game { observers.NewPlayerObserver(&world) observers.NewParticleObserver(&world) + game.Observer = observers.NewGameObserver(&world, startlevel, width, height, cellsize) game.Scenes[Play] = NewLevelScene(game, startlevel) diff --git a/game/levels.go b/game/levels.go index b39d393..798a33b 100644 --- a/game/levels.go +++ b/game/levels.go @@ -6,6 +6,7 @@ import ( "openquell/assets" "openquell/components" "openquell/grid" + "openquell/observers" "openquell/systems" "strings" @@ -71,6 +72,10 @@ func (level *Level) SetupGrid(game *Game) { selector := ecs.All(posID) level.World.Batch().RemoveEntities(selector) + // get rid of any players on PlayerObserver. FIXME: remove them in grid.NewGrid()? + playerobserver := observers.GetPlayerObserver(level.World) + playerobserver.RemoveEntities() + // setup world level.GridSystem.SetGrid(grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice)) } diff --git a/game/levelscene.go b/game/levelscene.go index 4c4e4ca..3441a94 100644 --- a/game/levelscene.go +++ b/game/levelscene.go @@ -1,12 +1,14 @@ package game import ( + "fmt" "openquell/assets" "github.com/hajimehoshi/ebiten/v2" ) type LevelScene struct { + Game *Game CurrentLevel int Levels []*Level Next int @@ -16,10 +18,10 @@ type LevelScene struct { // Implements the actual playing Scene func NewLevelScene(game *Game, startlevel int) Scene { - scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play} + scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play, Game: game} scene.GenerateLevels(game) - scene.Levels[game.CurrentLevel].SetupGrid(game) + scene.Levels[scene.CurrentLevel].SetupGrid(game) return scene } @@ -40,6 +42,12 @@ func (scene *LevelScene) SetNext() int { } func (scene *LevelScene) Update() error { + if scene.CurrentLevel != scene.Game.Observer.CurrentLevel { + fmt.Printf("current: %d, next: %d\n", scene.CurrentLevel, scene.Game.Observer.CurrentLevel) + scene.CurrentLevel = scene.Game.Observer.CurrentLevel + scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game) + } + scene.Levels[scene.CurrentLevel].Update() return nil } diff --git a/grid/grid.go b/grid/grid.go index 9004f58..ff79202 100644 --- a/grid/grid.go +++ b/grid/grid.go @@ -6,6 +6,7 @@ import ( "log" "openquell/assets" "openquell/components" + "openquell/config" "openquell/observers" "github.com/mlange-42/arche/ecs" @@ -27,10 +28,11 @@ func NewGrid(world *ecs.World, // we use this to turn our tiles into iterable entities, used for // collision detection, transformation and other things - playermapper := generic.NewMap4[ + playermapper := generic.NewMap5[ components.Position, components.Velocity, components.Renderable, + components.Speed, components.Player](world) solidmapper := generic.NewMap4[ @@ -48,6 +50,7 @@ func NewGrid(world *ecs.World, var pos *components.Position var render *components.Renderable + var speed *components.Speed playerobserver := observers.GetPlayerObserver(world) @@ -60,9 +63,9 @@ func NewGrid(world *ecs.World, pos, render, _, _ = solidmapper.Get(entity) case tile.Player: entity := playermapper.New() - pos, _, render, _ = playermapper.Get(entity) + pos, _, render, speed, _ = playermapper.Get(entity) playerobserver.AddEntity(entity) - + speed.Value = config.PLAYERSPEED fmt.Printf("player start pos: %d,%d\n", point.X*tilesize, point.Y*tilesize) case tile.Collectible: entity := colmapper.New() diff --git a/main.go b/main.go index fe266ce..2d2d15d 100644 --- a/main.go +++ b/main.go @@ -8,15 +8,16 @@ import ( ) const ( - width int = 640 - height int = 480 + width int = 640 + height int = 480 + cellsize int = 32 ) func main() { ebiten.SetWindowSize(width, height) ebiten.SetWindowTitle("openquell") - g := game.NewGame(width, height, 0, game.Play) + g := game.NewGame(width, height, cellsize, 0, game.Play) err := ebiten.RunGame(g) if err != nil { diff --git a/observers/game_observer.go b/observers/game_observer.go new file mode 100644 index 0000000..8de76c1 --- /dev/null +++ b/observers/game_observer.go @@ -0,0 +1,31 @@ +package observers + +import ( + "github.com/mlange-42/arche/ecs" + "github.com/mlange-42/arche/generic" +) + +// Used for global game state +type GameObserver struct { + CurrentLevel, Width, Height, Cellsize, Score int +} + +func NewGameObserver(world *ecs.World, startlevel, width, height, cellsize int) *GameObserver { + observer := &GameObserver{ + CurrentLevel: startlevel, + Width: width, + Height: height, + Cellsize: cellsize, + } + + resmanger := generic.NewResource[GameObserver](world) + resmanger.Add(observer) + + return observer +} + +func GetGameObserver(world *ecs.World) *GameObserver { + observerID := ecs.ResourceID[GameObserver](world) + observer := world.Resources().Get(observerID).(*GameObserver) + return observer +} diff --git a/observers/player_observer.go b/observers/player_observer.go index fed55f4..a5a4577 100644 --- a/observers/player_observer.go +++ b/observers/player_observer.go @@ -50,3 +50,7 @@ func (observer *PlayerObserver) AddEntity(entity ecs.Entity) { func (observer *PlayerObserver) RemoveEntity(entity ecs.Entity) { delete(observer.Entities, entity) } + +func (observer *PlayerObserver) RemoveEntities() { + observer.Entities = make(map[ecs.Entity]int) +} diff --git a/systems/collectible_system.go b/systems/collectible_system.go index 8a303a9..75b13da 100644 --- a/systems/collectible_system.go +++ b/systems/collectible_system.go @@ -35,6 +35,12 @@ func (system *CollectibleSystem) Update() { 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() @@ -58,6 +64,14 @@ func (system *CollectibleSystem) Update() { for _, entity := range EntitiesToRemove { system.World.RemoveEntity(entity) + numcollectibles-- + } + + if numcollectibles == 0 { + // winner, winner, chicken dinner! + game := observers.GetGameObserver(system.World) + game.Score++ + game.CurrentLevel++ } } diff --git a/systems/grid_system.go b/systems/grid_system.go index 464ea5c..d78675c 100644 --- a/systems/grid_system.go +++ b/systems/grid_system.go @@ -9,7 +9,6 @@ import ( . "openquell/config" "openquell/grid" - "github.com/alecthomas/repr" "github.com/hajimehoshi/ebiten/v2" "github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/generic" @@ -119,7 +118,6 @@ func (system *GridSystem) GetSolidNeighborPosition( } newpos := components.NewPosition(neighborpos, system.Tilesize) - repr.Println(newpos) if !edge && system.Grid.Map[neighborpos].Solid { return true, newpos diff --git a/systems/player_system.go b/systems/player_system.go index 18eac83..d2f829f 100644 --- a/systems/player_system.go +++ b/systems/player_system.go @@ -12,7 +12,7 @@ import ( type PlayerSystem struct { World *ecs.World - Selector *generic.Filter4[Position, Velocity, Player, Renderable] + Selector *generic.Filter5[Position, Velocity, Player, Renderable, Speed] Particle *ParticleSystem Collectible *CollectibleSystem Grid *GridSystem @@ -20,7 +20,7 @@ type PlayerSystem struct { func NewPlayerSystem(world *ecs.World, grid *GridSystem) *PlayerSystem { system := &PlayerSystem{ - Selector: generic.NewFilter4[Position, Velocity, Player, Renderable](), + Selector: generic.NewFilter5[Position, Velocity, Player, Renderable, Speed](), Particle: NewParticleSystem(world, grid.Tilesize), Collectible: NewCollectibleSystem(world), Grid: grid, @@ -34,7 +34,7 @@ func (system PlayerSystem) Update() error { query := system.Selector.Query(system.World) for query.Next() { - playerposition, velocity, _, _ := query.Get() + playerposition, velocity, _, _, speed := query.Get() if !velocity.Moving() { switch { @@ -72,7 +72,7 @@ func (system PlayerSystem) Update() error { } } - playerposition.Move(velocity) + playerposition.Move(velocity, speed) } system.Particle.Update() @@ -87,7 +87,7 @@ func (system *PlayerSystem) Draw(screen *ebiten.Image) { query := system.Selector.Query(system.World) for query.Next() { - pos, _, _, sprite := query.Get() + pos, _, _, sprite, _ := query.Get() op.GeoM.Reset() op.GeoM.Translate(float64(pos.X), float64(pos.Y))