From cc16a472af5ca0c79e6914df8abb282b8e4305ac Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Mon, 4 Oct 2021 22:02:00 -0700 Subject: [PATCH] "Playtest From Here" Feature In the level editor, the "Play (P)" button has a new feature: Play From Here. On mouse down you begin dragging a silhouette of Boy or whoever the default player character is, as if you were dragging a doodad onto your level. Drop the silhouette on your level and enter Play Mode from that location instead of the Start Flag. Release your cursor over the Play button or press the "P" key to spawn at the Start Flag as usual. --- pkg/editor_scene.go | 12 ++++++++++++ pkg/editor_ui.go | 21 +++++++++++++++++++++ pkg/play_scene.go | 17 +++++++++++------ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/pkg/editor_scene.go b/pkg/editor_scene.go index 2979495..f877180 100644 --- a/pkg/editor_scene.go +++ b/pkg/editor_scene.go @@ -234,6 +234,18 @@ func (s *EditorScene) Playtest() { }) } +// PlaytestFrom enters play mode starting at a custom spawn point. +func (s *EditorScene) PlaytestFrom(p render.Point) { + log.Info("Play Mode, Go!") + s.d.Goto(&PlayScene{ + Filename: s.filename, + Level: s.Level, + CanEdit: true, + RememberScrollPosition: s.UI.Canvas.Scroll, + SpawnPoint: p, + }) +} + // ConfirmUnload may pop up a confirmation modal to save the level before the // user performs an action that may close the level, such as click File->New. func (s *EditorScene) ConfirmUnload(fn func()) { diff --git a/pkg/editor_ui.go b/pkg/editor_ui.go index ca5e656..da5ee2e 100644 --- a/pkg/editor_ui.go +++ b/pkg/editor_ui.go @@ -6,11 +6,13 @@ import ( "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/branding" + "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/drawtool" "git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/license" "git.kirsle.net/apps/doodle/pkg/log" + "git.kirsle.net/apps/doodle/pkg/shmem" "git.kirsle.net/apps/doodle/pkg/uix" "git.kirsle.net/apps/doodle/pkg/usercfg" "git.kirsle.net/go/render" @@ -114,6 +116,15 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI { Text: "Play (P)", Font: balance.PlayButtonFont, })) + u.PlayButton.Handle(ui.MouseDown, func(ed ui.EventData) error { + // Ugly hack: reuse the doodad dropper drag/drop function, + // smuggle state by the special filename >.< + doodad, _ := doodads.LoadFile(balance.PlayerCharacterDoodad) + u.startDragActor(doodad, &level.Actor{ + Filename: "__play_from_here__", + }) + return nil + }) u.PlayButton.Handle(ui.Click, func(ed ui.EventData) error { u.Scene.Playtest() return nil @@ -461,6 +472,16 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas { if actor.actor != nil { actor.actor.Point = position u.Scene.Level.Actors.Add(actor.actor) + + // Was this doodad drop, the Play Level button? + if actor.actor.Filename == "__play_from_here__" { + if shmem.Cursor.Inside(u.PlayButton.Rect()) { + u.Scene.Playtest() + } else { + u.Scene.PlaytestFrom(position) + } + return nil + } } else { u.Scene.Level.Actors.Add(&level.Actor{ Point: position, diff --git a/pkg/play_scene.go b/pkg/play_scene.go index c6ada7e..3c14b24 100644 --- a/pkg/play_scene.go +++ b/pkg/play_scene.go @@ -28,6 +28,7 @@ type PlayScene struct { CanEdit bool // i.e. you came from the Editor Mode HasNext bool // has a next level to load next RememberScrollPosition render.Point // for the Editor quality of life + SpawnPoint render.Point // if not zero, overrides Start Flag // Private variables. d *Doodle @@ -257,13 +258,17 @@ func (s *PlayScene) setupPlayer() { player = doodads.NewDummy(32) } - spawn = render.NewPoint( - // X: centered inside the flag. - flag.Point.X+(flagSize.W/2)-(player.Layers[0].Chunker.Size/2), + if !s.SpawnPoint.IsZero() { + spawn = s.SpawnPoint + } else { + spawn = render.NewPoint( + // X: centered inside the flag. + flag.Point.X+(flagSize.W/2)-(player.Layers[0].Chunker.Size/2), - // Y: the bottom of the flag, 4 pixels from the floor. - flag.Point.Y+flagSize.H-4-(player.Layers[0].Chunker.Size), - ) + // Y: the bottom of the flag, 4 pixels from the floor. + flag.Point.Y+flagSize.H-4-(player.Layers[0].Chunker.Size), + ) + } // Surface warnings around the spawn flag. if flagCount == 0 {