Prepare v0.8.0 for release
This commit is contained in:
parent
7866f618da
commit
f446ed9130
48
Changes.md
48
Changes.md
|
@ -1,15 +1,31 @@
|
|||
# Changes
|
||||
|
||||
## v0.8.0 (TBD)
|
||||
|
||||
To Do:
|
||||
* Thief needs animations
|
||||
* New levels
|
||||
## v0.8.0 (September 3, 2021)
|
||||
|
||||
This release brings some new features, new doodads, and new levels.
|
||||
|
||||
New features:
|
||||
|
||||
* **Checkpoints** for gameplay will ease the pain of dying to fire
|
||||
pixels or Anvils by teleporting you back to the checkpoint instead
|
||||
of resetting the whole level.
|
||||
* The **Doodad Properties** window while editing a doodad grants access
|
||||
to many features which were previously only available via the
|
||||
`doodad` tool, such as:
|
||||
* Edit metadata like the Title and Author of your doodad
|
||||
* Set the default hitbox of your doodad.
|
||||
* Attach, open, and delete the JavaScript for your doodad
|
||||
* Manage tags (key/value store) on your doodads: how you can
|
||||
communicate settings to the JavaScript which can receive the
|
||||
tags via `Self.GetTag("name")`
|
||||
* Some **Generic Doodad Scripts** are built in. Using only the in-game
|
||||
tools, it is possible to create custom doodads which have some basic
|
||||
in-game logic and you don't need to write any code. The generic
|
||||
scripts include:
|
||||
* Generic Solid: the hitbox is solid
|
||||
* Generic Fire: its hitbox harms the player
|
||||
* Generic Anvil: harmless, deadly when falling
|
||||
* Generic Collectible Item: it goes in your inventory
|
||||
* **All Characters are Playable!** Use the Link Tool to connect your
|
||||
Start Flag with another doodad on your level, and you will play
|
||||
**as** that doodad when the level starts. The Creature doodads are
|
||||
|
@ -31,6 +47,18 @@ New doodads have been added:
|
|||
* The **Blue Azulian** is now selectable from the Doodads menu. It
|
||||
behaves like the Red Azulian but moves at half the speed. The
|
||||
Azulians can pick up items and open doors.
|
||||
* The **Checkpoint Flag** will remember the player's spot in the level.
|
||||
Dying to fire pixels or Anvils no longer forces a restart of the
|
||||
level - you can resume from your last checkpoint, or the Start Flag
|
||||
by default.
|
||||
|
||||
New levels have been added:
|
||||
|
||||
* **Castle.level:** introduces the new Thief character. Castle-themed
|
||||
level showing off various new doodads.
|
||||
* **Thief 1.level:** a level where you play as the Thief! You need to
|
||||
steal Small Keys from dozens of Azulians and even steal items back
|
||||
from another Thief who has already stolen some of the keys.
|
||||
|
||||
Some doodads have changed behavior:
|
||||
|
||||
|
@ -52,12 +80,11 @@ The user interface has been improved:
|
|||
5. All: a classic view paging over all doodads (and doodads
|
||||
not fitting any of the above categories).
|
||||
|
||||
doodad edit-doodad --tag "categories=doors,gizmos" filename.doodad
|
||||
|
||||
New functions are available in the JavaScript API for custom doodads:
|
||||
|
||||
* FailLevel(message string): global function that kills the player
|
||||
with a custom death message.
|
||||
* SetCheckpoint(Point): set the player respawn location
|
||||
* Self.MoveTo(Point(x, y int))
|
||||
* Self.IsPlayer() bool
|
||||
* Self.SetInventory(bool): turn on or off inventory. Keys and other
|
||||
|
@ -69,6 +96,7 @@ New functions are available in the JavaScript API for custom doodads:
|
|||
* Self.RemoveItem(filename string, quantity int)
|
||||
* Self.HasItem(filename string)
|
||||
* Self.Inventory() map[string]int
|
||||
* Self.Hitbox() - also see Self.Hitbox.IsEmpty()
|
||||
|
||||
The Events.OnLeave() callback now receives a CollideEvent argument,
|
||||
like OnCollide, instead of the useless actor ID string. Notable
|
||||
|
@ -87,6 +115,12 @@ Other miscellaneous changes:
|
|||
* A **death barrier** will prevent Boy from falling forever on unbounded
|
||||
maps should he somehow fall off the level. The death barrier is a
|
||||
Y value 1,000 pixels below the lowest pixel on your map.
|
||||
* Mobile doodads no longer "moonwalk" when they change directions.
|
||||
* A new color is added to all default palettes: "hint" (pink) for
|
||||
writing hint notes.
|
||||
* A maximum scroll speed on the "follow the player character" logic
|
||||
makes for cooler animations when the character teleports around.
|
||||
* Levels and Doodads are now sorted on the Open menu.
|
||||
|
||||
## v0.7.2 (July 19 2021)
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ func init() {
|
|||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() < 2 {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
"Usage: doodad convert <input.png...> <output.doodad>\n"+
|
||||
" Image file types: png, bmp\n"+
|
||||
" Drawing file types: level, doodad",
|
||||
|
@ -59,7 +59,7 @@ func init() {
|
|||
// Parse the chroma key.
|
||||
chroma, err := render.HexColor(c.String("key"))
|
||||
if err != nil {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
"Chrome key not a valid color: "+err.Error(),
|
||||
1,
|
||||
)
|
||||
|
@ -76,22 +76,22 @@ func init() {
|
|||
if inputType == extPNG || inputType == extBMP {
|
||||
if outputType == extLevel || outputType == extDoodad {
|
||||
if err := imageToDrawing(c, chroma, inputFiles, outputFile); err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return cli.NewExitError("Image inputs can only output to Doodle drawings", 1)
|
||||
return cli.Exit("Image inputs can only output to Doodle drawings", 1)
|
||||
} else if inputType == extLevel || inputType == extDoodad {
|
||||
if outputType == extPNG || outputType == extBMP {
|
||||
if err := drawingToImage(c, chroma, inputFiles, outputFile); err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return cli.NewExitError("Doodle drawing inputs can only output to image files", 1)
|
||||
return cli.Exit("Doodle drawing inputs can only output to image files", 1)
|
||||
}
|
||||
|
||||
return cli.NewExitError("File types must be: png, bmp, level, doodad", 1)
|
||||
return cli.Exit("File types must be: png, bmp, level, doodad", 1)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -107,13 +107,13 @@ func imageToDrawing(c *cli.Context, chroma render.Color, inputFiles []string, ou
|
|||
for i, filename := range inputFiles {
|
||||
reader, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
|
||||
img, format, err := image.Decode(reader)
|
||||
log.Info("Parsed image %d of %d. Format: %s", i+1, len(inputFiles), format)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
|
||||
// Get the bounding box information of the source image.
|
||||
|
@ -131,7 +131,7 @@ func imageToDrawing(c *cli.Context, chroma render.Color, inputFiles []string, ou
|
|||
chunkSize = imageSize.Y
|
||||
}
|
||||
} else if imageSize != imageBounds {
|
||||
return cli.NewExitError("your source images are not all the same dimensions", 1)
|
||||
return cli.Exit("your source images are not all the same dimensions", 1)
|
||||
}
|
||||
|
||||
images = append(images, img)
|
||||
|
@ -177,7 +177,7 @@ func imageToDrawing(c *cli.Context, chroma render.Color, inputFiles []string, ou
|
|||
|
||||
err := doodad.WriteJSON(outputFile)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
case extLevel:
|
||||
log.Info("Output is a Level file: %s", outputFile)
|
||||
|
@ -198,10 +198,10 @@ func imageToDrawing(c *cli.Context, chroma render.Color, inputFiles []string, ou
|
|||
|
||||
err := lvl.WriteJSON(outputFile)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
default:
|
||||
return cli.NewExitError("invalid output file: not a Doodle drawing", 1)
|
||||
return cli.Exit("invalid output file: not a Doodle drawing", 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -3,10 +3,12 @@ package commands
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.kirsle.net/apps/doodle/pkg/doodads"
|
||||
"git.kirsle.net/apps/doodle/pkg/log"
|
||||
"git.kirsle.net/go/render"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
@ -32,6 +34,10 @@ func init() {
|
|||
Name: "author",
|
||||
Usage: "set the doodad author",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "hitbox",
|
||||
Usage: "set the doodad hitbox (X,Y,W,H or W,H format)",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "tag",
|
||||
Aliases: []string{"t"},
|
||||
|
@ -56,7 +62,7 @@ func init() {
|
|||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
"Usage: doodad edit-doodad <filename.doodad>",
|
||||
1,
|
||||
)
|
||||
|
@ -100,6 +106,34 @@ func editDoodad(c *cli.Context, filename string) error {
|
|||
modified = true
|
||||
}
|
||||
|
||||
if c.String("hitbox") != "" {
|
||||
// Setting a hitbox, parse it out.
|
||||
parts := strings.Split(c.String("hitbox"), ",")
|
||||
var ints []int
|
||||
for _, part := range parts {
|
||||
a, err := strconv.Atoi(strings.TrimSpace(part))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ints = append(ints, a)
|
||||
}
|
||||
|
||||
if len(ints) == 2 {
|
||||
dd.Hitbox = render.NewRect(ints[0], ints[1])
|
||||
modified = true
|
||||
} else if len(ints) == 4 {
|
||||
dd.Hitbox = render.Rect{
|
||||
X: ints[0],
|
||||
Y: ints[1],
|
||||
W: ints[2],
|
||||
H: ints[3],
|
||||
}
|
||||
modified = true
|
||||
} else {
|
||||
return cli.Exit("Hitbox should be in X,Y,W,H or just W,H format, 2 or 4 numbers.", 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Tags.
|
||||
tags := c.StringSlice("tag")
|
||||
if len(tags) > 0 {
|
||||
|
@ -152,7 +186,7 @@ func editDoodad(c *cli.Context, filename string) error {
|
|||
|
||||
if modified {
|
||||
if err := dd.WriteJSON(filename); err != nil {
|
||||
return cli.NewExitError(fmt.Sprintf("Write error: %s", err), 1)
|
||||
return cli.Exit(fmt.Sprintf("Write error: %s", err), 1)
|
||||
}
|
||||
} else {
|
||||
log.Warn("Note: No changes made to level")
|
||||
|
|
|
@ -58,7 +58,7 @@ func init() {
|
|||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
"Usage: doodad edit-level <filename.level>",
|
||||
1,
|
||||
)
|
||||
|
@ -151,7 +151,7 @@ func editLevel(c *cli.Context, filename string) error {
|
|||
|
||||
if modified {
|
||||
if err := lvl.WriteFile(filename); err != nil {
|
||||
return cli.NewExitError(fmt.Sprintf("Write error: %s", err), 1)
|
||||
return cli.Exit(fmt.Sprintf("Write error: %s", err), 1)
|
||||
}
|
||||
} else {
|
||||
log.Warn("Note: No changes made to level")
|
||||
|
|
|
@ -26,7 +26,7 @@ func init() {
|
|||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() != 2 {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
"Usage: doodad install-script <script.js> <filename.doodad>",
|
||||
1,
|
||||
)
|
||||
|
@ -41,12 +41,12 @@ func init() {
|
|||
// Read the JavaScript source.
|
||||
javascript, err := ioutil.ReadFile(scriptFile)
|
||||
if err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
return cli.Exit(err.Error(), 1)
|
||||
}
|
||||
|
||||
doodad, err := doodads.LoadJSON(doodadFile)
|
||||
if err != nil {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
fmt.Sprintf("Failed to read doodad file: %s", err),
|
||||
1,
|
||||
)
|
||||
|
|
|
@ -34,9 +34,9 @@ func init() {
|
|||
Usage: "print the script from a doodad file and exit",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "attachment",
|
||||
Name: "attachment",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "print the contents of the attached filename to terminal",
|
||||
Usage: "print the contents of the attached filename to terminal",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
|
@ -46,7 +46,7 @@ func init() {
|
|||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
return cli.NewExitError(
|
||||
return cli.Exit(
|
||||
"Usage: doodad show <.level .doodad ...>",
|
||||
1,
|
||||
)
|
||||
|
@ -58,12 +58,12 @@ func init() {
|
|||
case enum.LevelExt:
|
||||
if err := showLevel(c, filename); err != nil {
|
||||
log.Error(err.Error())
|
||||
return cli.NewExitError("Error", 1)
|
||||
return cli.Exit("Error", 1)
|
||||
}
|
||||
case enum.DoodadExt:
|
||||
if err := showDoodad(c, filename); err != nil {
|
||||
log.Error(err.Error())
|
||||
return cli.NewExitError("Error", 1)
|
||||
return cli.Exit("Error", 1)
|
||||
}
|
||||
default:
|
||||
log.Error("File %s: not a level or doodad", filename)
|
||||
|
@ -172,6 +172,7 @@ func showDoodad(c *cli.Context, filename string) error {
|
|||
fmt.Printf(" Game version: %s\n", dd.GameVersion)
|
||||
fmt.Printf(" Doodad title: %s\n", dd.Title)
|
||||
fmt.Printf(" Author: %s\n", dd.Author)
|
||||
fmt.Printf(" Hitbox: %s\n", dd.Hitbox)
|
||||
fmt.Printf(" Locked: %+v\n", dd.Locked)
|
||||
fmt.Printf(" Hidden: %+v\n", dd.Hidden)
|
||||
fmt.Printf(" Script size: %d bytes\n", len(dd.Script))
|
||||
|
|
|
@ -4,7 +4,7 @@ package branding
|
|||
const (
|
||||
AppName = "Sketchy Maze"
|
||||
Summary = "A drawing-based maze game"
|
||||
Version = "0.7.2"
|
||||
Version = "0.8.0"
|
||||
Website = "https://www.sketchymaze.com"
|
||||
Copyright = "2021 Noah Petherbridge"
|
||||
Byline = "a game by Noah Petherbridge."
|
||||
|
|
|
@ -385,8 +385,8 @@ func (s *MainScene) Draw(d *Doodle) error {
|
|||
|
||||
// Version label
|
||||
s.labelVersion.MoveTo(render.Point{
|
||||
X: (d.width / 2) - (s.labelVersion.Size().W / 2),
|
||||
Y: s.labelSubtitle.Point().Y + s.labelSubtitle.Size().H + 8,
|
||||
X: (d.width) - (s.labelVersion.Size().W) - 20,
|
||||
Y: 20,
|
||||
})
|
||||
s.labelVersion.Present(d.Engine, s.labelVersion.Point())
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user