From ebaeb51f686d7f99cf6b64d4ed905cba9aada259 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Wed, 28 Feb 2024 13:15:45 +0100 Subject: [PATCH] started implementing score system --- TODO.md | 6 +++++- game/game.go | 14 ++++++------- game/level_scene.go | 7 ++++++- game/levels.go | 7 ------- observers/game_observer.go | 40 ++++++++++++++++++++++++++++++++++---- systems/player_system.go | 8 ++++---- 6 files changed, 58 insertions(+), 24 deletions(-) diff --git a/TODO.md b/TODO.md index 7aafb9f..dee2d07 100644 --- a/TODO.md +++ b/TODO.md @@ -14,7 +14,11 @@ - Add shaders for animation (player destruction etc) - +- Add Score system, see game_observer.go bottom. + - add MinMoves to each level (one line) [min moves to win] + - count moves in player_scene.Update (put to observer as well?) + - reset counters when new level starts + - display level score in level select ## Collider Rework diff --git a/game/game.go b/game/game.go index 473f9b2..f721bc9 100644 --- a/game/game.go +++ b/game/game.go @@ -18,7 +18,7 @@ type Game struct { Scenes map[SceneName]Scene CurrentScene SceneName Observer *observers.GameObserver - Levels []*Level // needed to feed select_scene + //Levels []*Level // fed in LevelScene.GenerateLevels() Config *config.Config } @@ -35,11 +35,6 @@ func NewGame(width, height, cellsize int, cfg *config.Config, startscene SceneNa Config: cfg, } - // observers.NewPlayerObserver(&world) - // observers.NewParticleObserver(&world) - // observers.NewObstacleObserver(&world) - game.Observer = observers.NewGameObserver(&world, cfg.Startlevel, width, height, cellsize) - game.Scenes[Welcome] = NewWelcomeScene(game) game.Scenes[Menu] = NewMenuScene(game) game.Scenes[About] = NewAboutScene(game) @@ -49,6 +44,9 @@ func NewGame(width, height, cellsize int, cfg *config.Config, startscene SceneNa game.CurrentScene = startscene + game.Observer = observers.NewGameObserver( + &world, cfg.Startlevel, len(game.Levels), width, height, cellsize) + fmt.Println(game.World.Stats().String()) return game @@ -71,7 +69,9 @@ func (game *Game) Update() error { slog.Debug("timer ready", "lost", gameobserver.Lost, "retry", gameobserver.Retry) if !gameobserver.Lost { - gameobserver.Score++ // FIXME: use level.Score(), see TODO + level := // current level? + score := ((level.MinMoves * 100) / gameobserver.Moves) / 30 + gameobserver.AddScore() } game.Scenes[Nextlevel] = NewNextlevelScene(game, gameobserver.Lost) diff --git a/game/level_scene.go b/game/level_scene.go index bb93528..1c8b7d8 100644 --- a/game/level_scene.go +++ b/game/level_scene.go @@ -3,6 +3,7 @@ package game import ( "log/slog" "openquell/assets" + "openquell/observers" "github.com/hajimehoshi/ebiten/v2" ) @@ -27,11 +28,15 @@ func NewLevelScene(game *Game, startlevel int) Scene { } func (scene *LevelScene) GenerateLevels(game *Game) { + min := []int{} for _, level := range assets.Levels { scene.Levels = append(scene.Levels, NewLevel(game, 32, &level)) + min = append(min, level.MinMoves) } - scene.Game.Levels = scene.Levels + observer := observers.GetGameObserver(scene.Game.World) + observer.SetupLevelScore(min) + //scene.Game.Levels = scene.Levels } func (scene *LevelScene) SetLevel(level int) { diff --git a/game/levels.go b/game/levels.go index 12fd3e4..ba4e3c0 100644 --- a/game/levels.go +++ b/game/levels.go @@ -82,13 +82,6 @@ func (level *Level) Draw(screen *ebiten.Image) { } } -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) RestoreMap() { for point, tile := range level.BackupMapslice { level.Mapslice[point] = tile.Clone() diff --git a/observers/game_observer.go b/observers/game_observer.go index 1e0568a..7fbc8fa 100644 --- a/observers/game_observer.go +++ b/observers/game_observer.go @@ -11,6 +11,10 @@ import ( "github.com/mlange-42/arche/listener" ) +type Score struct { + Min, Score int +} + // Used for global game state. Also stores mobile entities of the // current level. The Entities map will be reset on each level // initialization in grid/grid.go @@ -23,6 +27,7 @@ type GameObserver struct { Retry bool NextlevelText string Entities map[ecs.ID]map[ecs.Entity]int + LevelScore []Score // one score per level } func (observer *GameObserver) GetListenerCallback(comp ecs.ID) listener.Callback { @@ -36,7 +41,8 @@ func (observer *GameObserver) GetListenerCallback(comp ecs.ID) listener.Callback ) } -func NewGameObserver(world *ecs.World, startlevel, width, height, cellsize int) *GameObserver { +func NewGameObserver(world *ecs.World, startlevel, levelcount, + width, height, cellsize int) *GameObserver { observer := &GameObserver{ CurrentLevel: startlevel, StopTimer: &components.Timer{}, @@ -46,9 +52,6 @@ func NewGameObserver(world *ecs.World, startlevel, width, height, cellsize int) World: world, } - resmanger := generic.NewResource[GameObserver](world) - resmanger.Add(observer) - playerID := ecs.ComponentID[components.Player](world) obstacleID := ecs.ComponentID[components.Obstacle](world) particleID := ecs.ComponentID[components.Particle](world) @@ -70,6 +73,11 @@ func NewGameObserver(world *ecs.World, startlevel, width, height, cellsize int) observer.Entities[obstacleID] = make(map[ecs.Entity]int) observer.Entities[particleID] = make(map[ecs.Entity]int) + observer.LevelScore = make([]Score, levelcount) + + resmanger := generic.NewResource[GameObserver](world) + resmanger.Add(observer) + return observer } @@ -124,3 +132,27 @@ func (observer *GameObserver) RemoveEntities() { observer.Entities[obstacleID] = make(map[ecs.Entity]int) observer.Entities[particleID] = make(map[ecs.Entity]int) } + +func (observer *GameObserver) SetupLevelScore(min []int) { + for level, minmoves := range min { + observer.LevelScore[level].Min = minmoves + } +} + +// to be called from scenes where player wins or looses +func (observer *GameObserver) AddScore(level, moves int) { + observer.LevelScore[level].Score = ((observer.LevelScore[level].Min * 100) / moves) / 30 +} + +func (observer *GameObserver) GetScore() int { + sum := 0 + for _, score := range observer.LevelScore { + sum += score.Score + } + + return sum +} + +func (observer *GameObserver) GetLevelScore(level int) int { + return observer.LevelScore[level].Score +} diff --git a/systems/player_system.go b/systems/player_system.go index d43c12e..f724152 100644 --- a/systems/player_system.go +++ b/systems/player_system.go @@ -151,16 +151,16 @@ func (system *PlayerSystem) CheckMovement( if !velocity.Moving() { switch { - case ebiten.IsKeyPressed(ebiten.KeyRight): + case inpututil.IsKeyJustPressed(ebiten.KeyRight): velocity.Change(East) moved = true - case ebiten.IsKeyPressed(ebiten.KeyLeft): + case inpututil.IsKeyJustPressed(ebiten.KeyLeft): velocity.Change(West) moved = true - case ebiten.IsKeyPressed(ebiten.KeyDown): + case inpututil.IsKeyJustPressed(ebiten.KeyDown): velocity.Change(South) moved = true - case ebiten.IsKeyPressed(ebiten.KeyUp): + case inpututil.IsKeyJustPressed(ebiten.KeyUp): velocity.Change(North) moved = true }