"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.
This commit is contained in:
Noah 2021-10-04 22:02:00 -07:00
parent c2c91e45a9
commit cc16a472af
3 changed files with 44 additions and 6 deletions

View File

@ -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 // 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. // user performs an action that may close the level, such as click File->New.
func (s *EditorScene) ConfirmUnload(fn func()) { func (s *EditorScene) ConfirmUnload(fn func()) {

View File

@ -6,11 +6,13 @@ import (
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/branding" "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/drawtool"
"git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/level"
"git.kirsle.net/apps/doodle/pkg/license" "git.kirsle.net/apps/doodle/pkg/license"
"git.kirsle.net/apps/doodle/pkg/log" "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/uix"
"git.kirsle.net/apps/doodle/pkg/usercfg" "git.kirsle.net/apps/doodle/pkg/usercfg"
"git.kirsle.net/go/render" "git.kirsle.net/go/render"
@ -114,6 +116,15 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI {
Text: "Play (P)", Text: "Play (P)",
Font: balance.PlayButtonFont, 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.PlayButton.Handle(ui.Click, func(ed ui.EventData) error {
u.Scene.Playtest() u.Scene.Playtest()
return nil return nil
@ -461,6 +472,16 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas {
if actor.actor != nil { if actor.actor != nil {
actor.actor.Point = position actor.actor.Point = position
u.Scene.Level.Actors.Add(actor.actor) 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 { } else {
u.Scene.Level.Actors.Add(&level.Actor{ u.Scene.Level.Actors.Add(&level.Actor{
Point: position, Point: position,

View File

@ -28,6 +28,7 @@ type PlayScene struct {
CanEdit bool // i.e. you came from the Editor Mode CanEdit bool // i.e. you came from the Editor Mode
HasNext bool // has a next level to load next HasNext bool // has a next level to load next
RememberScrollPosition render.Point // for the Editor quality of life RememberScrollPosition render.Point // for the Editor quality of life
SpawnPoint render.Point // if not zero, overrides Start Flag
// Private variables. // Private variables.
d *Doodle d *Doodle
@ -257,6 +258,9 @@ func (s *PlayScene) setupPlayer() {
player = doodads.NewDummy(32) player = doodads.NewDummy(32)
} }
if !s.SpawnPoint.IsZero() {
spawn = s.SpawnPoint
} else {
spawn = render.NewPoint( spawn = render.NewPoint(
// X: centered inside the flag. // X: centered inside the flag.
flag.Point.X+(flagSize.W/2)-(player.Layers[0].Chunker.Size/2), flag.Point.X+(flagSize.W/2)-(player.Layers[0].Chunker.Size/2),
@ -264,6 +268,7 @@ func (s *PlayScene) setupPlayer() {
// Y: the bottom of the flag, 4 pixels from the floor. // Y: the bottom of the flag, 4 pixels from the floor.
flag.Point.Y+flagSize.H-4-(player.Layers[0].Chunker.Size), flag.Point.Y+flagSize.H-4-(player.Layers[0].Chunker.Size),
) )
}
// Surface warnings around the spawn flag. // Surface warnings around the spawn flag.
if flagCount == 0 { if flagCount == 0 {