doodle/pkg/userdir/userdir.go

135 lines
3.6 KiB
Go
Raw Permalink Normal View History

Draw Actors Embedded in Levels in Edit Mode Add the JSON format for embedding Actors (Doodad instances) inside of a Level. I made a test map that manually inserted a couple of actors. Actors are given to the Canvas responsible for the Level via the function `InstallActors()`. So it means you'll call LoadLevel and then InstallActors to hook everything up. The Canvas creates sub-Canvas widgets from each Actor. After drawing the main level geometry from the Canvas.Chunker, it calls the drawActors() function which does the same but for Actors. Levels keep a global map of all Actors that exist. For any Actors that are visible within the Viewport, their sub-Canvas widgets are presented appropriately on top of the parent Canvas. In case their sub-Canvas overlaps the parent's boundaries, their sub-Canvas is resized and moved appropriately. - Allow the MainWindow to be resized at run time, and the UI recalculates its sizing and position. - Made the in-game Shell properties editable via environment variables. The kirsle.env file sets a blue and pink color scheme. - Begin the ground work for Levels and Doodads to embed files inside their data via the level.FileSystem type. - UI: Labels can now contain line break characters. It will appropriately render multiple lines of render.Text and take into account the proper BoxSize to contain them all. - Add environment variable DOODLE_DEBUG_ALL=true that will turn on ALL debug overlay and visualization options. - Add debug overlay to "tag" each Canvas widget with some of its details, like its Name and World Position. Can be enabled with the environment variable DEBUG_CANVAS_LABEL=true - Improved the FPS debug overlay to show in labeled columns and multiple colors, with easy ability to add new data points to it.
2018-10-19 20:31:58 +00:00
package userdir
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/kirsle/configdir"
)
// Profile Directory settings.
var (
ConfigDirectoryName = "doodle"
ProfileDirectory string
LevelDirectory string
DoodadDirectory string
CacheDirectory string
FontDirectory string
)
// File extensions
const (
extLevel = ".level"
extDoodad = ".doodad"
)
func init() {
// Profile directory contains the user's levels and doodads.
ProfileDirectory = configdir.LocalConfig(ConfigDirectoryName)
LevelDirectory = configdir.LocalConfig(ConfigDirectoryName, "levels")
DoodadDirectory = configdir.LocalConfig(ConfigDirectoryName, "doodads")
// Cache directory to extract font files to.
CacheDirectory = configdir.LocalCache(ConfigDirectoryName)
FontDirectory = configdir.LocalCache(ConfigDirectoryName, "fonts")
// Ensure all the directories exist.
configdir.MakePath(LevelDirectory)
configdir.MakePath(DoodadDirectory)
configdir.MakePath(FontDirectory)
}
// LevelPath will turn a "simple" filename into an absolute path in the user's
// local levels folder. If the filename already contains slashes, it is returned
// as-is as an absolute or relative path.
func LevelPath(filename string) string {
return resolvePath(LevelDirectory, filename, extLevel)
}
// DoodadPath is like LevelPath but for Doodad files.
func DoodadPath(filename string) string {
return resolvePath(DoodadDirectory, filename, extDoodad)
}
// CacheFilename returns a path to a file in the cache folder. Send in path
// components and not literal slashes, like
// CacheFilename("images", "chunks", "id.bmp")
func CacheFilename(filename ...string) string {
paths := append([]string{CacheDirectory}, filename...)
dir := paths[:len(paths)-1]
configdir.MakePath(filepath.Join(dir...))
return filepath.Join(paths[0], filepath.Join(paths[1:]...))
}
Draw Actors Embedded in Levels in Edit Mode Add the JSON format for embedding Actors (Doodad instances) inside of a Level. I made a test map that manually inserted a couple of actors. Actors are given to the Canvas responsible for the Level via the function `InstallActors()`. So it means you'll call LoadLevel and then InstallActors to hook everything up. The Canvas creates sub-Canvas widgets from each Actor. After drawing the main level geometry from the Canvas.Chunker, it calls the drawActors() function which does the same but for Actors. Levels keep a global map of all Actors that exist. For any Actors that are visible within the Viewport, their sub-Canvas widgets are presented appropriately on top of the parent Canvas. In case their sub-Canvas overlaps the parent's boundaries, their sub-Canvas is resized and moved appropriately. - Allow the MainWindow to be resized at run time, and the UI recalculates its sizing and position. - Made the in-game Shell properties editable via environment variables. The kirsle.env file sets a blue and pink color scheme. - Begin the ground work for Levels and Doodads to embed files inside their data via the level.FileSystem type. - UI: Labels can now contain line break characters. It will appropriately render multiple lines of render.Text and take into account the proper BoxSize to contain them all. - Add environment variable DOODLE_DEBUG_ALL=true that will turn on ALL debug overlay and visualization options. - Add debug overlay to "tag" each Canvas widget with some of its details, like its Name and World Position. Can be enabled with the environment variable DEBUG_CANVAS_LABEL=true - Improved the FPS debug overlay to show in labeled columns and multiple colors, with easy ability to add new data points to it.
2018-10-19 20:31:58 +00:00
// ListDoodads returns a listing of all available doodads.
func ListDoodads() ([]string, error) {
var names []string
files, err := ioutil.ReadDir(DoodadDirectory)
if err != nil {
return names, err
}
for _, file := range files {
name := file.Name()
if strings.HasSuffix(strings.ToLower(name), extDoodad) {
names = append(names, name)
}
}
return names, nil
}
// resolvePath is the inner logic for LevelPath and DoodadPath.
func resolvePath(directory, filename, extension string) string {
if strings.Contains(filename, "/") {
return filename
}
// Attach the file extension?
if strings.ToLower(filepath.Ext(filename)) != extension {
filename += extension
}
return filepath.Join(directory, filename)
}
// ResolvePath takes an ambiguous simple filename and searches for a Level or
// Doodad that matches. Returns a blank string if no files found.
//
// Pass a true value for `one` if you are intending to create the file. It will
// only test one filepath and return the first one, regardless if the file
// existed. So the filename should have a ".level" or ".doodad" extension and
// then this path will resolve the ProfileDirectory of the file.
func ResolvePath(filename, extension string, one bool) string {
// If the filename exists outright, return it.
if _, err := os.Stat(filename); !os.IsNotExist(err) {
return filename
}
var paths []string
if extension == extLevel {
paths = append(paths, filepath.Join(LevelDirectory, filename))
} else if extension == extDoodad {
paths = append(paths, filepath.Join(DoodadDirectory, filename))
} else {
paths = append(paths,
filepath.Join(LevelDirectory, filename+".level"),
filepath.Join(DoodadDirectory, filename+".doodad"),
)
}
for _, test := range paths {
if _, err := os.Stat(test); os.IsNotExist(err) {
continue
}
return test
}
return ""
}