2024-02-16 18:23:19 +01:00
|
|
|
package game
|
|
|
|
|
|
|
|
|
|
import (
|
2024-02-18 18:19:34 +01:00
|
|
|
"fmt"
|
2024-02-16 18:23:19 +01:00
|
|
|
"image/color"
|
2024-02-21 12:50:17 +01:00
|
|
|
"log/slog"
|
2024-02-16 18:23:19 +01:00
|
|
|
"openquell/assets"
|
2024-02-18 12:32:18 +01:00
|
|
|
"openquell/gameui"
|
2024-02-18 18:19:34 +01:00
|
|
|
"openquell/observers"
|
2024-02-16 18:23:19 +01:00
|
|
|
|
|
|
|
|
"github.com/ebitenui/ebitenui"
|
2024-02-18 18:19:34 +01:00
|
|
|
"github.com/ebitenui/ebitenui/image"
|
2024-02-16 18:23:19 +01:00
|
|
|
"github.com/ebitenui/ebitenui/widget"
|
|
|
|
|
|
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
2024-03-18 19:34:57 +01:00
|
|
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
2024-02-16 18:23:19 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type SelectScene struct {
|
2024-02-18 18:19:34 +01:00
|
|
|
Game *Game
|
|
|
|
|
Next SceneName
|
|
|
|
|
Whoami SceneName
|
|
|
|
|
UseCache bool
|
|
|
|
|
Ui *ebitenui.UI
|
|
|
|
|
SelectedLevel int
|
2024-02-16 18:23:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewSelectScene(game *Game) Scene {
|
|
|
|
|
scene := &SelectScene{Whoami: Select, Game: game, Next: Select}
|
|
|
|
|
|
|
|
|
|
scene.SetupUI()
|
|
|
|
|
|
|
|
|
|
return scene
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 12:50:17 +01:00
|
|
|
func (scene *SelectScene) SetLevel(level int) {}
|
|
|
|
|
|
2024-02-16 18:23:19 +01:00
|
|
|
func (scene *SelectScene) GetNext() SceneName {
|
|
|
|
|
return scene.Next
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-18 12:32:18 +01:00
|
|
|
func (scene *SelectScene) ResetNext() {
|
|
|
|
|
scene.Next = scene.Whoami
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 18:23:19 +01:00
|
|
|
func (scene *SelectScene) SetNext(next SceneName) {
|
|
|
|
|
scene.Next = next
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-18 18:19:34 +01:00
|
|
|
func (scene *SelectScene) Clearscreen() bool {
|
|
|
|
|
// both level_scene AND the popup must not clear to get an actual popup
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 18:23:19 +01:00
|
|
|
func (scene *SelectScene) Update() error {
|
|
|
|
|
scene.Ui.Update()
|
2024-03-18 19:34:57 +01:00
|
|
|
|
|
|
|
|
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
|
|
|
|
|
scene.SetNext(Menu)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 18:23:19 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (scene *SelectScene) Draw(screen *ebiten.Image) {
|
|
|
|
|
scene.Ui.Draw(screen)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-18 18:19:34 +01:00
|
|
|
type LevelEntry struct {
|
2024-03-21 09:38:47 +01:00
|
|
|
Id int
|
|
|
|
|
Number int
|
|
|
|
|
Name string
|
2024-02-18 18:19:34 +01:00
|
|
|
}
|
|
|
|
|
|
2024-02-16 18:23:19 +01:00
|
|
|
func (scene *SelectScene) SetupUI() {
|
2024-02-18 18:19:34 +01:00
|
|
|
gameobserver := observers.GetGameObserver(scene.Game.World)
|
|
|
|
|
|
2024-02-18 12:32:18 +01:00
|
|
|
blue := color.RGBA{0, 255, 128, 255}
|
2024-02-16 18:23:19 +01:00
|
|
|
|
2024-02-18 12:32:18 +01:00
|
|
|
rowContainer := gameui.NewRowContainer()
|
2024-02-16 18:23:19 +01:00
|
|
|
|
2024-02-18 18:19:34 +01:00
|
|
|
label := widget.NewText(
|
|
|
|
|
widget.TextOpts.Text("Select Level", *assets.FontRenderer.FontBig, blue),
|
|
|
|
|
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
|
|
|
|
|
)
|
2024-02-18 12:32:18 +01:00
|
|
|
|
2024-02-18 18:19:34 +01:00
|
|
|
levels := make([]any, 0, len(scene.Game.Levels))
|
|
|
|
|
for id := 0; id < len(scene.Game.Levels); id++ {
|
2024-03-21 09:38:47 +01:00
|
|
|
levels = append(levels, LevelEntry{Id: id, Number: scene.Game.Levels[id].Number, Name: scene.Game.Levels[id].Name})
|
2024-02-18 18:19:34 +01:00
|
|
|
}
|
2024-02-18 12:32:18 +01:00
|
|
|
|
2024-02-21 12:50:17 +01:00
|
|
|
slog.Debug("levels", "levels", levels)
|
2024-02-18 18:19:34 +01:00
|
|
|
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),
|
2024-03-16 23:11:22 +01:00
|
|
|
widget.WidgetOpts.LayoutData(widget.RowLayoutData{
|
|
|
|
|
Position: widget.RowLayoutPositionCenter,
|
|
|
|
|
Stretch: true,
|
2024-03-17 16:29:56 +01:00
|
|
|
MaxHeight: 200,
|
2024-02-18 18:19:34 +01:00
|
|
|
}),
|
|
|
|
|
)),
|
|
|
|
|
// 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{
|
2024-03-16 18:49:28 +01:00
|
|
|
Selected: color.NRGBA{0, 255, 0, 255},
|
|
|
|
|
Unselected: color.NRGBA{254, 255, 255, 255},
|
|
|
|
|
SelectedBackground: color.NRGBA{R: 130, G: 130, B: 200, A: 255},
|
|
|
|
|
SelectedFocusedBackground: color.NRGBA{R: 130, G: 130, B: 170, A: 255},
|
|
|
|
|
FocusedBackground: color.NRGBA{R: 170, G: 170, B: 180, A: 255},
|
|
|
|
|
DisabledUnselected: color.NRGBA{100, 100, 100, 255},
|
|
|
|
|
DisabledSelected: color.NRGBA{100, 100, 100, 255},
|
|
|
|
|
DisabledSelectedBackground: color.NRGBA{100, 100, 100, 255},
|
2024-02-18 18:19:34 +01:00
|
|
|
}),
|
|
|
|
|
// This required function returns the string displayed in the list
|
|
|
|
|
widget.ListOpts.EntryLabelFunc(func(e interface{}) string {
|
2024-03-21 09:38:47 +01:00
|
|
|
return fmt.Sprintf("%02d %s", e.(LevelEntry).Number, e.(LevelEntry).Name)
|
2024-02-18 18:19:34 +01:00
|
|
|
}),
|
|
|
|
|
// 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
|
|
|
|
|
}),
|
|
|
|
|
)
|
2024-02-18 12:32:18 +01:00
|
|
|
|
2024-03-17 16:29:56 +01:00
|
|
|
buttonContainer := widget.NewContainer(
|
|
|
|
|
widget.ContainerOpts.Layout(widget.NewGridLayout(
|
|
|
|
|
widget.GridLayoutOpts.Columns(2),
|
|
|
|
|
widget.GridLayoutOpts.Padding(widget.NewInsetsSimple(30)),
|
|
|
|
|
widget.GridLayoutOpts.Spacing(20, 10),
|
|
|
|
|
widget.GridLayoutOpts.Stretch([]bool{true, false}, []bool{false, true}),
|
|
|
|
|
)),
|
|
|
|
|
)
|
|
|
|
|
|
2024-02-18 18:19:34 +01:00
|
|
|
buttonPlay := gameui.NewMenuButton("Play selected level", *assets.FontRenderer.FontNormal,
|
2024-02-18 12:32:18 +01:00
|
|
|
func(args *widget.ButtonClickedEventArgs) {
|
2024-02-18 18:19:34 +01:00
|
|
|
scene.SetNext(Play)
|
2024-02-18 12:32:18 +01:00
|
|
|
})
|
|
|
|
|
|
2024-03-17 16:29:56 +01:00
|
|
|
buttonAbort := gameui.NewMenuButton("Back", *assets.FontRenderer.FontNormal,
|
|
|
|
|
func(args *widget.ButtonClickedEventArgs) {
|
|
|
|
|
scene.SetNext(Menu)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
buttonContainer.AddChild(buttonPlay)
|
|
|
|
|
buttonContainer.AddChild(buttonAbort)
|
|
|
|
|
|
2024-02-18 12:32:18 +01:00
|
|
|
rowContainer.AddChild(label)
|
2024-02-18 18:19:34 +01:00
|
|
|
rowContainer.AddChild(list)
|
2024-03-17 16:29:56 +01:00
|
|
|
rowContainer.AddChild(buttonContainer)
|
2024-02-16 18:23:19 +01:00
|
|
|
|
|
|
|
|
scene.Ui = &ebitenui.UI{
|
2024-02-18 12:32:18 +01:00
|
|
|
Container: rowContainer.Container(),
|
2024-02-16 18:23:19 +01:00
|
|
|
}
|
|
|
|
|
}
|