Noah Petherbridge
ddcad27485
Convert the Chunker size to a uint8 so chunk sizes are limited to 255px. This means that inside of a chunk, uint8's can track the relative pixel coordinates and result in a great memory savings since all of these uint8's are currently 64-bits wide apiece. WIP on rectangular shaped doodads: * You can create such a doodad in the editor and draw it normally. * It doesn't draw the right size when dragged into your level however: - In uix.Actor.Size() it gets a rect of the doodad's square Chunker size, instead of getting the proper doodad.Size rect. - If you give it the doodad.Size rect, it draws the Canvas size correctly instead of a square - the full drawing appears and in gameplay its hitbox (assuming the same large rectangle size) works correctly in-game. - But, the doodad has scrolling issues when it gets to the top or left edge of the screen! This old gnarly bug has come back. For some reason square canvas doodads draw correctly but rectangular ones have the drawing scroll just a bit - how far it scrolls is proportional to how big the doodad is, with the Start Flag only scrolling a few pixels before it stops.
260 lines
6.0 KiB
Go
260 lines
6.0 KiB
Go
package doodle
|
|
|
|
import (
|
|
"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"
|
|
"git.kirsle.net/go/render"
|
|
"git.kirsle.net/go/render/event"
|
|
"git.kirsle.net/go/ui"
|
|
)
|
|
|
|
/*
|
|
MenuScene holds the main dialog menu UIs for:
|
|
|
|
* New Level
|
|
* Open Level
|
|
* Settings
|
|
|
|
DEPRECATED: migrate these prompts into popup windows to appear
|
|
on the MainScene or elsewhere as wanted.
|
|
*/
|
|
type MenuScene struct {
|
|
// Configuration.
|
|
StartupMenu string
|
|
NewDoodad bool
|
|
|
|
Supervisor *ui.Supervisor
|
|
|
|
// Private widgets.
|
|
window *ui.Window
|
|
|
|
// Background wallpaper canvas.
|
|
canvas *uix.Canvas
|
|
|
|
// Values for the New menu
|
|
newPageType string
|
|
newWallpaper string
|
|
|
|
// Values for the Load/Play menu.
|
|
loadForPlay bool // false = load for edit
|
|
}
|
|
|
|
// Name of the scene.
|
|
func (s *MenuScene) Name() string {
|
|
return "Menu"
|
|
}
|
|
|
|
// DebugGetWindow surfaces the underlying private window.
|
|
func (s *MenuScene) DebugGetWindow() *ui.Window {
|
|
return s.window
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
// GotoLoadMenu loads the MenuScene and shows the "Load" window.
|
|
func (d *Doodle) GotoLoadMenu() {
|
|
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")
|
|
scene := &MenuScene{
|
|
StartupMenu: "load",
|
|
loadForPlay: true,
|
|
}
|
|
d.Goto(scene)
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
// Setup the scene.
|
|
func (s *MenuScene) Setup(d *Doodle) error {
|
|
s.Supervisor = ui.NewSupervisor()
|
|
|
|
// Set up the background wallpaper canvas.
|
|
s.canvas = uix.NewCanvas(100, false)
|
|
s.canvas.Resize(render.Rect{
|
|
W: d.width,
|
|
H: d.height,
|
|
})
|
|
s.canvas.LoadLevel(&level.Level{
|
|
Chunker: level.NewChunker(100),
|
|
Palette: level.NewPalette(),
|
|
PageType: level.Bounded,
|
|
Wallpaper: "notebook.png",
|
|
})
|
|
|
|
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
|
|
}
|
|
case "settings":
|
|
if err := s.setupSettingsWindow(d); err != nil {
|
|
return err
|
|
}
|
|
default:
|
|
d.FlashError("No Valid StartupMenu Given to MenuScene")
|
|
}
|
|
|
|
// 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,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// configureCanvas updates the settings of the background canvas, so a live
|
|
// preview of the wallpaper and wrapping type can be shown.
|
|
func (s *MenuScene) configureCanvas(pageType level.PageType, wallpaper string) {
|
|
s.canvas.LoadLevel(&level.Level{
|
|
Chunker: level.NewChunker(100),
|
|
Palette: level.NewPalette(),
|
|
PageType: pageType,
|
|
Wallpaper: wallpaper,
|
|
})
|
|
}
|
|
|
|
// setupNewWindow sets up the UI for the "New" window.
|
|
func (s *MenuScene) setupNewWindow(d *Doodle) error {
|
|
window := windows.NewAddEditLevel(windows.AddEditLevel{
|
|
Supervisor: s.Supervisor,
|
|
Engine: d.Engine,
|
|
NewDoodad: s.NewDoodad,
|
|
OnChangePageTypeAndWallpaper: func(pageType level.PageType, wallpaper string) {
|
|
log.Info("OnChangePageTypeAndWallpaper called: %+v, %+v", pageType, wallpaper)
|
|
s.canvas.Destroy() // clean up old textures
|
|
s.configureCanvas(pageType, wallpaper)
|
|
},
|
|
OnCreateNewLevel: func(lvl *level.Level) {
|
|
d.Goto(&EditorScene{
|
|
DrawingType: enum.LevelDrawing,
|
|
Level: lvl,
|
|
})
|
|
},
|
|
OnCreateNewDoodad: func(width, height int) {
|
|
d.NewDoodad(width, height)
|
|
},
|
|
OnCancel: func() {
|
|
d.Goto(&MainScene{})
|
|
},
|
|
})
|
|
s.window = window
|
|
window.SetButtons(0)
|
|
window.Show()
|
|
return nil
|
|
}
|
|
|
|
// setupLoadWindow sets up the UI for the "New" window.
|
|
func (s *MenuScene) setupLoadWindow(d *Doodle) error {
|
|
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{})
|
|
},
|
|
})
|
|
s.window = window
|
|
return nil
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// Loop the editor scene.
|
|
func (s *MenuScene) Loop(d *Doodle, ev *event.State) error {
|
|
s.Supervisor.Loop(ev)
|
|
|
|
if ev.WindowResized {
|
|
log.Info("Resized to %dx%d", d.width, d.height)
|
|
s.canvas.Resize(render.Rect{
|
|
W: d.width,
|
|
H: d.height,
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Draw the pixels on this frame.
|
|
func (s *MenuScene) Draw(d *Doodle) error {
|
|
// Draw the background canvas.
|
|
s.canvas.Present(d.Engine, render.Origin)
|
|
|
|
// TODO: if I don't call Compute here, buttons in the Edit Window get all
|
|
// bunched up. Investigate why later.
|
|
s.window.Compute(d.Engine)
|
|
|
|
// Draw the window managed by Supervisor.
|
|
s.Supervisor.Present(d.Engine)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Destroy the scene.
|
|
func (s *MenuScene) Destroy() error {
|
|
// Free (wallpaper) textures.
|
|
s.canvas.Destroy()
|
|
|
|
return nil
|
|
}
|