added MinMoves to lvl files, added score system in game observer
This commit is contained in:
parent
ebaeb51f68
commit
1c0f3d19d0
12
TODO.md
12
TODO.md
@ -20,6 +20,18 @@
|
|||||||
- reset counters when new level starts
|
- reset counters when new level starts
|
||||||
- display level score in level select
|
- display level score in level select
|
||||||
|
|
||||||
|
- for finding caller:
|
||||||
|
pc := make([]uintptr, 10)
|
||||||
|
n := runtime.Callers(0, pc)
|
||||||
|
pc = pc[:n]
|
||||||
|
fs := runtime.CallersFrames(pc)
|
||||||
|
source, _ := fs.Next()
|
||||||
|
source, _ = fs.Next()
|
||||||
|
source, _ = fs.Next()
|
||||||
|
|
||||||
|
slog.Debug("get observer", "minmoves", observer.LevelScore,
|
||||||
|
"file", source.File, "line", source.Line)
|
||||||
|
|
||||||
## Collider Rework
|
## Collider Rework
|
||||||
|
|
||||||
- do not use the map anymore for collision detection
|
- do not use the map anymore for collision detection
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
Description: test obstacles
|
Description: test obstacles
|
||||||
|
MinMoves: 2
|
||||||
Background: background-lila
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
Description: test obstacles
|
Description: test obstacles
|
||||||
|
MinMoves: 14
|
||||||
Background: background-lila
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
Description: find the fruit
|
Description: find the fruit
|
||||||
|
MinMoves: 7
|
||||||
Background: background-lila
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
Description: win
|
Description: win
|
||||||
|
MinMoves: 5
|
||||||
Background: background-lila
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
########
|
########
|
||||||
#v o #
|
# o <o#
|
||||||
# S<# #
|
#v S # #
|
||||||
# #### #
|
# #### #
|
||||||
|
|
||||||
|
|
||||||
# #### #
|
# #### #
|
||||||
# #
|
# #
|
||||||
#> ^#
|
# ^#
|
||||||
########
|
########
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
Description: use multiple players
|
Description: use multiple players
|
||||||
|
MinMoves: 4
|
||||||
Background: background-lila
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
Description: space
|
Description: space
|
||||||
|
MinMoves: 3
|
||||||
Background: background-lila
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
@ -204,6 +205,7 @@ type RawLevel struct {
|
|||||||
Description string
|
Description string
|
||||||
Background *ebiten.Image
|
Background *ebiten.Image
|
||||||
Data []byte
|
Data []byte
|
||||||
|
MinMoves int
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitTiles() TileRegistry {
|
func InitTiles() TileRegistry {
|
||||||
@ -272,6 +274,7 @@ func ParseRawLevel(dir string, levelfile fs.DirEntry) RawLevel {
|
|||||||
des := ""
|
des := ""
|
||||||
background := &ebiten.Image{}
|
background := &ebiten.Image{}
|
||||||
data := []byte{}
|
data := []byte{}
|
||||||
|
minmoves := 0
|
||||||
|
|
||||||
scanner := bufio.NewScanner(fd)
|
scanner := bufio.NewScanner(fd)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
@ -292,6 +295,12 @@ func ParseRawLevel(dir string, levelfile fs.DirEntry) RawLevel {
|
|||||||
case strings.Contains(line, "Description:"):
|
case strings.Contains(line, "Description:"):
|
||||||
haveit := strings.Split(line, ": ")
|
haveit := strings.Split(line, ": ")
|
||||||
des = haveit[1]
|
des = haveit[1]
|
||||||
|
case strings.Contains(line, "MinMoves:"):
|
||||||
|
haveit := strings.Split(line, ": ")
|
||||||
|
minmoves, err = strconv.Atoi(haveit[1])
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to convert MinMoves to int: %w", err)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// all other non-empty and non-equalsign lines are
|
// all other non-empty and non-equalsign lines are
|
||||||
// level definition matrix data, merge thes into data
|
// level definition matrix data, merge thes into data
|
||||||
@ -304,5 +313,6 @@ func ParseRawLevel(dir string, levelfile fs.DirEntry) RawLevel {
|
|||||||
Data: data,
|
Data: data,
|
||||||
Background: background,
|
Background: background,
|
||||||
Description: des,
|
Description: des,
|
||||||
|
MinMoves: minmoves,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
assets/sprites/background-popup-wide.png
Normal file
BIN
assets/sprites/background-popup-wide.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
@ -4,8 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
. "openquell/config"
|
. "openquell/config"
|
||||||
|
|
||||||
"log/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// physical location on screen
|
// physical location on screen
|
||||||
@ -105,13 +103,13 @@ func (tile *Position) Intersects(moving *Position, velocity *Velocity) (bool, *P
|
|||||||
object.Update(tile.X, tile.Rect.Max.Y)
|
object.Update(tile.X, tile.Rect.Max.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Debug("Intersect",
|
// slog.Debug("Intersect",
|
||||||
"velocity", velocity.Data,
|
// "velocity", velocity.Data,
|
||||||
"player", moving,
|
// "player", moving,
|
||||||
"moved player", object,
|
// "moved player", object,
|
||||||
"collision at", is,
|
// "collision at", is,
|
||||||
"tilepos", tile,
|
// "tilepos", tile,
|
||||||
)
|
// )
|
||||||
return true, object
|
return true, object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
game/game.go
34
game/game.go
@ -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 // fed in LevelScene.GenerateLevels()
|
Levels []*Level // fed in LevelScene.GenerateLevels()
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +35,9 @@ func NewGame(width, height, cellsize int, cfg *config.Config, startscene SceneNa
|
|||||||
Config: cfg,
|
Config: cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
@ -44,9 +47,6 @@ 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
|
||||||
@ -57,24 +57,18 @@ func (game *Game) GetCurrentScene() Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Update() error {
|
func (game *Game) Update() error {
|
||||||
gameobserver := observers.GetGameObserver(game.World)
|
|
||||||
|
|
||||||
// handle level ends
|
// handle level ends
|
||||||
timer := gameobserver.StopTimer
|
timer := game.Observer.StopTimer
|
||||||
|
|
||||||
if timer.IsReady() {
|
if timer.IsReady() {
|
||||||
// a level is either lost or won, we display a small popup
|
// a level is either lost or won, we display a small popup
|
||||||
// asking the user how to continue from here
|
// asking the user how to continue from here
|
||||||
timer.Reset()
|
timer.Reset()
|
||||||
|
|
||||||
slog.Debug("timer ready", "lost", gameobserver.Lost, "retry", gameobserver.Retry)
|
slog.Debug("timer ready", "lost", game.Observer.Lost, "retry", game.Observer.Retry)
|
||||||
if !gameobserver.Lost {
|
game.Observer.AddScore()
|
||||||
level := // current level?
|
|
||||||
score := ((level.MinMoves * 100) / gameobserver.Moves) / 30
|
|
||||||
gameobserver.AddScore()
|
|
||||||
}
|
|
||||||
|
|
||||||
game.Scenes[Nextlevel] = NewNextlevelScene(game, gameobserver.Lost)
|
game.Scenes[Nextlevel] = NewNextlevelScene(game)
|
||||||
game.CurrentScene = Nextlevel
|
game.CurrentScene = Nextlevel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,15 +85,15 @@ func (game *Game) Update() error {
|
|||||||
if next != game.CurrentScene {
|
if next != game.CurrentScene {
|
||||||
if next == Play && game.CurrentScene == Nextlevel {
|
if next == Play && game.CurrentScene == Nextlevel {
|
||||||
// switched from nextlevel (lost or won) popup to play (either retry or next level)
|
// switched from nextlevel (lost or won) popup to play (either retry or next level)
|
||||||
if !gameobserver.Retry {
|
if !game.Observer.Retry {
|
||||||
gameobserver.CurrentLevel++
|
game.Observer.CurrentLevel++
|
||||||
}
|
}
|
||||||
gameobserver.Retry = false
|
game.Observer.Retry = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if next == Play {
|
if next == Play {
|
||||||
// fresh setup of actual level every time we enter the play scene
|
// fresh setup of actual level every time we enter the play scene
|
||||||
game.Scenes[Play].SetLevel(gameobserver.CurrentLevel)
|
game.Scenes[Play].SetLevel(game.Observer.CurrentLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we stay on the selected scene
|
// make sure we stay on the selected scene
|
||||||
@ -108,8 +102,8 @@ func (game *Game) Update() error {
|
|||||||
// finally switch
|
// finally switch
|
||||||
game.CurrentScene = next
|
game.CurrentScene = next
|
||||||
|
|
||||||
// FIXME: add some reset function to gameobserver for these kinds of things
|
// FIXME: add some reset function to game.Observer for these kinds of things
|
||||||
gameobserver.Lost = false
|
game.Observer.Lost = false
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.Update()
|
timer.Update()
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package game
|
|||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/observers"
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
)
|
)
|
||||||
@ -34,9 +33,8 @@ func (scene *LevelScene) GenerateLevels(game *Game) {
|
|||||||
min = append(min, level.MinMoves)
|
min = append(min, level.MinMoves)
|
||||||
}
|
}
|
||||||
|
|
||||||
observer := observers.GetGameObserver(scene.Game.World)
|
scene.Game.Observer.SetupLevelScore(min)
|
||||||
observer.SetupLevelScore(min)
|
scene.Game.Levels = scene.Levels
|
||||||
//scene.Game.Levels = scene.Levels
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) SetLevel(level int) {
|
func (scene *LevelScene) SetLevel(level int) {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
@ -22,12 +23,11 @@ type NextlevelScene struct {
|
|||||||
Lost bool
|
Lost bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNextlevelScene(game *Game, lost bool) Scene {
|
func NewNextlevelScene(game *Game) Scene {
|
||||||
scene := &NextlevelScene{
|
scene := &NextlevelScene{
|
||||||
Whoami: Nextlevel,
|
Whoami: Nextlevel,
|
||||||
Game: game,
|
Game: game,
|
||||||
Next: Nextlevel,
|
Next: Nextlevel,
|
||||||
Lost: lost,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.SetupUI()
|
scene.SetupUI()
|
||||||
@ -61,7 +61,7 @@ func (scene *NextlevelScene) Update() error {
|
|||||||
func (scene *NextlevelScene) SetLevel(level int) {}
|
func (scene *NextlevelScene) SetLevel(level int) {}
|
||||||
|
|
||||||
func (scene *NextlevelScene) Draw(screen *ebiten.Image) {
|
func (scene *NextlevelScene) Draw(screen *ebiten.Image) {
|
||||||
background := assets.Assets["background-popup"]
|
background := assets.Assets["background-popup-wide"]
|
||||||
|
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.GeoM.Translate(
|
op.GeoM.Translate(
|
||||||
@ -69,33 +69,33 @@ func (scene *NextlevelScene) Draw(screen *ebiten.Image) {
|
|||||||
float64((scene.Game.ScreenHeight/2)-(background.Bounds().Dy()/2)),
|
float64((scene.Game.ScreenHeight/2)-(background.Bounds().Dy()/2)),
|
||||||
)
|
)
|
||||||
|
|
||||||
screen.DrawImage(assets.Assets["background-popup"], op)
|
screen.DrawImage(background, op)
|
||||||
|
|
||||||
scene.Ui.Draw(screen)
|
scene.Ui.Draw(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *NextlevelScene) SetupUI() {
|
func (scene *NextlevelScene) SetupUI() {
|
||||||
blue := color.RGBA{0, 255, 128, 255}
|
blue := color.RGBA{0, 255, 128, 255}
|
||||||
gameobserver := observers.GetGameObserver(scene.Game.World)
|
observer := observers.GetGameObserver(scene.Game.World)
|
||||||
|
|
||||||
rowContainer := gameui.NewRowContainer(false)
|
rowContainer := gameui.NewRowContainer(false)
|
||||||
labeltext := "Success"
|
labeltext := fmt.Sprintf("Great! (Score: %d)", observer.GetLevelScore())
|
||||||
|
|
||||||
switch scene.Lost {
|
switch observer.Lost {
|
||||||
case true:
|
case true:
|
||||||
labeltext = "Failure"
|
labeltext = "Too bad!"
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonRetry := gameui.NewMenuButton("Retry", *assets.FontRenderer.FontNormal,
|
buttonRetry := gameui.NewMenuButton("Retry", *assets.FontRenderer.FontNormal,
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
scene.SetNext(Play)
|
scene.SetNext(Play)
|
||||||
gameobserver.Retry = true
|
observer.Retry = true
|
||||||
})
|
})
|
||||||
|
|
||||||
buttonNext := gameui.NewMenuButton("Next Level", *assets.FontRenderer.FontNormal,
|
buttonNext := gameui.NewMenuButton("Next Level", *assets.FontRenderer.FontNormal,
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
scene.SetNext(Play)
|
scene.SetNext(Play)
|
||||||
gameobserver.Retry = false
|
observer.Retry = false
|
||||||
})
|
})
|
||||||
|
|
||||||
buttonAbort := gameui.NewMenuButton("Abort", *assets.FontRenderer.FontNormal,
|
buttonAbort := gameui.NewMenuButton("Abort", *assets.FontRenderer.FontNormal,
|
||||||
@ -104,7 +104,7 @@ func (scene *NextlevelScene) SetupUI() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
label := widget.NewText(
|
label := widget.NewText(
|
||||||
widget.TextOpts.Text(labeltext, *assets.FontRenderer.FontBig, blue),
|
widget.TextOpts.Text(labeltext, *assets.FontRenderer.FontNormal, blue),
|
||||||
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
package observers
|
package observers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
|
|
||||||
"log/slog"
|
|
||||||
|
|
||||||
"github.com/mlange-42/arche/ecs"
|
"github.com/mlange-42/arche/ecs"
|
||||||
"github.com/mlange-42/arche/ecs/event"
|
"github.com/mlange-42/arche/ecs/event"
|
||||||
"github.com/mlange-42/arche/generic"
|
"github.com/mlange-42/arche/generic"
|
||||||
@ -20,29 +19,29 @@ type Score struct {
|
|||||||
// initialization in grid/grid.go
|
// initialization in grid/grid.go
|
||||||
type GameObserver struct {
|
type GameObserver struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
CurrentLevel, Width int
|
CurrentLevel, Width, Moves int
|
||||||
Height, Cellsize, Score int
|
Height, Cellsize, Score int
|
||||||
StopTimer *components.Timer
|
StopTimer *components.Timer
|
||||||
Lost bool // set to true if player is struck or something, by default: win!
|
Lost bool // set to true if player is struck or something, by default: win!
|
||||||
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
|
LevelScore map[int]*Score // one score per level
|
||||||
|
Id int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (observer *GameObserver) GetListenerCallback(comp ecs.ID) listener.Callback {
|
func (observer *GameObserver) GetListenerCallback(comp ecs.ID) listener.Callback {
|
||||||
return listener.NewCallback(
|
return listener.NewCallback(
|
||||||
func(world *ecs.World, event ecs.EntityEvent) {
|
func(world *ecs.World, event ecs.EntityEvent) {
|
||||||
observer.RemoveEntity(event.Entity, comp)
|
observer.RemoveEntity(event.Entity, comp)
|
||||||
slog.Debug("player removed")
|
|
||||||
},
|
},
|
||||||
event.EntityRemoved,
|
event.EntityRemoved,
|
||||||
comp,
|
comp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGameObserver(world *ecs.World, startlevel, levelcount,
|
func NewGameObserver(
|
||||||
width, height, cellsize int) *GameObserver {
|
world *ecs.World, startlevel, width, height, cellsize int) *GameObserver {
|
||||||
observer := &GameObserver{
|
observer := &GameObserver{
|
||||||
CurrentLevel: startlevel,
|
CurrentLevel: startlevel,
|
||||||
StopTimer: &components.Timer{},
|
StopTimer: &components.Timer{},
|
||||||
@ -50,6 +49,7 @@ func NewGameObserver(world *ecs.World, startlevel, levelcount,
|
|||||||
Height: height,
|
Height: height,
|
||||||
Cellsize: cellsize,
|
Cellsize: cellsize,
|
||||||
World: world,
|
World: world,
|
||||||
|
Id: rand.Intn(1000),
|
||||||
}
|
}
|
||||||
|
|
||||||
playerID := ecs.ComponentID[components.Player](world)
|
playerID := ecs.ComponentID[components.Player](world)
|
||||||
@ -73,8 +73,6 @@ func NewGameObserver(world *ecs.World, startlevel, levelcount,
|
|||||||
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 := generic.NewResource[GameObserver](world)
|
||||||
resmanger.Add(observer)
|
resmanger.Add(observer)
|
||||||
|
|
||||||
@ -82,8 +80,9 @@ func NewGameObserver(world *ecs.World, startlevel, levelcount,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetGameObserver(world *ecs.World) *GameObserver {
|
func GetGameObserver(world *ecs.World) *GameObserver {
|
||||||
observerID := ecs.ResourceID[GameObserver](world)
|
resmanger := generic.NewResource[GameObserver](world)
|
||||||
observer := world.Resources().Get(observerID).(*GameObserver)
|
observer := resmanger.Get()
|
||||||
|
|
||||||
return observer
|
return observer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,16 +133,31 @@ func (observer *GameObserver) RemoveEntities() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (observer *GameObserver) SetupLevelScore(min []int) {
|
func (observer *GameObserver) SetupLevelScore(min []int) {
|
||||||
|
observer.LevelScore = make(map[int]*Score, len(min))
|
||||||
|
|
||||||
for level, minmoves := range min {
|
for level, minmoves := range min {
|
||||||
observer.LevelScore[level].Min = minmoves
|
observer.LevelScore[level] = &Score{Min: minmoves}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// to be called from scenes where player wins or looses
|
// set current level stats and reset counters
|
||||||
func (observer *GameObserver) AddScore(level, moves int) {
|
func (observer *GameObserver) AddScore() {
|
||||||
|
level := observer.CurrentLevel
|
||||||
|
moves := observer.Moves
|
||||||
|
|
||||||
|
if observer.Lost {
|
||||||
|
observer.LevelScore[level].Score = 0
|
||||||
|
} else {
|
||||||
observer.LevelScore[level].Score = ((observer.LevelScore[level].Min * 100) / moves) / 30
|
observer.LevelScore[level].Score = ((observer.LevelScore[level].Min * 100) / moves) / 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
observer.Moves = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (observer *GameObserver) AddMove() {
|
||||||
|
observer.Moves++
|
||||||
|
}
|
||||||
|
|
||||||
func (observer *GameObserver) GetScore() int {
|
func (observer *GameObserver) GetScore() int {
|
||||||
sum := 0
|
sum := 0
|
||||||
for _, score := range observer.LevelScore {
|
for _, score := range observer.LevelScore {
|
||||||
@ -153,6 +167,6 @@ func (observer *GameObserver) GetScore() int {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (observer *GameObserver) GetLevelScore(level int) int {
|
func (observer *GameObserver) GetLevelScore() int {
|
||||||
return observer.LevelScore[level].Score
|
return observer.LevelScore[observer.CurrentLevel].Score
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@ -1,7 +1,6 @@
|
|||||||
package systems
|
package systems
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
@ -46,7 +45,7 @@ func (system *CollectibleSystem) Update() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for query.Next() {
|
for query.Next() {
|
||||||
colposition, collectible, _ := query.Get()
|
colposition, _, _ := query.Get()
|
||||||
|
|
||||||
for _, player := range observer.GetPlayers() {
|
for _, player := range observer.GetPlayers() {
|
||||||
if !system.World.Alive(player) {
|
if !system.World.Alive(player) {
|
||||||
@ -58,7 +57,7 @@ func (system *CollectibleSystem) Update() error {
|
|||||||
|
|
||||||
ok, _ := colposition.Intersects(playerposition, playervelocity)
|
ok, _ := colposition.Intersects(playerposition, playervelocity)
|
||||||
if ok {
|
if ok {
|
||||||
slog.Debug("bumped into collectible", "collectible", collectible)
|
//slog.Debug("bumped into collectible", "collectible", collectible)
|
||||||
particlepositions = append(particlepositions, colposition)
|
particlepositions = append(particlepositions, colposition)
|
||||||
EntitiesToRemove = append(EntitiesToRemove, query.Entity())
|
EntitiesToRemove = append(EntitiesToRemove, query.Entity())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,4 +41,6 @@ func (system *HudSystem) Draw(screen *ebiten.Image) {
|
|||||||
system.Plan.Name,
|
system.Plan.Name,
|
||||||
system.Plan.Description,
|
system.Plan.Description,
|
||||||
), 10, 10)
|
), 10, 10)
|
||||||
|
|
||||||
|
ebitenutil.DebugPrintAt(screen, fmt.Sprintf("Score: %d", system.Observer.GetScore()), 10, 455)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,6 +148,7 @@ func (system *PlayerSystem) CheckMovement(
|
|||||||
player *components.Player) {
|
player *components.Player) {
|
||||||
|
|
||||||
moved := false
|
moved := false
|
||||||
|
observer := observers.GetGameObserver(system.World)
|
||||||
|
|
||||||
if !velocity.Moving() {
|
if !velocity.Moving() {
|
||||||
switch {
|
switch {
|
||||||
@ -169,6 +170,7 @@ func (system *PlayerSystem) CheckMovement(
|
|||||||
// will be reset every time the user initiates player movement
|
// will be reset every time the user initiates player movement
|
||||||
player.LoopPos.Set(position)
|
player.LoopPos.Set(position)
|
||||||
player.LoopCount = 0
|
player.LoopCount = 0
|
||||||
|
observer.AddMove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,8 +187,8 @@ func (system *PlayerSystem) CheckGridCollision(
|
|||||||
} else {
|
} else {
|
||||||
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
||||||
if ok {
|
if ok {
|
||||||
slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos",
|
// slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos",
|
||||||
tilepos.Point(), "playerpos", playerposition)
|
// tilepos.Point(), "playerpos", playerposition)
|
||||||
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
||||||
if intersects {
|
if intersects {
|
||||||
playerposition.Set(newpos)
|
playerposition.Set(newpos)
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package systems
|
package systems
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
@ -79,7 +78,7 @@ func (system *TransientSystem) Update() error {
|
|||||||
Position: *transientposition,
|
Position: *transientposition,
|
||||||
NewSprite: transient.GetNext(),
|
NewSprite: transient.GetNext(),
|
||||||
})
|
})
|
||||||
slog.Debug("done transient", "transient", transientposition)
|
//slog.Debug("done transient", "transient", transientposition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user