diff --git a/TODO.md b/TODO.md index ed29ff4..d5cc441 100644 --- a/TODO.md +++ b/TODO.md @@ -24,8 +24,9 @@ - Bug: when pushing obstacles around edges, they vanish -- Bug: Level list grows infinitely, there's now upper and lowever - limit on its size. Asked in Doscord about it +- Turn menu button in hud_system (events in level_scene!) into ebitenui button + +- On level loose, do not offer "next level" ## Collider Rework [abandoned: see branch collider-system, fails] diff --git a/assets/levels/openquell.ldtk b/assets/levels/openquell.ldtk index 9d0c847..3c41ea3 100644 --- a/assets/levels/openquell.ldtk +++ b/assets/levels/openquell.ldtk @@ -1165,19 +1165,19 @@ }, { "__identifier": "Collectible", - "__grid": [4,13], + "__grid": [4,12], "__pivot": [0,0], "__tags": [], "__tile": { "tilesetUid": 1, "x": 32, "y": 32, "w": 32, "h": 32 }, "__smartColor": "#FEAE34", - "iid": "d485afa0-d7b0-11ee-8ccf-af928d225609", + "iid": "0bca9cc0-d7b0-11ee-bb29-030d1778ceb9", "width": 32, "height": 32, "defUid": 4, - "px": [128,416], + "px": [128,384], "fieldInstances": [], "__worldX": 2016, - "__worldY": 416 + "__worldY": 384 } ] }, @@ -1243,25 +1243,34 @@ { "px": [352,256], "src": [64,0], "f": 0, "t": 2, "d": [171], "a": 1 }, { "px": [352,288], "src": [64,0], "f": 0, "t": 2, "d": [191], "a": 1 }, { "px": [352,320], "src": [64,0], "f": 0, "t": 2, "d": [211], "a": 1 }, + { "px": [64,352], "src": [0,0], "f": 0, "t": 0, "d": [222], "a": 1 }, + { "px": [64,352], "src": [64,0], "f": 0, "t": 2, "d": [222], "a": 1 }, + { "px": [96,352], "src": [0,0], "f": 0, "t": 0, "d": [223], "a": 1 }, + { "px": [96,352], "src": [64,0], "f": 0, "t": 2, "d": [223], "a": 1 }, + { "px": [128,352], "src": [0,0], "f": 0, "t": 0, "d": [224], "a": 1 }, + { "px": [128,352], "src": [64,0], "f": 0, "t": 2, "d": [224], "a": 1 }, + { "px": [160,352], "src": [0,0], "f": 0, "t": 0, "d": [225], "a": 1 }, + { "px": [160,352], "src": [64,0], "f": 0, "t": 2, "d": [225], "a": 1 }, + { "px": [192,352], "src": [0,0], "f": 0, "t": 0, "d": [226], "a": 1 }, + { "px": [192,352], "src": [64,0], "f": 0, "t": 2, "d": [226], "a": 1 }, + { "px": [224,352], "src": [0,0], "f": 0, "t": 0, "d": [227], "a": 1 }, + { "px": [224,352], "src": [64,0], "f": 0, "t": 2, "d": [227], "a": 1 }, + { "px": [256,352], "src": [0,0], "f": 0, "t": 0, "d": [228], "a": 1 }, + { "px": [256,352], "src": [64,0], "f": 0, "t": 2, "d": [228], "a": 1 }, + { "px": [288,352], "src": [0,0], "f": 0, "t": 0, "d": [229], "a": 1 }, + { "px": [288,352], "src": [64,0], "f": 0, "t": 2, "d": [229], "a": 1 }, + { "px": [320,352], "src": [0,0], "f": 0, "t": 0, "d": [230], "a": 1 }, + { "px": [320,352], "src": [64,0], "f": 0, "t": 2, "d": [230], "a": 1 }, + { "px": [352,352], "src": [0,0], "f": 0, "t": 0, "d": [231], "a": 1 }, { "px": [352,352], "src": [64,0], "f": 0, "t": 2, "d": [231], "a": 1 }, + { "px": [384,352], "src": [64,0], "f": 0, "t": 2, "d": [232], "a": 1 }, + { "px": [416,352], "src": [64,0], "f": 0, "t": 2, "d": [233], "a": 1 }, + { "px": [448,352], "src": [64,0], "f": 0, "t": 2, "d": [234], "a": 1 }, + { "px": [480,352], "src": [64,0], "f": 0, "t": 2, "d": [235], "a": 1 }, + { "px": [512,352], "src": [64,0], "f": 0, "t": 2, "d": [236], "a": 1 }, + { "px": [544,352], "src": [64,0], "f": 0, "t": 2, "d": [237], "a": 1 }, { "px": [64,384], "src": [64,0], "f": 0, "t": 2, "d": [242], "a": 1 }, - { "px": [96,384], "src": [64,0], "f": 0, "t": 2, "d": [243], "a": 1 }, - { "px": [128,384], "src": [64,0], "f": 0, "t": 2, "d": [244], "a": 1 }, - { "px": [160,384], "src": [64,0], "f": 0, "t": 2, "d": [245], "a": 1 }, - { "px": [192,384], "src": [64,0], "f": 0, "t": 2, "d": [246], "a": 1 }, - { "px": [224,384], "src": [64,0], "f": 0, "t": 2, "d": [247], "a": 1 }, - { "px": [256,384], "src": [64,0], "f": 0, "t": 2, "d": [248], "a": 1 }, - { "px": [288,384], "src": [64,0], "f": 0, "t": 2, "d": [249], "a": 1 }, - { "px": [320,384], "src": [64,0], "f": 0, "t": 2, "d": [250], "a": 1 }, - { "px": [352,384], "src": [64,0], "f": 0, "t": 2, "d": [251], "a": 1 }, - { "px": [384,384], "src": [64,0], "f": 0, "t": 2, "d": [252], "a": 1 }, - { "px": [416,384], "src": [64,0], "f": 0, "t": 2, "d": [253], "a": 1 }, - { "px": [448,384], "src": [64,0], "f": 0, "t": 2, "d": [254], "a": 1 }, - { "px": [480,384], "src": [64,0], "f": 0, "t": 2, "d": [255], "a": 1 }, - { "px": [512,384], "src": [64,0], "f": 0, "t": 2, "d": [256], "a": 1 }, - { "px": [544,384], "src": [64,0], "f": 0, "t": 2, "d": [257], "a": 1 }, - { "px": [64,416], "src": [64,0], "f": 0, "t": 2, "d": [262], "a": 1 }, - { "px": [96,416], "src": [64,0], "f": 0, "t": 2, "d": [263], "a": 1 } + { "px": [96,384], "src": [64,0], "f": 0, "t": 2, "d": [243], "a": 1 } ], "entityInstances": [] } diff --git a/assets/sprites/menu.png b/assets/sprites/menu.png new file mode 100644 index 0000000..ab0ad6c Binary files /dev/null and b/assets/sprites/menu.png differ diff --git a/config/static.go b/config/static.go index e1d579a..9aa4789 100644 --- a/config/static.go +++ b/config/static.go @@ -1,6 +1,8 @@ package config -import "time" +import ( + "time" +) const ( Stop = iota @@ -16,4 +18,8 @@ const PARTICLE_LOOPWAIT time.Duration = 250 * time.Millisecond const LEVEL_END_WAIT time.Duration = 500 * time.Millisecond const version string = "1.1.0" +const MenuRectX int = 600 +const MenuRectY int = 0 +const MenuRectCellsize int = 32 + var VERSION string // maintained by -x diff --git a/game/game.go b/game/game.go index 2d187d6..e52990d 100644 --- a/game/game.go +++ b/game/game.go @@ -82,6 +82,7 @@ func (game *Game) Update() error { } next := scene.GetNext() + if next != game.CurrentScene { if next == Play && game.CurrentScene == Nextlevel { // switched from nextlevel (lost or won) popup to play (either retry or next level) diff --git a/game/level_scene.go b/game/level_scene.go index 33b8645..0ca5ef7 100644 --- a/game/level_scene.go +++ b/game/level_scene.go @@ -1,10 +1,13 @@ package game import ( + "image" "log/slog" "openquell/assets" + "openquell/config" "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/inpututil" ) type LevelScene struct { @@ -14,6 +17,7 @@ type LevelScene struct { Next SceneName Whoami SceneName UseCache bool + MenuRect image.Rectangle } // Implements the actual playing Scene @@ -22,6 +26,9 @@ func NewLevelScene(game *Game, startlevel int) Scene { scene.GenerateLevels(game) scene.SetLevel(startlevel) + scene.MenuRect = image.Rect(config.MenuRectX, config.MenuRectY, + config.MenuRectX+config.MenuRectCellsize, + config.MenuRectY+config.MenuRectCellsize) return scene } @@ -66,8 +73,15 @@ func (scene *LevelScene) Update() error { scene.Levels[scene.CurrentLevel].Update() switch { - case ebiten.IsKeyPressed(ebiten.KeyEscape): + case inpututil.IsKeyJustPressed(ebiten.KeyEscape): scene.SetNext(Popup) + + case inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft): + // ok we're checking the menu button here, but drawing it in hud_system, + // because systems can't switch scenes + if image.Pt(ebiten.CursorPosition()).In(scene.MenuRect) { + scene.SetNext(Popup) + } } return nil diff --git a/game/popup_scene.go b/game/popup_scene.go index 3e20b0c..e84f537 100644 --- a/game/popup_scene.go +++ b/game/popup_scene.go @@ -10,6 +10,7 @@ import ( "github.com/ebitenui/ebitenui/widget" "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/inpututil" ) type PopupScene struct { @@ -50,6 +51,11 @@ func (scene *PopupScene) Clearscreen() bool { func (scene *PopupScene) Update() error { scene.Ui.Update() + + if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { + scene.SetNext(Play) + } + return nil } diff --git a/game/select_scene.go b/game/select_scene.go index d671536..118cad5 100644 --- a/game/select_scene.go +++ b/game/select_scene.go @@ -13,6 +13,7 @@ import ( "github.com/ebitenui/ebitenui/widget" "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/inpututil" ) type SelectScene struct { @@ -53,6 +54,11 @@ func (scene *SelectScene) Clearscreen() bool { func (scene *SelectScene) Update() error { scene.Ui.Update() + + if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { + scene.SetNext(Menu) + } + return nil } diff --git a/systems/hud_system.go b/systems/hud_system.go index 63ebd60..130f529 100644 --- a/systems/hud_system.go +++ b/systems/hud_system.go @@ -19,6 +19,7 @@ type HudSystem struct { Cellsize int Observer *observers.GameObserver Plan *ldtkgo.Level + MenuIcon *ebiten.Image } func NewHudSystem(world *ecs.World, plan *ldtkgo.Level) System { @@ -26,6 +27,7 @@ func NewHudSystem(world *ecs.World, plan *ldtkgo.Level) System { Observer: observers.GetGameObserver(world), World: world, Plan: plan, + MenuIcon: assets.Assets["menu"], } return system @@ -51,16 +53,20 @@ func (system *HudSystem) Draw(screen *ebiten.Image) { score := fmt.Sprintf("Score: %d", system.Observer.GetScore()) level := fmt.Sprintf("Level %d: %s", system.Plan.PropertyByIdentifier("level").AsInt(), strings.ReplaceAll(system.Plan.Identifier, "_", " ")) + des := system.Plan.PropertyByIdentifier("description").AsString() assets.FontRenderer.Renderer.SetSizePx(20) assets.FontRenderer.Renderer.SetTarget(screen) - system.Print(score, 515, 22) - des := system.Plan.PropertyByIdentifier("description").AsString() + system.Print(score, 450, 22) x := system.GetTextXCentered(des) - system.Print(system.Plan.PropertyByIdentifier("description").AsString(), x, 470) + system.Print(des, x, 470) system.Print(level, 10, 22) + + op.GeoM.Reset() + op.GeoM.Translate(600, 0) + screen.DrawImage(system.MenuIcon, op) } func (system *HudSystem) Print(text string, x, y int) {