Doodads: Use Key and Working Warp Doors

* The "Use Key" (Q or Spacebar) now activates the Warp Door instead of a
  collision event doing so.
* Warp Doors are now functional: the player opens a door, disappears,
  the door closes; player is teleported to the linked door which opens,
  appears the player and closes.
* If the player exits thru a Blue or Orange door which is disabled
  (dotted outline), the door still opens and drops the player off but
  returns to a Disabled state, acting as a one-way door.
* Clean up several debug log lines from Doodle and doodad scripts.
This commit is contained in:
Noah 2021-01-03 15:19:21 -08:00
parent 2c1185cc9f
commit 3892087932
26 changed files with 218 additions and 77 deletions

View File

@ -1,6 +1,4 @@
function main() { function main() {
console.log("Azulian '%s' initialized!", Self.Title);
var playerSpeed = 4; var playerSpeed = 4;
var gravity = 4; var gravity = 4;
var Vx = Vy = 0; var Vx = Vy = 0;

View File

@ -4,8 +4,6 @@ function main() {
var Vx = Vy = 0; var Vx = Vy = 0;
var altitude = Self.Position().Y; // original height in the level var altitude = Self.Position().Y; // original height in the level
console.log("Bird altitude is %d", altitude);
var direction = "left"; var direction = "left";
var states = { var states = {
flying: 0, flying: 0,

View File

@ -1,6 +1,4 @@
function main() { function main() {
console.log("%s initialized!", Self.Title);
var timer = 0; var timer = 0;
var pressed = false; var pressed = false;

View File

@ -1,6 +1,4 @@
function main() { function main() {
console.log("%s initialized!", Self.Title);
var pressed = false; var pressed = false;
// When a sticky button receives power, it pops back up. // When a sticky button receives power, it pops back up.

View File

@ -1,6 +1,4 @@
function main() { function main() {
console.log("%s initialized!", Self.Title);
Self.AddAnimation("open", 100, [0, 1, 2, 3]); Self.AddAnimation("open", 100, [0, 1, 2, 3]);
Self.AddAnimation("close", 100, [3, 2, 1, 0]); Self.AddAnimation("close", 100, [3, 2, 1, 0]);
var animating = false; var animating = false;
@ -9,8 +7,6 @@ function main() {
Self.SetHitbox(0, 0, 34, 76); Self.SetHitbox(0, 0, 34, 76);
Message.Subscribe("power", function(powered) { Message.Subscribe("power", function(powered) {
console.log("%s got power=%+v", Self.Title, powered);
if (powered) { if (powered) {
if (animating || opened) { if (animating || opened) {
return; return;

View File

@ -1,6 +1,5 @@
// Exit Flag. // Exit Flag.
function main() { function main() {
console.log("%s initialized!", Self.Title);
Self.SetHitbox(22+16, 16, 75-16, 86); Self.SetHitbox(22+16, 16, 75-16, 86);
Events.OnCollide(function(e) { Events.OnCollide(function(e) {

View File

@ -4,7 +4,6 @@
var state = false; var state = false;
function main() { function main() {
console.log("%s ID '%s' initialized!", Self.Title, Self.ID());
Self.SetHitbox(0, 0, 42, 42); Self.SetHitbox(0, 0, 42, 42);
// When the button is activated, don't keep toggling state until we're not // When the button is activated, don't keep toggling state until we're not

View File

@ -1,5 +1,4 @@
function main() { function main() {
console.log("%s initialized!", Self.Title);
// Switch has two frames: // Switch has two frames:
// 0: Off // 0: Off

View File

@ -1,6 +1,4 @@
function main() { function main() {
console.log("%s initialized!", Self.Title);
var timer = 0; var timer = 0;
Self.SetHitbox(0, 0, 72, 6); Self.SetHitbox(0, 0, 72, 6);

View File

@ -1,7 +1,6 @@
function main() { function main() {
// What direction is the trapdoor facing? // What direction is the trapdoor facing?
var direction = Self.GetTag("direction"); var direction = Self.GetTag("direction");
console.log("Trapdoor(%s) initialized", direction);
var timer = 0; var timer = 0;

View File

@ -1,7 +1,5 @@
// Warp Doors // Warp Doors
function main() { function main() {
console.log("Warp Door %s Initialized", Self.Title);
Self.SetHitbox(0, 0, 34, 76); Self.SetHitbox(0, 0, 34, 76);
// Are we a blue or orange door? Regular warp door will be 'none' // Are we a blue or orange door? Regular warp door will be 'none'
@ -31,12 +29,18 @@ function main() {
spriteDefault = "door-1"; spriteDefault = "door-1";
} }
console.log("Warp %s: default=%s disabled=%+v color=%s isState=%+v state=%+v", Self.Title, spriteDefault, spriteDisabled, color, isStateDoor, state); // Find our linked Warp Door.
var links = Self.GetLinks()
var linkedDoor = null;
for (var i = 0; i < links.length; i++) {
if (links[i].Title.indexOf("Warp Door") > -1) {
linkedDoor = links[i];
}
}
// Subscribe to the global state-change if we are a state door. // Subscribe to the global state-change if we are a state door.
if (isStateDoor) { if (isStateDoor) {
Message.Subscribe("broadcast:state-change", function(newState) { Message.Subscribe("broadcast:state-change", function(newState) {
console.log("Warp %s: received state to %+v", Self.Title, newState);
state = color === 'blue' ? !newState : newState; state = color === 'blue' ? !newState : newState;
// Activate or deactivate the door. // Activate or deactivate the door.
@ -44,38 +48,69 @@ function main() {
}); });
} }
// TODO: respond to a "Use" button instead of a Collide to open the door. // The player Uses the door.
Events.OnCollide(function(e) { var flashedCooldown = false; // "Locked Door" flashed message.
if (!e.Settled) { Events.OnUse(function(e) {
if (animating) {
return; return;
} }
if (animating || collide) { // Doors without linked exits are not usable.
if (linkedDoor === null) {
if (!flashedCooldown) {
Flash("This door is locked.");
flashedCooldown = true;
setTimeout(function() {
flashedCooldown = false;
}, 1000);
}
return; return;
} }
// Only players can use doors for now. // Only players can use doors for now.
if (e.Actor.IsPlayer() && e.InHitbox) { if (e.Actor.IsPlayer()) {
if (isStateDoor && !state) { if (isStateDoor && !state) {
// The state door is inactive (dotted outline). // The state door is inactive (dotted outline).
return; return;
} }
// Freeze the player.
e.Actor.Freeze()
// Play the open and close animation. // Play the open and close animation.
animating = true; animating = true;
collide = true;
Self.PlayAnimation("open", function() { Self.PlayAnimation("open", function() {
e.Actor.Hide() e.Actor.Hide()
Self.PlayAnimation("close", function() { Self.PlayAnimation("close", function() {
Self.ShowLayerNamed(isStateDoor && !state ? spriteDisabled : spriteDefault); Self.ShowLayerNamed(isStateDoor && !state ? spriteDisabled : spriteDefault);
e.Actor.Show()
animating = false; animating = false;
// Teleport the player to the linked door. Inform the target
// door of the arrival of the player so it doesn't trigger
// to send the player back here again on a loop.
if (linkedDoor !== null) {
Message.Publish("warp-door:incoming", e.Actor);
e.Actor.MoveTo(linkedDoor.Position());
}
}); });
}); });
} }
}); });
Events.OnLeave(function(e) { // Respond to incoming warp events.
collide = false; Message.Subscribe("warp-door:incoming", function(player) {
animating = true;
player.Unfreeze();
Self.PlayAnimation("open", function() {
player.Show();
Self.PlayAnimation("close", function() {
animating = false;
// If the receiving door was a State Door, fix its state.
if (isStateDoor) {
Self.ShowLayerNamed(state ? spriteDefault : spriteDisabled);
}
});
});
}); });
} }

View File

@ -109,7 +109,6 @@ func NewEditorUI(d *Doodle, s *EditorScene) *EditorUI {
// Preload pop-up windows before they're needed. // Preload pop-up windows before they're needed.
u.SetupPopups(d) u.SetupPopups(d)
log.Error("menu size: %s", u.MenuBar.Rect())
u.screen.Pack(u.MenuBar, ui.Pack{ u.screen.Pack(u.MenuBar, ui.Pack{
Side: ui.N, Side: ui.N,
FillX: true, FillX: true,
@ -676,7 +675,6 @@ func (u *EditorUI) SetupMenuBar(d *Doodle) *ui.MenuBar {
menu.Supervise(u.Supervisor) menu.Supervise(u.Supervisor)
menu.Compute(d.Engine) menu.Compute(d.Engine)
log.Error("Setup MenuBar: %s\n", menu.Size())
return menu return menu
} }

View File

@ -106,3 +106,33 @@ func EraserTool(ev *event.State) bool {
func DoodadDropper(ev *event.State) bool { func DoodadDropper(ev *event.State) bool {
return ev.KeyDown("d") return ev.KeyDown("d")
} }
// Shift key.
func Shift(ev *event.State) bool {
return ev.Shift
}
// Left arrow.
func Left(ev *event.State) bool {
return ev.Left || ev.KeyDown("a")
}
// Right arrow.
func Right(ev *event.State) bool {
return ev.Right || ev.KeyDown("d")
}
// Up arrow.
func Up(ev *event.State) bool {
return ev.Up || ev.KeyDown("w")
}
// Down arrow.
func Down(ev *event.State) bool {
return ev.Down || ev.KeyDown("s")
}
// "Use" button.
func Use(ev *event.State) bool {
return ev.Space || ev.KeyDown("q")
}

View File

@ -57,7 +57,7 @@ func LoadFile(filename string) (*Level, error) {
// Do we have the file in bindata? // Do we have the file in bindata?
if jsonData, err := bindata.Asset(filename); err == nil { if jsonData, err := bindata.Asset(filename); err == nil {
log.Info("loaded from embedded bindata") log.Debug("Level %s: loaded from embedded bindata", filename)
return FromJSON(filename, jsonData) return FromJSON(filename, jsonData)
} }

View File

@ -471,30 +471,30 @@ func (s *PlayScene) movePlayer(ev *event.State) {
velocity.Y = 0 velocity.Y = 0
// Shift to slow your roll to 1 pixel per tick. // Shift to slow your roll to 1 pixel per tick.
if ev.Shift { if keybind.Shift(ev) {
playerSpeed = 1 playerSpeed = 1
} }
if ev.Left { if keybind.Left(ev) {
velocity.X = -playerSpeed velocity.X = -playerSpeed
} else if ev.Right { } else if keybind.Right(ev) {
velocity.X = playerSpeed velocity.X = playerSpeed
} }
if ev.Up { if keybind.Up(ev) {
velocity.Y = -playerSpeed velocity.Y = -playerSpeed
} else if ev.Down { } else if keybind.Down(ev) {
velocity.Y = playerSpeed velocity.Y = playerSpeed
} }
} else { } else {
// Moving left or right. // Moving left or right.
if ev.Left { if keybind.Left(ev) {
direction = -1 direction = -1
} else if ev.Right { } else if keybind.Right(ev) {
direction = 1 direction = 1
} }
// Up button to signal they want to jump. // Up button to signal they want to jump.
if ev.Up && (s.Player.Grounded() || s.playerJumpCounter >= 0) { if keybind.Up(ev) && (s.Player.Grounded() || s.playerJumpCounter >= 0) {
jumping = true jumping = true
if s.Player.Grounded() { if s.Player.Grounded() {
@ -533,8 +533,18 @@ func (s *PlayScene) movePlayer(ev *event.State) {
} }
} }
// Move the player unless frozen.
// TODO: if Y=0 then gravity fails, but not doing this allows the
// player to jump while frozen. Not a HUGE deal right now as only Warp Doors
// freeze the player currently but do address this later.
if s.Player.IsFrozen() {
velocity.X = 0
}
s.Player.SetVelocity(velocity) s.Player.SetVelocity(velocity)
// If the "Use" key is pressed, set an actor flag on the player.
s.Player.SetUsing(keybind.Use(ev))
s.scripting.To(s.Player.ID()).Events.RunKeypress(ev) s.scripting.To(s.Player.ID()).Events.RunKeypress(ev)
} }

View File

@ -13,6 +13,7 @@ const (
CollideEvent = "OnCollide" // another doodad collides with us CollideEvent = "OnCollide" // another doodad collides with us
EnterEvent = "OnEnter" // a doodad is fully inside us EnterEvent = "OnEnter" // a doodad is fully inside us
LeaveEvent = "OnLeave" // a doodad no longer collides with us LeaveEvent = "OnLeave" // a doodad no longer collides with us
UseEvent = "OnUse" // player pressed the Use key while touching us
// Controllable (player character) doodad events // Controllable (player character) doodad events
KeypressEvent = "OnKeypress" // i.e. arrow keys KeypressEvent = "OnKeypress" // i.e. arrow keys
@ -46,6 +47,16 @@ func (e *Events) RunCollide(v interface{}) error {
return e.run(CollideEvent, v) return e.run(CollideEvent, v)
} }
// OnUse fires when another actor collides with yours.
func (e *Events) OnUse(call otto.FunctionCall) otto.Value {
return e.register(UseEvent, call.Argument(0))
}
// RunUse invokes the OnUse handler function.
func (e *Events) RunUse(v interface{}) error {
return e.run(UseEvent, v)
}
// OnLeave fires when another actor stops colliding with yours. // OnLeave fires when another actor stops colliding with yours.
func (e *Events) OnLeave(call otto.FunctionCall) otto.Value { func (e *Events) OnLeave(call otto.FunctionCall) otto.Value {
return e.register(LeaveEvent, call.Argument(0)) return e.register(LeaveEvent, call.Argument(0))

View File

@ -93,9 +93,9 @@ func (s *Supervisor) To(name string) *VM {
// TODO: put this log back in, but add PLAYER script so it doesn't spam // TODO: put this log back in, but add PLAYER script so it doesn't spam
// the console for missing PLAYER. // the console for missing PLAYER.
// log.Error("scripting.Supervisor.To(%s): no such VM but returning blank VM", log.Error("scripting.Supervisor.To(%s): no such VM but returning blank VM",
// name, name,
// ) )
return NewVM(name) return NewVM(name)
} }

View File

@ -25,19 +25,20 @@ import (
// as defined in the map: its spawn coordinate and configuration. // as defined in the map: its spawn coordinate and configuration.
// - A uix.Canvas that can present the actor's graphics to the screen. // - A uix.Canvas that can present the actor's graphics to the screen.
type Actor struct { type Actor struct {
id string
Drawing *doodads.Drawing Drawing *doodads.Drawing
Actor *level.Actor Actor *level.Actor
Canvas *Canvas Canvas *Canvas
activeLayer int // active drawing frame for display activeLayer int // active drawing frame for display
flagDestroy bool // flag the actor for destruction flagDestroy bool // flag the actor for destruction
flagUsing bool // flag that the (player) has pressed the Use key.
// Actor runtime variables. // Actor runtime variables.
hasGravity bool hasGravity bool
isMobile bool // Mobile character, such as the player or an enemy isMobile bool // Mobile character, such as the player or an enemy
noclip bool // Disable collision detection noclip bool // Disable collision detection
hidden bool // invisible, via Hide() and Show() hidden bool // invisible, via Hide() and Show()
frozen bool // Frozen, via Freeze() and Unfreeze()
hitbox render.Rect hitbox render.Rect
inventory map[string]int // item inventory. doodad name -> quantity, 0 for key item. inventory map[string]int // item inventory. doodad name -> quantity, 0 for key item.
data map[string]string // arbitrary key/value store. DEPRECATED ?? data map[string]string // arbitrary key/value store. DEPRECATED ??
@ -174,6 +175,28 @@ func (a *Actor) Show() {
a.hidden = false a.hidden = false
} }
// Freeze an actor. For the player character, this means arrow key inputs
// will stop moving the actor.
func (a *Actor) Freeze() {
a.frozen = true
}
// Unfreeze an actor.
func (a *Actor) Unfreeze() {
a.frozen = false
}
// IsFrozen returns true if the actor is frozen.
func (a *Actor) IsFrozen() bool {
return a.frozen
}
// SetUsing enables the "Use Key" flag, mainly for the player character to activate
// certain doodads in the level.
func (a *Actor) SetUsing(v bool) {
a.flagUsing = v
}
// SetNoclip sets the noclip setting for an actor. If true, the actor can // SetNoclip sets the noclip setting for an actor. If true, the actor can
// clip through level geometry. // clip through level geometry.
func (a *Actor) SetNoclip(v bool) { func (a *Actor) SetNoclip(v bool) {

View File

@ -276,6 +276,16 @@ func (w *Canvas) loopActorCollision() error {
}); err != nil && err != scripting.ErrReturnFalse { }); err != nil && err != scripting.ErrReturnFalse {
log.Error("VM(%s).RunCollide: %s", a.ID(), err.Error()) log.Error("VM(%s).RunCollide: %s", a.ID(), err.Error())
} }
// If the (player) is pressing the Use key, call the colliding
// actor's OnUse event.
if b.flagUsing {
if err := w.scripting.To(a.ID()).Events.RunUse(&UseEvent{
Actor: b,
}); err != nil {
log.Error("VM(%s).RunUse: %s", a.ID(), err.Error())
}
}
} }
} }
} }

View File

@ -9,3 +9,8 @@ type CollideEvent struct {
InHitbox bool // If the two elected hitboxes are overlapping InHitbox bool // If the two elected hitboxes are overlapping
Settled bool // Movement phase finished, actor script can fire actions Settled bool // Movement phase finished, actor script can fire actions
} }
// UseEvent holds data sent to an actor's OnUse handler.
type UseEvent struct {
Actor *Actor
}

View File

@ -57,26 +57,7 @@ func (w *Canvas) InstallScripts() error {
vm := w.scripting.To(actor.ID()) vm := w.scripting.To(actor.ID())
// Security: expose a selective API to the actor to the JS engine. // Security: expose a selective API to the actor to the JS engine.
vm.Self = map[string]interface{}{ vm.Self = w.MakeSelfAPI(actor)
"Filename": actor.Doodad().Filename,
"Title": actor.Doodad().Title,
// functions
"ID": actor.ID,
"GetTag": actor.Doodad().Tag,
"Position": actor.Position,
"SetHitbox": actor.SetHitbox,
"SetVelocity": actor.SetVelocity,
"SetMobile": actor.SetMobile,
"SetGravity": actor.SetGravity,
"AddAnimation": actor.AddAnimation,
"IsAnimating": actor.IsAnimating,
"PlayAnimation": actor.PlayAnimation,
"StopAnimation": actor.StopAnimation,
"ShowLayer": actor.ShowLayer,
"ShowLayerNamed": actor.ShowLayerNamed,
"Destroy": actor.Destroy,
}
vm.Set("Self", vm.Self) vm.Set("Self", vm.Self)
if _, err := vm.Run(actor.Doodad().Script); err != nil { if _, err := vm.Run(actor.Doodad().Script); err != nil {

View File

@ -2,6 +2,7 @@ package uix
import ( import (
"errors" "errors"
"sort"
"git.kirsle.net/apps/doodle/pkg/drawtool" "git.kirsle.net/apps/doodle/pkg/drawtool"
"git.kirsle.net/apps/doodle/pkg/shmem" "git.kirsle.net/apps/doodle/pkg/shmem"
@ -34,3 +35,34 @@ func (w *Canvas) LinkAdd(a *Actor) error {
} }
return nil return nil
} }
// GetLinkedActors returns the live Actor instances (Play Mode) which are linked
// to the live actor given.
func (w *Canvas) GetLinkedActors(a *Actor) []*Actor {
// Identify the linked actor UUIDs from the level file.
linkedIDs := map[string]interface{}{}
matching := map[string]*Actor{}
for _, id := range a.Actor.Links {
linkedIDs[id] = nil
}
// Find live instances of these actors.
for _, live := range w.actors {
if _, ok := linkedIDs[live.ID()]; ok {
matching[live.ID()] = live
}
}
// Sort them deterministically and return.
keys := []string{}
for key, _ := range matching {
keys = append(keys, key)
}
sort.Strings(keys)
result := []*Actor{}
for _, key := range keys {
result = append(result, matching[key])
}
return result
}

35
pkg/uix/scripting.go Normal file
View File

@ -0,0 +1,35 @@
package uix
// Functions relating to the Doodad JavaScript API for Canvas Actors.
// MakeSelfAPI generates the `Self` object for the scripting API in
// reference to a live Canvas actor in the level.
func (w *Canvas) MakeSelfAPI(actor *Actor) map[string]interface{} {
return map[string]interface{}{
"Filename": actor.Doodad().Filename,
"Title": actor.Doodad().Title,
// functions
"ID": actor.ID,
"GetTag": actor.Doodad().Tag,
"Position": actor.Position,
"SetHitbox": actor.SetHitbox,
"SetVelocity": actor.SetVelocity,
"SetMobile": actor.SetMobile,
"SetGravity": actor.SetGravity,
"AddAnimation": actor.AddAnimation,
"IsAnimating": actor.IsAnimating,
"PlayAnimation": actor.PlayAnimation,
"StopAnimation": actor.StopAnimation,
"ShowLayer": actor.ShowLayer,
"ShowLayerNamed": actor.ShowLayerNamed,
"Destroy": actor.Destroy,
"GetLinks": func() []map[string]interface{} {
var result = []map[string]interface{}{}
for _, linked := range w.GetLinkedActors(actor) {
result = append(result, w.MakeSelfAPI(linked))
}
return result
},
}
}

View File

@ -6,7 +6,6 @@ import (
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/doodads"
"git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/shmem" "git.kirsle.net/apps/doodle/pkg/shmem"
"git.kirsle.net/go/render" "git.kirsle.net/go/render"
"git.kirsle.net/go/ui" "git.kirsle.net/go/ui"
@ -54,7 +53,6 @@ func NewLayerWindow(config Layers) *ui.Window {
) )
config.activeLayer = fmt.Sprintf("%d", config.ActiveLayer) config.activeLayer = fmt.Sprintf("%d", config.ActiveLayer)
log.Warn("config.activeLayer=%s", config.activeLayer)
window := ui.NewWindow(title) window := ui.NewWindow(title)
window.SetButtons(ui.CloseButton) window.SetButtons(ui.CloseButton)
@ -71,8 +69,6 @@ func NewLayerWindow(config Layers) *ui.Window {
Expand: true, Expand: true,
}) })
log.Info("SETUP PALETTE WINDOW")
// Draw the header row. // Draw the header row.
headers := []struct { headers := []struct {
Name string Name string
@ -143,7 +139,6 @@ func NewLayerWindow(config Layers) *ui.Window {
}) })
btnName.Handle(ui.Click, func(ed ui.EventData) error { btnName.Handle(ui.Click, func(ed ui.EventData) error {
shmem.Prompt("New layer name ["+doodad.Layers[i].Name+"]: ", func(answer string) { shmem.Prompt("New layer name ["+doodad.Layers[i].Name+"]: ", func(answer string) {
log.Warn("Answer: %s", answer)
if answer != "" { if answer != "" {
doodad.Layers[i].Name = answer doodad.Layers[i].Name = answer
if config.OnChange != nil { if config.OnChange != nil {
@ -220,7 +215,6 @@ func NewLayerWindow(config Layers) *ui.Window {
Font: balance.MenuFont, Font: balance.MenuFont,
OnChange: func(newPage, perPage int) { OnChange: func(newPage, perPage int) {
page = newPage page = newPage
log.Info("Page: %d, %d", page, perPage)
// Re-evaluate which rows are shown/hidden for this page. // Re-evaluate which rows are shown/hidden for this page.
var ( var (

View File

@ -5,7 +5,6 @@ import (
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/level"
"git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/pkg/userdir"
"git.kirsle.net/go/render" "git.kirsle.net/go/render"
"git.kirsle.net/go/ui" "git.kirsle.net/go/ui"
@ -74,7 +73,6 @@ func NewOpenLevelEditor(config OpenLevelEditor) *ui.Window {
}) })
for i, lvl := range levels { for i, lvl := range levels {
func(i int, lvl string) { func(i int, lvl string) {
log.Info("Add file %s to row %s", lvl, lvlRow.Name)
btn := ui.NewButton("Level Btn", ui.NewLabel(ui.Label{ btn := ui.NewButton("Level Btn", ui.NewLabel(ui.Label{
Text: lvl, Text: lvl,
Font: balance.MenuFont, Font: balance.MenuFont,
@ -95,7 +93,6 @@ func NewOpenLevelEditor(config OpenLevelEditor) *ui.Window {
}) })
if i > 0 && (i+1)%4 == 0 { if i > 0 && (i+1)%4 == 0 {
log.Warn("i=%d wrapped at mod 4", i)
lvlRow = ui.NewFrame(fmt.Sprintf("Level Row %d", i)) lvlRow = ui.NewFrame(fmt.Sprintf("Level Row %d", i))
frame.Pack(lvlRow, ui.Pack{ frame.Pack(lvlRow, ui.Pack{
Side: ui.N, Side: ui.N,

View File

@ -73,8 +73,6 @@ func NewPaletteEditor(config PaletteEditor) *ui.Window {
Expand: true, Expand: true,
}) })
log.Info("SETUP PALETTE WINDOW")
// Draw the header row. // Draw the header row.
headers := []struct { headers := []struct {
Name string Name string