added select and popup screens
This commit is contained in:
parent
4c9ab36fa1
commit
e12af87fb7
13
TODO.md
13
TODO.md
@ -10,3 +10,16 @@
|
|||||||
|
|
||||||
- Grid Observer:
|
- Grid Observer:
|
||||||
https://github.com/mlange-42/arche/issues/374
|
https://github.com/mlange-42/arche/issues/374
|
||||||
|
|
||||||
|
|
||||||
|
Screenshot:
|
||||||
|
|
||||||
|
Yes, since *ebiten.Image implements the standard image.Image interface
|
||||||
|
I just made a screenshot example (in Draw() function):
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyS) {
|
||||||
|
f, err := os.Create("screenshot.png")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("can't create file: ", err)
|
||||||
|
}
|
||||||
|
png.Encode(f, screen)
|
||||||
|
}
|
||||||
|
|||||||
BIN
assets/sprites/background-popup.png
Normal file
BIN
assets/sprites/background-popup.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
@ -50,6 +50,10 @@ func (scene *AboutScene) ResetNext() {
|
|||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *AboutScene) Clearscreen() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *AboutScene) Update() error {
|
func (scene *AboutScene) Update() error {
|
||||||
scene.Ui.Update()
|
scene.Ui.Update()
|
||||||
return nil
|
return nil
|
||||||
@ -66,7 +70,7 @@ func (scene *AboutScene) SetupUI() {
|
|||||||
|
|
||||||
buttonBack := gameui.NewMenuButton("Back", *assets.FontRenderer.FontNormal,
|
buttonBack := gameui.NewMenuButton("Back", *assets.FontRenderer.FontNormal,
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
scene.SetNext(Select)
|
scene.SetNext(Menu)
|
||||||
})
|
})
|
||||||
|
|
||||||
label := widget.NewText(
|
label := widget.NewText(
|
||||||
|
|||||||
15
game/game.go
15
game/game.go
@ -16,6 +16,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
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Game {
|
func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Game {
|
||||||
@ -34,9 +35,12 @@ func NewGame(width, height, cellsize, startlevel int, startscene SceneName) *Gam
|
|||||||
game.Observer = observers.NewGameObserver(&world, startlevel, width, height, cellsize)
|
game.Observer = observers.NewGameObserver(&world, startlevel, width, height, cellsize)
|
||||||
|
|
||||||
game.Scenes[Welcome] = NewWelcomeScene(game)
|
game.Scenes[Welcome] = NewWelcomeScene(game)
|
||||||
game.Scenes[Select] = NewSelectScene(game)
|
game.Scenes[Menu] = NewMenuScene(game)
|
||||||
game.Scenes[About] = NewAboutScene(game)
|
game.Scenes[About] = NewAboutScene(game)
|
||||||
|
game.Scenes[Popup] = NewPopupScene(game)
|
||||||
game.Scenes[Play] = NewLevelScene(game, startlevel)
|
game.Scenes[Play] = NewLevelScene(game, startlevel)
|
||||||
|
game.Scenes[Select] = NewSelectScene(game)
|
||||||
|
|
||||||
game.CurrentScene = startscene
|
game.CurrentScene = startscene
|
||||||
|
|
||||||
fmt.Println(game.World.Stats().String())
|
fmt.Println(game.World.Stats().String())
|
||||||
@ -50,6 +54,9 @@ func (game *Game) GetCurrentScene() Scene {
|
|||||||
|
|
||||||
func (game *Game) Update() error {
|
func (game *Game) Update() error {
|
||||||
gameobserver := observers.GetGameObserver(game.World)
|
gameobserver := observers.GetGameObserver(game.World)
|
||||||
|
|
||||||
|
// handle level ends
|
||||||
|
// FIXME: add a scene here, which asks: restart, next or abort
|
||||||
timer := gameobserver.StopTimer
|
timer := gameobserver.StopTimer
|
||||||
|
|
||||||
if timer.IsReady() {
|
if timer.IsReady() {
|
||||||
@ -61,6 +68,12 @@ func (game *Game) Update() error {
|
|||||||
scene := game.GetCurrentScene()
|
scene := game.GetCurrentScene()
|
||||||
scene.Update()
|
scene.Update()
|
||||||
|
|
||||||
|
if scene.Clearscreen() {
|
||||||
|
ebiten.SetScreenClearedEveryFrame(true)
|
||||||
|
} else {
|
||||||
|
ebiten.SetScreenClearedEveryFrame(false)
|
||||||
|
}
|
||||||
|
|
||||||
next := scene.GetNext()
|
next := scene.GetNext()
|
||||||
if next != game.CurrentScene {
|
if next != game.CurrentScene {
|
||||||
scene.ResetNext()
|
scene.ResetNext()
|
||||||
|
|||||||
@ -30,6 +30,8 @@ func (scene *LevelScene) GenerateLevels(game *Game) {
|
|||||||
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scene.Game.Levels = scene.Levels
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface methods
|
// Interface methods
|
||||||
@ -46,18 +48,28 @@ func (scene *LevelScene) ResetNext() {
|
|||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *LevelScene) Clearscreen() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) Update() error {
|
func (scene *LevelScene) Update() error {
|
||||||
|
|
||||||
|
scene.Levels[scene.CurrentLevel].Update()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ebiten.IsKeyPressed(ebiten.KeyEscape):
|
||||||
|
scene.SetNext(Popup)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *LevelScene) Draw(screen *ebiten.Image) {
|
||||||
if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
|
if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
|
||||||
slog.Debug("level", "current", scene.CurrentLevel, "next", scene.Game.Observer.CurrentLevel)
|
slog.Debug("level", "current", scene.CurrentLevel, "next", scene.Game.Observer.CurrentLevel)
|
||||||
scene.CurrentLevel = scene.Game.Observer.CurrentLevel
|
scene.CurrentLevel = scene.Game.Observer.CurrentLevel
|
||||||
scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
|
scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.Levels[scene.CurrentLevel].Update()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (scene *LevelScene) Draw(screen *ebiten.Image) {
|
|
||||||
screen.Clear()
|
screen.Clear()
|
||||||
scene.Levels[scene.CurrentLevel].Draw(screen)
|
scene.Levels[scene.CurrentLevel].Draw(screen)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,7 @@ func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
|
|||||||
Width: game.ScreenWidth,
|
Width: game.ScreenWidth,
|
||||||
Height: game.ScreenHeight,
|
Height: game.ScreenHeight,
|
||||||
Description: plan.Description,
|
Description: plan.Description,
|
||||||
|
Name: plan.Name,
|
||||||
GridSystem: gridsystem,
|
GridSystem: gridsystem,
|
||||||
Player: playersystem,
|
Player: playersystem,
|
||||||
}
|
}
|
||||||
|
|||||||
97
game/menu_scene.go
Normal file
97
game/menu_scene.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package game
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"log/slog"
|
||||||
|
"openquell/assets"
|
||||||
|
"openquell/gameui"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/ebitenui/ebitenui"
|
||||||
|
"github.com/ebitenui/ebitenui/widget"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MenuScene struct {
|
||||||
|
Game *Game
|
||||||
|
Next SceneName
|
||||||
|
Whoami SceneName
|
||||||
|
UseCache bool
|
||||||
|
Ui *ebitenui.UI
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMenuScene(game *Game) Scene {
|
||||||
|
scene := &MenuScene{Whoami: Menu, Game: game, Next: Menu}
|
||||||
|
|
||||||
|
scene.SetupUI()
|
||||||
|
|
||||||
|
return scene
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) GetNext() SceneName {
|
||||||
|
return scene.Next
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) ResetNext() {
|
||||||
|
scene.Next = scene.Whoami
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) SetNext(next SceneName) {
|
||||||
|
slog.Debug("select setnext", "next", next)
|
||||||
|
scene.Next = next
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) Clearscreen() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) Update() error {
|
||||||
|
scene.Ui.Update()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) Draw(screen *ebiten.Image) {
|
||||||
|
scene.Ui.Draw(screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *MenuScene) SetupUI() {
|
||||||
|
blue := color.RGBA{0, 255, 128, 255}
|
||||||
|
|
||||||
|
rowContainer := gameui.NewRowContainer()
|
||||||
|
|
||||||
|
buttonStartnew := gameui.NewMenuButton("Start new game", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
scene.SetNext(Play)
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonMenuLevel := gameui.NewMenuButton("Select Level", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
scene.SetNext(Select)
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonAbout := gameui.NewMenuButton("About this game", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
scene.SetNext(About)
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonQuit := gameui.NewMenuButton("Quit Game", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
os.Exit(1) // FIXME: present another scene "are you sure and/or thank you"
|
||||||
|
})
|
||||||
|
|
||||||
|
label := widget.NewText(
|
||||||
|
widget.TextOpts.Text("Menu", *assets.FontRenderer.FontBig, blue),
|
||||||
|
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
||||||
|
)
|
||||||
|
|
||||||
|
rowContainer.AddChild(label)
|
||||||
|
rowContainer.AddChild(buttonStartnew)
|
||||||
|
rowContainer.AddChild(buttonMenuLevel)
|
||||||
|
rowContainer.AddChild(buttonAbout)
|
||||||
|
rowContainer.AddChild(buttonQuit)
|
||||||
|
|
||||||
|
scene.Ui = &ebitenui.UI{
|
||||||
|
Container: rowContainer.Container(),
|
||||||
|
}
|
||||||
|
}
|
||||||
101
game/popup_scene.go
Normal file
101
game/popup_scene.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package game
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"log/slog"
|
||||||
|
"openquell/assets"
|
||||||
|
"openquell/gameui"
|
||||||
|
|
||||||
|
"github.com/ebitenui/ebitenui"
|
||||||
|
"github.com/ebitenui/ebitenui/widget"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PopupScene struct {
|
||||||
|
Game *Game
|
||||||
|
Next SceneName
|
||||||
|
Whoami SceneName
|
||||||
|
UseCache bool
|
||||||
|
Ui *ebitenui.UI
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPopupScene(game *Game) Scene {
|
||||||
|
scene := &PopupScene{Whoami: Popup, Game: game, Next: Popup}
|
||||||
|
|
||||||
|
scene.SetupUI()
|
||||||
|
|
||||||
|
return scene
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) GetNext() SceneName {
|
||||||
|
return scene.Next
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) ResetNext() {
|
||||||
|
scene.Next = scene.Whoami
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) SetNext(next SceneName) {
|
||||||
|
slog.Debug("select setnext", "next", next)
|
||||||
|
scene.Next = next
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) Clearscreen() bool {
|
||||||
|
// both level_scene AND the popup must not clear to get an actual popup
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) Update() error {
|
||||||
|
scene.Ui.Update()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) Draw(screen *ebiten.Image) {
|
||||||
|
background := assets.Assets["background-popup"]
|
||||||
|
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
op.GeoM.Translate(
|
||||||
|
float64((scene.Game.ScreenWidth/2)-(background.Bounds().Dx()/2)),
|
||||||
|
float64((scene.Game.ScreenHeight/2)-(background.Bounds().Dy()/2)),
|
||||||
|
)
|
||||||
|
|
||||||
|
screen.DrawImage(assets.Assets["background-popup"], op)
|
||||||
|
|
||||||
|
scene.Ui.Draw(screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *PopupScene) SetupUI() {
|
||||||
|
blue := color.RGBA{0, 255, 128, 255}
|
||||||
|
|
||||||
|
rowContainer := gameui.NewRowContainer(false)
|
||||||
|
|
||||||
|
buttonContinue := gameui.NewMenuButton("Continue", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
scene.SetNext(Play)
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonAbort := gameui.NewMenuButton("Abort", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
scene.SetNext(Menu)
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonOptions := gameui.NewMenuButton("Options", *assets.FontRenderer.FontNormal,
|
||||||
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
|
scene.SetNext(Settings)
|
||||||
|
})
|
||||||
|
|
||||||
|
label := widget.NewText(
|
||||||
|
widget.TextOpts.Text("Menu", *assets.FontRenderer.FontBig, blue),
|
||||||
|
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
||||||
|
)
|
||||||
|
|
||||||
|
rowContainer.AddChild(label)
|
||||||
|
rowContainer.AddChild(buttonContinue)
|
||||||
|
rowContainer.AddChild(buttonAbort)
|
||||||
|
rowContainer.AddChild(buttonOptions)
|
||||||
|
|
||||||
|
scene.Ui = &ebitenui.UI{
|
||||||
|
Container: rowContainer.Container(),
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,15 +5,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Welcome = iota
|
Welcome = iota // startup
|
||||||
Select
|
Menu // main top level menu
|
||||||
Play
|
Play // actual playing happens here
|
||||||
About
|
About // about the game
|
||||||
Settings
|
Settings // options
|
||||||
|
Popup // in-game options
|
||||||
|
Select // select which level to play
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wrapper for different screens to be shown, as Welcome, Options,
|
// Wrapper for different screens to be shown, as Welcome, Options,
|
||||||
// About, Select Level and of course the actual Levels.
|
// About, Menu Level and of course the actual Levels.
|
||||||
// Scenes are responsible for screen clearing! That way a scene is able
|
// Scenes are responsible for screen clearing! That way a scene is able
|
||||||
// to render its content onto the running level, e.g. the options scene
|
// to render its content onto the running level, e.g. the options scene
|
||||||
// etc.
|
// etc.
|
||||||
@ -21,6 +23,7 @@ type Scene interface {
|
|||||||
SetNext(SceneName)
|
SetNext(SceneName)
|
||||||
GetNext() SceneName
|
GetNext() SceneName
|
||||||
ResetNext()
|
ResetNext()
|
||||||
|
Clearscreen() bool
|
||||||
Update() error
|
Update() error
|
||||||
Draw(screen *ebiten.Image)
|
Draw(screen *ebiten.Image)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,26 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"log/slog"
|
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/gameui"
|
"openquell/gameui"
|
||||||
"os"
|
"openquell/observers"
|
||||||
|
|
||||||
"github.com/ebitenui/ebitenui"
|
"github.com/ebitenui/ebitenui"
|
||||||
|
"github.com/ebitenui/ebitenui/image"
|
||||||
"github.com/ebitenui/ebitenui/widget"
|
"github.com/ebitenui/ebitenui/widget"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SelectScene struct {
|
type SelectScene struct {
|
||||||
Game *Game
|
Game *Game
|
||||||
Next SceneName
|
Next SceneName
|
||||||
Whoami SceneName
|
Whoami SceneName
|
||||||
UseCache bool
|
UseCache bool
|
||||||
Ui *ebitenui.UI
|
Ui *ebitenui.UI
|
||||||
|
SelectedLevel int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSelectScene(game *Game) Scene {
|
func NewSelectScene(game *Game) Scene {
|
||||||
@ -38,10 +40,14 @@ func (scene *SelectScene) ResetNext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (scene *SelectScene) SetNext(next SceneName) {
|
func (scene *SelectScene) SetNext(next SceneName) {
|
||||||
slog.Debug("select setnext", "next", next)
|
|
||||||
scene.Next = next
|
scene.Next = next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *SelectScene) Clearscreen() bool {
|
||||||
|
// both level_scene AND the popup must not clear to get an actual popup
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *SelectScene) Update() error {
|
func (scene *SelectScene) Update() error {
|
||||||
scene.Ui.Update()
|
scene.Ui.Update()
|
||||||
return nil
|
return nil
|
||||||
@ -51,41 +57,101 @@ func (scene *SelectScene) Draw(screen *ebiten.Image) {
|
|||||||
scene.Ui.Draw(screen)
|
scene.Ui.Draw(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LevelEntry struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *SelectScene) SetupUI() {
|
func (scene *SelectScene) SetupUI() {
|
||||||
|
gameobserver := observers.GetGameObserver(scene.Game.World)
|
||||||
|
|
||||||
blue := color.RGBA{0, 255, 128, 255}
|
blue := color.RGBA{0, 255, 128, 255}
|
||||||
|
|
||||||
rowContainer := gameui.NewRowContainer()
|
rowContainer := gameui.NewRowContainer()
|
||||||
|
|
||||||
buttonStartnew := gameui.NewMenuButton("Start new game", *assets.FontRenderer.FontNormal,
|
label := widget.NewText(
|
||||||
|
widget.TextOpts.Text("Select Level", *assets.FontRenderer.FontBig, blue),
|
||||||
|
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
||||||
|
)
|
||||||
|
|
||||||
|
levels := make([]any, 0, len(scene.Game.Levels))
|
||||||
|
for id := 0; id < len(scene.Game.Levels); id++ {
|
||||||
|
levels = append(levels, LevelEntry{Id: id, Name: scene.Game.Levels[id].Name})
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonImage, err := gameui.LoadButtonImage()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
list := widget.NewList(
|
||||||
|
// Set how wide the list should be
|
||||||
|
widget.ListOpts.ContainerOpts(widget.ContainerOpts.WidgetOpts(
|
||||||
|
widget.WidgetOpts.MinSize(150, 0),
|
||||||
|
widget.WidgetOpts.LayoutData(widget.AnchorLayoutData{
|
||||||
|
HorizontalPosition: widget.AnchorLayoutPositionCenter,
|
||||||
|
VerticalPosition: widget.AnchorLayoutPositionEnd,
|
||||||
|
StretchVertical: true,
|
||||||
|
}),
|
||||||
|
)),
|
||||||
|
// Set the entries in the list
|
||||||
|
widget.ListOpts.Entries(levels),
|
||||||
|
widget.ListOpts.ScrollContainerOpts(
|
||||||
|
// Set the background images/color for the list
|
||||||
|
widget.ScrollContainerOpts.Image(&widget.ScrollContainerImage{
|
||||||
|
Idle: image.NewNineSliceColor(color.NRGBA{100, 100, 100, 255}),
|
||||||
|
Disabled: image.NewNineSliceColor(color.NRGBA{100, 100, 100, 255}),
|
||||||
|
Mask: image.NewNineSliceColor(color.NRGBA{100, 100, 100, 255}),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
widget.ListOpts.SliderOpts(
|
||||||
|
// Set the background images/color for the background of the slider track
|
||||||
|
widget.SliderOpts.Images(&widget.SliderTrackImage{
|
||||||
|
Idle: image.NewNineSliceColor(color.NRGBA{100, 100, 100, 255}),
|
||||||
|
Hover: image.NewNineSliceColor(color.NRGBA{100, 100, 100, 255}),
|
||||||
|
}, buttonImage),
|
||||||
|
widget.SliderOpts.MinHandleSize(5),
|
||||||
|
// Set how wide the track should be
|
||||||
|
widget.SliderOpts.TrackPadding(widget.NewInsetsSimple(2))),
|
||||||
|
// Hide the horizontal slider
|
||||||
|
widget.ListOpts.HideHorizontalSlider(),
|
||||||
|
// Set the font for the list options
|
||||||
|
widget.ListOpts.EntryFontFace(*assets.FontRenderer.FontNormal),
|
||||||
|
// Set the colors for the list
|
||||||
|
widget.ListOpts.EntryColor(&widget.ListEntryColor{
|
||||||
|
Selected: color.NRGBA{0, 255, 0, 255}, // Foreground color for the unfocused selected entry
|
||||||
|
Unselected: color.NRGBA{254, 255, 255, 255}, // Foreground color for the unfocused unselected entry
|
||||||
|
SelectedBackground: color.NRGBA{R: 130, G: 130, B: 200, A: 255}, // Background color for the unfocused selected entry
|
||||||
|
SelectedFocusedBackground: color.NRGBA{R: 130, G: 130, B: 170, A: 255}, // Background color for the focused selected entry
|
||||||
|
FocusedBackground: color.NRGBA{R: 170, G: 170, B: 180, A: 255}, // Background color for the focused unselected entry
|
||||||
|
DisabledUnselected: color.NRGBA{100, 100, 100, 255}, // Foreground color for the disabled unselected entry
|
||||||
|
DisabledSelected: color.NRGBA{100, 100, 100, 255}, // Foreground color for the disabled selected entry
|
||||||
|
DisabledSelectedBackground: color.NRGBA{100, 100, 100, 255}, // Background color for the disabled selected entry
|
||||||
|
}),
|
||||||
|
// This required function returns the string displayed in the list
|
||||||
|
widget.ListOpts.EntryLabelFunc(func(e interface{}) string {
|
||||||
|
return e.(LevelEntry).Name
|
||||||
|
}),
|
||||||
|
// Padding for each entry
|
||||||
|
widget.ListOpts.EntryTextPadding(widget.NewInsetsSimple(5)),
|
||||||
|
// Text position for each entry
|
||||||
|
widget.ListOpts.EntryTextPosition(widget.TextPositionStart, widget.TextPositionCenter),
|
||||||
|
// This handler defines what function to run when a list item is selected.
|
||||||
|
widget.ListOpts.EntrySelectedHandler(func(args *widget.ListEntrySelectedEventArgs) {
|
||||||
|
entry := args.Entry.(LevelEntry)
|
||||||
|
fmt.Println("Entry Selected: ", entry)
|
||||||
|
gameobserver.CurrentLevel = entry.Id
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
buttonPlay := gameui.NewMenuButton("Play selected level", *assets.FontRenderer.FontNormal,
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
scene.SetNext(Play)
|
scene.SetNext(Play)
|
||||||
})
|
})
|
||||||
|
|
||||||
buttonSelectLevel := gameui.NewMenuButton("Select Level", *assets.FontRenderer.FontNormal,
|
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
|
||||||
scene.SetNext(Select)
|
|
||||||
})
|
|
||||||
|
|
||||||
buttonAbout := gameui.NewMenuButton("About this game", *assets.FontRenderer.FontNormal,
|
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
|
||||||
scene.SetNext(About)
|
|
||||||
})
|
|
||||||
|
|
||||||
buttonQuit := gameui.NewMenuButton("Quit Game", *assets.FontRenderer.FontNormal,
|
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
|
||||||
os.Exit(1) // FIXME: present another scene "are you sure and/or thank you"
|
|
||||||
})
|
|
||||||
|
|
||||||
label := widget.NewText(
|
|
||||||
widget.TextOpts.Text("Menu", *assets.FontRenderer.FontBig, blue),
|
|
||||||
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
|
||||||
)
|
|
||||||
|
|
||||||
rowContainer.AddChild(label)
|
rowContainer.AddChild(label)
|
||||||
rowContainer.AddChild(buttonStartnew)
|
rowContainer.AddChild(list)
|
||||||
rowContainer.AddChild(buttonSelectLevel)
|
rowContainer.AddChild(buttonPlay)
|
||||||
rowContainer.AddChild(buttonAbout)
|
|
||||||
rowContainer.AddChild(buttonQuit)
|
|
||||||
|
|
||||||
scene.Ui = &ebitenui.UI{
|
scene.Ui = &ebitenui.UI{
|
||||||
Container: rowContainer.Container(),
|
Container: rowContainer.Container(),
|
||||||
|
|||||||
@ -36,10 +36,14 @@ func (scene *WelcomeScene) ResetNext() {
|
|||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *WelcomeScene) Clearscreen() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *WelcomeScene) Update() error {
|
func (scene *WelcomeScene) Update() error {
|
||||||
switch {
|
switch {
|
||||||
case ebiten.IsKeyPressed(ebiten.KeyEnter):
|
case ebiten.IsKeyPressed(ebiten.KeyEnter):
|
||||||
scene.SetNext(Select)
|
scene.SetNext(Menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.Ui.Update()
|
scene.Ui.Update()
|
||||||
@ -60,7 +64,7 @@ func (scene *WelcomeScene) SetupUI() {
|
|||||||
|
|
||||||
button := gameui.NewMenuButton("Start", *assets.FontRenderer.FontNormal,
|
button := gameui.NewMenuButton("Start", *assets.FontRenderer.FontNormal,
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
scene.SetNext(Select)
|
scene.SetNext(Menu)
|
||||||
})
|
})
|
||||||
|
|
||||||
label := widget.NewText(
|
label := widget.NewText(
|
||||||
|
|||||||
@ -52,14 +52,24 @@ func (container *RowContainer) Container() *widget.Container {
|
|||||||
return container.Root
|
return container.Root
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRowContainer() *RowContainer {
|
// set arg to false if no background needed
|
||||||
|
func NewRowContainer(setbackground ...bool) *RowContainer {
|
||||||
background := assets.Assets["background-lila"]
|
background := assets.Assets["background-lila"]
|
||||||
|
var uiContainer *widget.Container
|
||||||
|
|
||||||
uiContainer := widget.NewContainer(
|
if len(setbackground) > 0 {
|
||||||
widget.ContainerOpts.BackgroundImage(
|
// false
|
||||||
image.NewNineSlice(background, [3]int{0, 1, 639}, [3]int{0, 1, 479})),
|
uiContainer = widget.NewContainer(
|
||||||
widget.ContainerOpts.Layout(widget.NewAnchorLayout()),
|
widget.ContainerOpts.Layout(widget.NewAnchorLayout()),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
// default: true
|
||||||
|
uiContainer = widget.NewContainer(
|
||||||
|
widget.ContainerOpts.BackgroundImage(
|
||||||
|
image.NewNineSlice(background, [3]int{0, 1, 639}, [3]int{0, 1, 479})),
|
||||||
|
widget.ContainerOpts.Layout(widget.NewAnchorLayout()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
rowContainer := widget.NewContainer(
|
rowContainer := widget.NewContainer(
|
||||||
widget.ContainerOpts.WidgetOpts(
|
widget.ContainerOpts.WidgetOpts(
|
||||||
|
|||||||
BIN
src/background-popup.xcf
Normal file
BIN
src/background-popup.xcf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user