2019-06-25 21:57:11 +00:00
|
|
|
package doodle
|
|
|
|
|
|
|
|
import (
|
2022-09-24 22:17:25 +00:00
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/enum"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/level"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/log"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/uix"
|
|
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/windows"
|
2019-12-28 03:16:34 +00:00
|
|
|
"git.kirsle.net/go/render"
|
|
|
|
"git.kirsle.net/go/render/event"
|
|
|
|
"git.kirsle.net/go/ui"
|
2019-06-25 21:57:11 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
MenuScene holds the main dialog menu UIs for:
|
|
|
|
|
|
|
|
* New Level
|
|
|
|
* Open Level
|
|
|
|
* Settings
|
2021-12-31 00:31:45 +00:00
|
|
|
|
|
|
|
DEPRECATED: migrate these prompts into popup windows to appear
|
|
|
|
on the MainScene or elsewhere as wanted.
|
2019-06-25 21:57:11 +00:00
|
|
|
*/
|
|
|
|
type MenuScene struct {
|
|
|
|
// Configuration.
|
|
|
|
StartupMenu string
|
2023-02-17 05:47:18 +00:00
|
|
|
NewDoodad bool
|
2019-06-25 21:57:11 +00:00
|
|
|
|
|
|
|
Supervisor *ui.Supervisor
|
|
|
|
|
|
|
|
// Private widgets.
|
|
|
|
window *ui.Window
|
|
|
|
|
2019-06-26 00:43:23 +00:00
|
|
|
// Background wallpaper canvas.
|
|
|
|
canvas *uix.Canvas
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
// Values for the New menu
|
|
|
|
newPageType string
|
|
|
|
newWallpaper string
|
Add Switches, Fire/Water Collision and Play Menu
* New doodads: Switches.
* They come in four varieties: wall switch (background element, with
"ON/OFF" text) and three side-profile switches for the floor, left
or right walls.
* On collision with the player, they flip their state from "OFF" to
"ON" or vice versa. If the player walks away and then collides
again, the switch flips again.
* Can be used to open/close Electric Doors when turned on/off. Their
default state is "off"
* If a switch receives a power signal from another linked switch, it
sets its own state to match. So, two "on/off" switches that are
connected to a door AND to each other will both flip on/off when one
of them flips.
* Update the Level Collision logic to support Decoration, Fire and Water
pixel collisions.
* Previously, ALL pixels in the level were acting as though solid.
* Non-solid pixels don't count for collision detection, but their
attributes (fire and water) are collected and returned.
* Updated the MenuScene to support loading a map file in Play Mode
instead of Edit Mode. Updated the title screen menu to add a button
for playing levels instead of editing them.
* Wrote some documentation.
2019-07-07 01:30:03 +00:00
|
|
|
|
|
|
|
// Values for the Load/Play menu.
|
|
|
|
loadForPlay bool // false = load for edit
|
2019-06-25 21:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Name of the scene.
|
|
|
|
func (s *MenuScene) Name() string {
|
|
|
|
return "Menu"
|
|
|
|
}
|
|
|
|
|
2021-06-06 03:50:56 +00:00
|
|
|
// DebugGetWindow surfaces the underlying private window.
|
|
|
|
func (s *MenuScene) DebugGetWindow() *ui.Window {
|
|
|
|
return s.window
|
|
|
|
}
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
// GotoNewMenu loads the MenuScene and shows the "New" window.
|
|
|
|
func (d *Doodle) GotoNewMenu() {
|
|
|
|
log.Info("Loading the MenuScene to the New window")
|
|
|
|
scene := &MenuScene{
|
|
|
|
StartupMenu: "new",
|
|
|
|
}
|
|
|
|
d.Goto(scene)
|
|
|
|
}
|
|
|
|
|
2023-02-17 05:47:18 +00:00
|
|
|
// GotoNewDoodadMenu loads the MenuScene and shows the "New" window,
|
|
|
|
// but selected on the Doodad tab by default.
|
|
|
|
func (d *Doodle) GotoNewDoodadMenu() {
|
|
|
|
log.Info("Loading the MenuScene to the New window")
|
|
|
|
scene := &MenuScene{
|
|
|
|
StartupMenu: "new",
|
|
|
|
NewDoodad: true,
|
|
|
|
}
|
|
|
|
d.Goto(scene)
|
|
|
|
}
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
// GotoLoadMenu loads the MenuScene and shows the "Load" window.
|
|
|
|
func (d *Doodle) GotoLoadMenu() {
|
Add Switches, Fire/Water Collision and Play Menu
* New doodads: Switches.
* They come in four varieties: wall switch (background element, with
"ON/OFF" text) and three side-profile switches for the floor, left
or right walls.
* On collision with the player, they flip their state from "OFF" to
"ON" or vice versa. If the player walks away and then collides
again, the switch flips again.
* Can be used to open/close Electric Doors when turned on/off. Their
default state is "off"
* If a switch receives a power signal from another linked switch, it
sets its own state to match. So, two "on/off" switches that are
connected to a door AND to each other will both flip on/off when one
of them flips.
* Update the Level Collision logic to support Decoration, Fire and Water
pixel collisions.
* Previously, ALL pixels in the level were acting as though solid.
* Non-solid pixels don't count for collision detection, but their
attributes (fire and water) are collected and returned.
* Updated the MenuScene to support loading a map file in Play Mode
instead of Edit Mode. Updated the title screen menu to add a button
for playing levels instead of editing them.
* Wrote some documentation.
2019-07-07 01:30:03 +00:00
|
|
|
log.Info("Loading the MenuScene to the Load window for Edit Mode")
|
|
|
|
scene := &MenuScene{
|
|
|
|
StartupMenu: "load",
|
|
|
|
}
|
|
|
|
d.Goto(scene)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GotoPlayMenu loads the MenuScene and shows the "Load" window for playing a
|
|
|
|
// level, not editing it.
|
|
|
|
func (d *Doodle) GotoPlayMenu() {
|
|
|
|
log.Info("Loading the MenuScene to the Load window for Play Mode")
|
2019-06-25 21:57:11 +00:00
|
|
|
scene := &MenuScene{
|
|
|
|
StartupMenu: "load",
|
Add Switches, Fire/Water Collision and Play Menu
* New doodads: Switches.
* They come in four varieties: wall switch (background element, with
"ON/OFF" text) and three side-profile switches for the floor, left
or right walls.
* On collision with the player, they flip their state from "OFF" to
"ON" or vice versa. If the player walks away and then collides
again, the switch flips again.
* Can be used to open/close Electric Doors when turned on/off. Their
default state is "off"
* If a switch receives a power signal from another linked switch, it
sets its own state to match. So, two "on/off" switches that are
connected to a door AND to each other will both flip on/off when one
of them flips.
* Update the Level Collision logic to support Decoration, Fire and Water
pixel collisions.
* Previously, ALL pixels in the level were acting as though solid.
* Non-solid pixels don't count for collision detection, but their
attributes (fire and water) are collected and returned.
* Updated the MenuScene to support loading a map file in Play Mode
instead of Edit Mode. Updated the title screen menu to add a button
for playing levels instead of editing them.
* Wrote some documentation.
2019-07-07 01:30:03 +00:00
|
|
|
loadForPlay: true,
|
2019-06-25 21:57:11 +00:00
|
|
|
}
|
|
|
|
d.Goto(scene)
|
|
|
|
}
|
|
|
|
|
2020-09-02 03:54:58 +00:00
|
|
|
// GotoSettingsMenu loads the settings screen.
|
|
|
|
func (d *Doodle) GotoSettingsMenu() {
|
|
|
|
log.Info("Loading the MenuScene to the Settings Menu")
|
|
|
|
scene := &MenuScene{
|
|
|
|
StartupMenu: "settings",
|
|
|
|
}
|
|
|
|
d.Goto(scene)
|
|
|
|
}
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
// Setup the scene.
|
|
|
|
func (s *MenuScene) Setup(d *Doodle) error {
|
|
|
|
s.Supervisor = ui.NewSupervisor()
|
|
|
|
|
2019-06-26 00:43:23 +00:00
|
|
|
// Set up the background wallpaper canvas.
|
|
|
|
s.canvas = uix.NewCanvas(100, false)
|
|
|
|
s.canvas.Resize(render.Rect{
|
2019-12-28 03:16:34 +00:00
|
|
|
W: d.width,
|
|
|
|
H: d.height,
|
2019-06-26 00:43:23 +00:00
|
|
|
})
|
2021-07-20 00:14:00 +00:00
|
|
|
s.canvas.LoadLevel(&level.Level{
|
2019-06-26 00:43:23 +00:00
|
|
|
Chunker: level.NewChunker(100),
|
|
|
|
Palette: level.NewPalette(),
|
|
|
|
PageType: level.Bounded,
|
|
|
|
Wallpaper: "notebook.png",
|
|
|
|
})
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
switch s.StartupMenu {
|
|
|
|
case "new":
|
|
|
|
if err := s.setupNewWindow(d); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case "load":
|
|
|
|
if err := s.setupLoadWindow(d); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-09-02 03:54:58 +00:00
|
|
|
case "settings":
|
|
|
|
if err := s.setupSettingsWindow(d); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-06-25 21:57:11 +00:00
|
|
|
default:
|
2021-10-08 01:24:18 +00:00
|
|
|
d.FlashError("No Valid StartupMenu Given to MenuScene")
|
2019-06-25 21:57:11 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 06:21:17 +00:00
|
|
|
// Whatever window we got, give it window manager controls under Supervisor.
|
|
|
|
s.window.Supervise(s.Supervisor)
|
|
|
|
s.window.Compute(d.Engine)
|
|
|
|
|
|
|
|
// Center the window.
|
|
|
|
s.window.MoveTo(render.Point{
|
|
|
|
X: (d.width / 2) - (s.window.Size().W / 2),
|
|
|
|
Y: 60,
|
|
|
|
})
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-06-26 00:43:23 +00:00
|
|
|
// configureCanvas updates the settings of the background canvas, so a live
|
|
|
|
// preview of the wallpaper and wrapping type can be shown.
|
2021-07-20 00:14:00 +00:00
|
|
|
func (s *MenuScene) configureCanvas(pageType level.PageType, wallpaper string) {
|
|
|
|
s.canvas.LoadLevel(&level.Level{
|
2019-06-26 00:43:23 +00:00
|
|
|
Chunker: level.NewChunker(100),
|
|
|
|
Palette: level.NewPalette(),
|
|
|
|
PageType: pageType,
|
|
|
|
Wallpaper: wallpaper,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
// setupNewWindow sets up the UI for the "New" window.
|
|
|
|
func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
2020-04-07 06:21:17 +00:00
|
|
|
window := windows.NewAddEditLevel(windows.AddEditLevel{
|
|
|
|
Supervisor: s.Supervisor,
|
|
|
|
Engine: d.Engine,
|
2023-02-17 05:47:18 +00:00
|
|
|
NewDoodad: s.NewDoodad,
|
2020-04-07 06:21:17 +00:00
|
|
|
OnChangePageTypeAndWallpaper: func(pageType level.PageType, wallpaper string) {
|
|
|
|
log.Info("OnChangePageTypeAndWallpaper called: %+v, %+v", pageType, wallpaper)
|
2022-04-09 21:41:24 +00:00
|
|
|
s.canvas.Destroy() // clean up old textures
|
2021-07-20 00:14:00 +00:00
|
|
|
s.configureCanvas(pageType, wallpaper)
|
2020-04-07 06:21:17 +00:00
|
|
|
},
|
|
|
|
OnCreateNewLevel: func(lvl *level.Level) {
|
|
|
|
d.Goto(&EditorScene{
|
|
|
|
DrawingType: enum.LevelDrawing,
|
|
|
|
Level: lvl,
|
2019-06-25 21:57:11 +00:00
|
|
|
})
|
2020-04-07 06:21:17 +00:00
|
|
|
},
|
2023-02-17 05:47:18 +00:00
|
|
|
OnCreateNewDoodad: func(width, height int) {
|
|
|
|
d.NewDoodad(width, height)
|
2021-12-31 00:31:45 +00:00
|
|
|
},
|
2020-04-07 06:21:17 +00:00
|
|
|
OnCancel: func() {
|
|
|
|
d.Goto(&MainScene{})
|
|
|
|
},
|
|
|
|
})
|
2019-06-25 21:57:11 +00:00
|
|
|
s.window = window
|
2020-07-10 02:38:37 +00:00
|
|
|
window.SetButtons(0)
|
|
|
|
window.Show()
|
2019-06-25 21:57:11 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// setupLoadWindow sets up the UI for the "New" window.
|
|
|
|
func (s *MenuScene) setupLoadWindow(d *Doodle) error {
|
2020-04-07 06:21:17 +00:00
|
|
|
window := windows.NewOpenLevelEditor(windows.OpenLevelEditor{
|
|
|
|
Supervisor: s.Supervisor,
|
|
|
|
Engine: d.Engine,
|
|
|
|
LoadForPlay: s.loadForPlay,
|
|
|
|
OnPlayLevel: func(filename string) {
|
|
|
|
d.PlayLevel(filename)
|
|
|
|
},
|
|
|
|
OnEditLevel: func(filename string) {
|
|
|
|
d.EditFile(filename)
|
|
|
|
},
|
|
|
|
OnCancel: func() {
|
|
|
|
d.Goto(&MainScene{})
|
|
|
|
},
|
2019-06-25 22:23:01 +00:00
|
|
|
})
|
|
|
|
s.window = window
|
2019-06-25 21:57:11 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-09-02 03:54:58 +00:00
|
|
|
// setupLoadWindow sets up the UI for the "New" window.
|
|
|
|
func (s *MenuScene) setupSettingsWindow(d *Doodle) error {
|
|
|
|
window := windows.NewSettingsWindow(windows.Settings{
|
|
|
|
Supervisor: s.Supervisor,
|
|
|
|
Engine: d.Engine,
|
|
|
|
})
|
|
|
|
window.SetButtons(0)
|
|
|
|
s.window = window
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
// Loop the editor scene.
|
2019-12-22 22:11:01 +00:00
|
|
|
func (s *MenuScene) Loop(d *Doodle, ev *event.State) error {
|
2019-06-25 21:57:11 +00:00
|
|
|
s.Supervisor.Loop(ev)
|
2020-01-02 01:50:15 +00:00
|
|
|
|
|
|
|
if ev.WindowResized {
|
|
|
|
log.Info("Resized to %dx%d", d.width, d.height)
|
|
|
|
s.canvas.Resize(render.Rect{
|
|
|
|
W: d.width,
|
|
|
|
H: d.height,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw the pixels on this frame.
|
|
|
|
func (s *MenuScene) Draw(d *Doodle) error {
|
2019-06-26 00:43:23 +00:00
|
|
|
// Draw the background canvas.
|
|
|
|
s.canvas.Present(d.Engine, render.Origin)
|
|
|
|
|
2020-04-07 06:21:17 +00:00
|
|
|
// TODO: if I don't call Compute here, buttons in the Edit Window get all
|
|
|
|
// bunched up. Investigate why later.
|
2019-06-25 21:57:11 +00:00
|
|
|
s.window.Compute(d.Engine)
|
2020-04-07 06:21:17 +00:00
|
|
|
|
|
|
|
// Draw the window managed by Supervisor.
|
|
|
|
s.Supervisor.Present(d.Engine)
|
2019-06-25 21:57:11 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Destroy the scene.
|
|
|
|
func (s *MenuScene) Destroy() error {
|
2022-04-09 21:41:24 +00:00
|
|
|
// Free (wallpaper) textures.
|
|
|
|
s.canvas.Destroy()
|
|
|
|
|
2019-06-25 21:57:11 +00:00
|
|
|
return nil
|
|
|
|
}
|