started implementing score system

This commit is contained in:
Thomas von Dein 2024-02-28 13:15:45 +01:00
parent 707281212a
commit ebaeb51f68
6 changed files with 58 additions and 24 deletions

View File

@ -14,7 +14,11 @@
- Add shaders for animation (player destruction etc) - 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 ## Collider Rework

View File

@ -18,7 +18,7 @@ type Game struct {
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 // fed in LevelScene.GenerateLevels()
Config *config.Config Config *config.Config
} }
@ -35,11 +35,6 @@ func NewGame(width, height, cellsize int, cfg *config.Config, startscene SceneNa
Config: cfg, 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[Welcome] = NewWelcomeScene(game)
game.Scenes[Menu] = NewMenuScene(game) game.Scenes[Menu] = NewMenuScene(game)
game.Scenes[About] = NewAboutScene(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.CurrentScene = startscene
game.Observer = observers.NewGameObserver(
&world, cfg.Startlevel, len(game.Levels), width, height, cellsize)
fmt.Println(game.World.Stats().String()) fmt.Println(game.World.Stats().String())
return game return game
@ -71,7 +69,9 @@ func (game *Game) Update() error {
slog.Debug("timer ready", "lost", gameobserver.Lost, "retry", gameobserver.Retry) slog.Debug("timer ready", "lost", gameobserver.Lost, "retry", gameobserver.Retry)
if !gameobserver.Lost { 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) game.Scenes[Nextlevel] = NewNextlevelScene(game, gameobserver.Lost)

View File

@ -3,6 +3,7 @@ package game
import ( import (
"log/slog" "log/slog"
"openquell/assets" "openquell/assets"
"openquell/observers"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
@ -27,11 +28,15 @@ func NewLevelScene(game *Game, startlevel int) Scene {
} }
func (scene *LevelScene) GenerateLevels(game *Game) { func (scene *LevelScene) GenerateLevels(game *Game) {
min := []int{}
for _, level := range assets.Levels { for _, level := range assets.Levels {
scene.Levels = append(scene.Levels, NewLevel(game, 32, &level)) 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) { func (scene *LevelScene) SetLevel(level int) {

View File

@ -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() { func (level *Level) RestoreMap() {
for point, tile := range level.BackupMapslice { for point, tile := range level.BackupMapslice {
level.Mapslice[point] = tile.Clone() level.Mapslice[point] = tile.Clone()

View File

@ -11,6 +11,10 @@ import (
"github.com/mlange-42/arche/listener" "github.com/mlange-42/arche/listener"
) )
type Score struct {
Min, Score int
}
// Used for global game state. Also stores mobile entities of the // Used for global game state. Also stores mobile entities of the
// current level. The Entities map will be reset on each level // current level. The Entities map will be reset on each level
// initialization in grid/grid.go // initialization in grid/grid.go
@ -23,6 +27,7 @@ type GameObserver struct {
Retry bool Retry bool
NextlevelText string NextlevelText string
Entities map[ecs.ID]map[ecs.Entity]int Entities map[ecs.ID]map[ecs.Entity]int
LevelScore []Score // one score per level
} }
func (observer *GameObserver) GetListenerCallback(comp ecs.ID) listener.Callback { 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{ observer := &GameObserver{
CurrentLevel: startlevel, CurrentLevel: startlevel,
StopTimer: &components.Timer{}, StopTimer: &components.Timer{},
@ -46,9 +52,6 @@ func NewGameObserver(world *ecs.World, startlevel, width, height, cellsize int)
World: world, World: world,
} }
resmanger := generic.NewResource[GameObserver](world)
resmanger.Add(observer)
playerID := ecs.ComponentID[components.Player](world) playerID := ecs.ComponentID[components.Player](world)
obstacleID := ecs.ComponentID[components.Obstacle](world) obstacleID := ecs.ComponentID[components.Obstacle](world)
particleID := ecs.ComponentID[components.Particle](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[obstacleID] = make(map[ecs.Entity]int)
observer.Entities[particleID] = 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 return observer
} }
@ -124,3 +132,27 @@ func (observer *GameObserver) RemoveEntities() {
observer.Entities[obstacleID] = make(map[ecs.Entity]int) observer.Entities[obstacleID] = make(map[ecs.Entity]int)
observer.Entities[particleID] = 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
}

View File

@ -151,16 +151,16 @@ func (system *PlayerSystem) CheckMovement(
if !velocity.Moving() { if !velocity.Moving() {
switch { switch {
case ebiten.IsKeyPressed(ebiten.KeyRight): case inpututil.IsKeyJustPressed(ebiten.KeyRight):
velocity.Change(East) velocity.Change(East)
moved = true moved = true
case ebiten.IsKeyPressed(ebiten.KeyLeft): case inpututil.IsKeyJustPressed(ebiten.KeyLeft):
velocity.Change(West) velocity.Change(West)
moved = true moved = true
case ebiten.IsKeyPressed(ebiten.KeyDown): case inpututil.IsKeyJustPressed(ebiten.KeyDown):
velocity.Change(South) velocity.Change(South)
moved = true moved = true
case ebiten.IsKeyPressed(ebiten.KeyUp): case inpututil.IsKeyJustPressed(ebiten.KeyUp):
velocity.Change(North) velocity.Change(North)
moved = true moved = true
} }