diff --git a/dev-assets/doodads/build.sh b/dev-assets/doodads/build.sh index 5b91a4d..e06763e 100755 --- a/dev-assets/doodads/build.sh +++ b/dev-assets/doodads/build.sh @@ -63,7 +63,13 @@ trapdoors() { cd trapdoors/ doodad convert -t "Trapdoor" down{1,2,3,4}.png trapdoor-down.doodad - doodad install-script down.js trapdoor-down.doodad + doodad convert -t "Trapdoor Left" left{1,2,3,4}.png trapdoor-left.doodad + doodad convert -t "Trapdoor Right" right{1,2,3,4}.png trapdoor-right.doodad + doodad convert -t "Trapdoor Up" up{1,2,3,4}.png trapdoor-up.doodad + doodad install-script trapdoor.js trapdoor-down.doodad + doodad install-script trapdoor.js trapdoor-left.doodad + doodad install-script trapdoor.js trapdoor-right.doodad + doodad install-script trapdoor.js trapdoor-up.doodad cp trapdoor-*.doodad ../../../assets/doodads/ diff --git a/dev-assets/doodads/trapdoors/left1.png b/dev-assets/doodads/trapdoors/left1.png new file mode 100644 index 0000000..e8cc2a6 Binary files /dev/null and b/dev-assets/doodads/trapdoors/left1.png differ diff --git a/dev-assets/doodads/trapdoors/left2.png b/dev-assets/doodads/trapdoors/left2.png new file mode 100644 index 0000000..9c74728 Binary files /dev/null and b/dev-assets/doodads/trapdoors/left2.png differ diff --git a/dev-assets/doodads/trapdoors/left3.png b/dev-assets/doodads/trapdoors/left3.png new file mode 100644 index 0000000..d9a21bc Binary files /dev/null and b/dev-assets/doodads/trapdoors/left3.png differ diff --git a/dev-assets/doodads/trapdoors/left4.png b/dev-assets/doodads/trapdoors/left4.png new file mode 100644 index 0000000..96d1537 Binary files /dev/null and b/dev-assets/doodads/trapdoors/left4.png differ diff --git a/dev-assets/doodads/trapdoors/right1.png b/dev-assets/doodads/trapdoors/right1.png new file mode 100644 index 0000000..85e4394 Binary files /dev/null and b/dev-assets/doodads/trapdoors/right1.png differ diff --git a/dev-assets/doodads/trapdoors/right2.png b/dev-assets/doodads/trapdoors/right2.png new file mode 100644 index 0000000..d4b090f Binary files /dev/null and b/dev-assets/doodads/trapdoors/right2.png differ diff --git a/dev-assets/doodads/trapdoors/right3.png b/dev-assets/doodads/trapdoors/right3.png new file mode 100644 index 0000000..73bc55b Binary files /dev/null and b/dev-assets/doodads/trapdoors/right3.png differ diff --git a/dev-assets/doodads/trapdoors/right4.png b/dev-assets/doodads/trapdoors/right4.png new file mode 100644 index 0000000..cf7a4e0 Binary files /dev/null and b/dev-assets/doodads/trapdoors/right4.png differ diff --git a/dev-assets/doodads/trapdoors/trapdoor.js b/dev-assets/doodads/trapdoors/trapdoor.js new file mode 100644 index 0000000..7c3571b --- /dev/null +++ b/dev-assets/doodads/trapdoors/trapdoor.js @@ -0,0 +1,71 @@ +function main() { + // What direction is the trapdoor facing? + // - Titles are like "Trapdoor Left" or "Trapdoor Right" + // - The default (down) is called just "Trapdoor" + var direction = Self.Doodad.Title.split(" ")[1]; + if (!direction) { + direction = "down"; + } + direction = direction.toLowerCase(); + + console.log("Trapdoor(%s) initialized", direction); + + var timer = 0; + + // Set our hitbox based on our orientation. + var thickness = 6; + var doodadSize = 72; + if (direction === "left") { + Self.SetHitbox(48, 0, doodadSize, doodadSize); + } else if (direction === "right") { + Self.SetHitbox(0, 0, thickness+4, doodadSize); + } else if (direction === "up") { + Self.SetHitbox(0, doodadSize - thickness, doodadSize, doodadSize); + } else { // Down, default. + Self.SetHitbox(0, 0, 72, 6); + } + + var animationSpeed = 100; + var opened = false; + + // Register our animations. + var frames = []; + for (var i = 1; i <= 4; i++) { + frames.push(direction + i); + } + + Self.AddAnimation("open", animationSpeed, frames); + frames.reverse(); + Self.AddAnimation("close", animationSpeed, frames); + + Events.OnCollide( function(e) { + if (opened) { + return; + } + + // Is the actor colliding our solid part? + if (e.InHitbox) { + // Are they touching our opening side? + if (direction === "left" && (e.Overlap.X+e.Overlap.W) < (doodadSize-thickness)) { + return false; + } else if (direction === "right" && e.Overlap.X > 0) { + return false; + } else if (direction === "up" && (e.Overlap.Y+e.Overlap.H) < doodadSize) { + return false; + } else if (direction === "down" && e.Overlap.Y > 0) { + return false; + } else { + opened = true; + Self.PlayAnimation("open", null); + } + } + }); + + Events.OnLeave(function() { + if (opened) { + Self.PlayAnimation("close", function() { + opened = false; + }); + } + }) +} diff --git a/dev-assets/doodads/trapdoors/up1.png b/dev-assets/doodads/trapdoors/up1.png new file mode 100644 index 0000000..686664b Binary files /dev/null and b/dev-assets/doodads/trapdoors/up1.png differ diff --git a/dev-assets/doodads/trapdoors/up2.png b/dev-assets/doodads/trapdoors/up2.png new file mode 100644 index 0000000..9898ed1 Binary files /dev/null and b/dev-assets/doodads/trapdoors/up2.png differ diff --git a/dev-assets/doodads/trapdoors/up3.png b/dev-assets/doodads/trapdoors/up3.png new file mode 100644 index 0000000..1d75b3d Binary files /dev/null and b/dev-assets/doodads/trapdoors/up3.png differ diff --git a/dev-assets/doodads/trapdoors/up4.png b/dev-assets/doodads/trapdoors/up4.png new file mode 100644 index 0000000..cd880a8 Binary files /dev/null and b/dev-assets/doodads/trapdoors/up4.png differ diff --git a/pkg/editor_ui.go b/pkg/editor_ui.go index 258437d..20721e5 100644 --- a/pkg/editor_ui.go +++ b/pkg/editor_ui.go @@ -19,7 +19,7 @@ import ( ) // Width of the panel frame. -var paletteWidth int32 = 150 +var paletteWidth int32 = 160 // EditorUI manages the user interface for the Editor Scene. type EditorUI struct { diff --git a/pkg/editor_ui_palette.go b/pkg/editor_ui_palette.go index a423b6f..783e383 100644 --- a/pkg/editor_ui_palette.go +++ b/pkg/editor_ui_palette.go @@ -1,6 +1,8 @@ package doodle import ( + "fmt" + "git.kirsle.net/apps/doodle/lib/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" @@ -66,16 +68,42 @@ func (u *EditorUI) setupPaletteFrame(window *ui.Window) *ui.Frame { // Draw the radio buttons for the palette. if u.Canvas != nil && u.Canvas.Palette != nil { for _, swatch := range u.Canvas.Palette.Swatches { + swFrame := ui.NewFrame(fmt.Sprintf("Swatch(%s) Button Frame", swatch.Name)) + + colorFrame := ui.NewFrame(fmt.Sprintf("Swatch(%s) Color Box", swatch.Name)) + colorFrame.Configure(ui.Config{ + Width: 16, + Height: 16, + Background: swatch.Color, + BorderSize: 1, + BorderStyle: ui.BorderSunken, + }) + swFrame.Pack(colorFrame, ui.Pack{ + Anchor: ui.W, + }) + label := ui.NewLabel(ui.Label{ Text: swatch.Name, Font: balance.StatusFont, }) label.Font.Color = swatch.Color.Darken(128) + swFrame.Pack(label, ui.Pack{ + Anchor: ui.W, + }) - btn := ui.NewRadioButton("palette", &u.selectedSwatch, swatch.Name, label) + btn := ui.NewRadioButton("palette", &u.selectedSwatch, swatch.Name, swFrame) btn.Handle(ui.Click, onClick) u.Supervisor.Add(btn) + btn.Compute(u.d.Engine) + swFrame.Configure(ui.Config{ + Height: label.Size().H, + + // TODO: magic number, trying to left-align + // the label by making the frame as wide as possible. + Width: paletteWidth - 16, + }) + frame.Pack(btn, ui.Pack{ Anchor: ui.N, Fill: true, diff --git a/pkg/play_scene.go b/pkg/play_scene.go index 4992ef3..0633f52 100644 --- a/pkg/play_scene.go +++ b/pkg/play_scene.go @@ -47,7 +47,8 @@ type PlayScene struct { debWorldIndex *string // Player character - Player *uix.Actor + Player *uix.Actor + playerJumpCounter int // limit jump length } // Name of the scene. @@ -349,17 +350,22 @@ func (s *PlayScene) movePlayer(ev *events.State) { var velocity render.Point - if ev.Down.Now { - velocity.Y = playerSpeed - } if ev.Left.Now { velocity.X = -playerSpeed } if ev.Right.Now { velocity.X = playerSpeed } - if ev.Up.Now { + if ev.Up.Now && (s.Player.Grounded() || s.playerJumpCounter >= 0) { velocity.Y = -playerSpeed + + if s.Player.Grounded() { + s.playerJumpCounter = 20 + } + } + + if !s.Player.Grounded() { + s.playerJumpCounter-- } // // Apply gravity if not grounded. diff --git a/pkg/uix/actor_collision.go b/pkg/uix/actor_collision.go index 47bae67..7befaa0 100644 --- a/pkg/uix/actor_collision.go +++ b/pkg/uix/actor_collision.go @@ -1,6 +1,7 @@ package uix import ( + "errors" "sync" "time" @@ -16,9 +17,11 @@ import ( // loopActorCollision is the Loop function that checks if pairs of // actors are colliding with each other, and handles their scripting // responses to such collisions. -// -// boxes: array of Actor bounding box rects. func (w *Canvas) loopActorCollision() error { + if w.scripting == nil { + return errors.New("Canvas.loopActorCollision: scripting engine not attached to Canvas") + } + var ( // Current time of this tick so we can advance animations. now = time.Now() diff --git a/pkg/uix/canvas.go b/pkg/uix/canvas.go index 8d4e119..13ea54e 100644 --- a/pkg/uix/canvas.go +++ b/pkg/uix/canvas.go @@ -215,8 +215,10 @@ func (w *Canvas) Loop(ev *events.State) error { } // Check collisions between actors. - if err := w.loopActorCollision(); err != nil { - log.Error("loopActorCollision: %s", err) + if w.scripting != nil { + if err := w.loopActorCollision(); err != nil { + log.Error("loopActorCollision: %s", err) + } } // If the canvas is editable, only care if it's over our space.