Refactor variable name for Scene implementors
This commit is contained in:
parent
90f1704886
commit
cf6d5d999c
54
Ideas.md
54
Ideas.md
|
@ -2,10 +2,64 @@
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
|
* [Major Milestones](#major-milestones)
|
||||||
* [File Formats](#file-formats)
|
* [File Formats](#file-formats)
|
||||||
* [Text Console](#text-console)
|
* [Text Console](#text-console)
|
||||||
* [Doodads](#doodads)
|
* [Doodads](#doodads)
|
||||||
|
|
||||||
|
# Major Milestones
|
||||||
|
|
||||||
|
The major milestones of the game are roughly:
|
||||||
|
|
||||||
|
* [x] Prototype: make a simple SDL painting program that does nothing special.
|
||||||
|
* [ ] Simple Platformer: be able to toggle between "edit mode" and "play mode"
|
||||||
|
and control a character who can walk around your level and bump into the
|
||||||
|
solid geometry you've drawn (no objects yet, just the basics here).
|
||||||
|
* [ ] Add Doodads (buttons, doors, the player character themself, enemies, ...)
|
||||||
|
* Share a lot in common with map drawings, in that they're hand-drawn, will
|
||||||
|
share a similar file format.
|
||||||
|
* Available doodads can be dragged/dropped into maps.
|
||||||
|
* The player character should be a Doodad under the hood to keep it from
|
||||||
|
becoming too special (read: easier to make the game multiplayer in the
|
||||||
|
future by putting a "networked user" in control of a doodad instead of
|
||||||
|
the keyboard/mouse).
|
||||||
|
* [ ] **Version 1:** Single Player Campaign and Editor. This is the minimum
|
||||||
|
feature set for a first public release of the game. Required features:
|
||||||
|
* The game should ship with a single-player "campaign mode" of pre-made maps
|
||||||
|
that link to one another in sequence. i.e. 100 levels that the player can
|
||||||
|
play through in a certain order.
|
||||||
|
* It must include the level editor feature so players can create and share
|
||||||
|
their own maps.
|
||||||
|
* Dev tools may be clunky to use at this stage; i.e. players creating custom
|
||||||
|
Doodads will need to use external tools outside the game (i.e. code editors
|
||||||
|
to program the JavaScript logic of the doodad), but everything should be
|
||||||
|
available and possible for modders to extend the game with custom features.
|
||||||
|
* Game should have a good mixture of doodads and features: doors, buttons,
|
||||||
|
switches, etc. and make a usable single player experience.
|
||||||
|
* World sizes might be limited in dimension.
|
||||||
|
* [ ] **Version 2:** Multiplayer Collaborative World Builder. This is a
|
||||||
|
"pie in the sky" long-term vision for the game, to make it multiplayer,
|
||||||
|
hopefully addicting, and possibly slightly Minecraft-like. Some ideas:
|
||||||
|
* Players can self-host their own multiplayer servers to draw worlds with
|
||||||
|
friends.
|
||||||
|
* A new server would initialize as a blank white level with maybe a single
|
||||||
|
platform (a line) for players to spawn on.
|
||||||
|
* Gameplay is a mixture of players drawing the world and playing on it.
|
||||||
|
* i.e.: one player could be drawing himself a castle and, as he's drawing,
|
||||||
|
another player could be walking on the lines being laid down, etc.
|
||||||
|
* World size should be infinite.
|
||||||
|
* Version 1 can have limited world sizes as it will probably be easier,
|
||||||
|
but this should be opened up eventually.
|
||||||
|
* Besides creative mode, other game modes should be explored eventually...
|
||||||
|
* Automatically-spawning enemy doodads that you have to fight?
|
||||||
|
* Procedurally generated default maps? Having a blank white canvas is
|
||||||
|
sorta like Superflat worlds in Minecraft, whereas normal Minecraft worlds
|
||||||
|
come with randomly generated terrain to start from.
|
||||||
|
* Find a way to incorporate drawing into a survival mode game? i.e. instead
|
||||||
|
of a "Creative Mode" style, "unlimited ink to draw as much as you want,"
|
||||||
|
have some natural limiter where players have to spend time in Play Mode
|
||||||
|
to be able to change the map.
|
||||||
|
|
||||||
# File Formats
|
# File Formats
|
||||||
|
|
||||||
* The file formats should eventually have a **Protocol Buffers** binary
|
* The file formats should eventually have a **Protocol Buffers** binary
|
||||||
|
|
|
@ -29,27 +29,27 @@ func (s *EditorScene) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the editor scene.
|
// Setup the editor scene.
|
||||||
func (e *EditorScene) Setup(d *Doodle) error {
|
func (s *EditorScene) Setup(d *Doodle) error {
|
||||||
if e.pixelHistory == nil {
|
if s.pixelHistory == nil {
|
||||||
e.pixelHistory = []Pixel{}
|
s.pixelHistory = []Pixel{}
|
||||||
}
|
}
|
||||||
if e.canvas == nil {
|
if s.canvas == nil {
|
||||||
e.canvas = Grid{}
|
s.canvas = Grid{}
|
||||||
}
|
}
|
||||||
e.width = d.width // TODO: canvas width = copy the window size
|
s.width = d.width // TODO: canvas width = copy the window size
|
||||||
e.height = d.height
|
s.height = d.height
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop the editor scene.
|
// Loop the editor scene.
|
||||||
func (e *EditorScene) Loop(d *Doodle) error {
|
func (s *EditorScene) Loop(d *Doodle) error {
|
||||||
ev := d.events
|
ev := d.events
|
||||||
|
|
||||||
// Taking a screenshot?
|
// Taking a screenshot?
|
||||||
if ev.ScreenshotKey.Pressed() {
|
if ev.ScreenshotKey.Pressed() {
|
||||||
log.Info("Taking a screenshot")
|
log.Info("Taking a screenshot")
|
||||||
e.Screenshot()
|
s.Screenshot()
|
||||||
e.SaveLevel()
|
s.SaveLevel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the canvas and fill it with white.
|
// Clear the canvas and fill it with white.
|
||||||
|
@ -67,25 +67,25 @@ func (e *EditorScene) Loop(d *Doodle) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append unique new pixels.
|
// Append unique new pixels.
|
||||||
if len(e.pixelHistory) == 0 || e.pixelHistory[len(e.pixelHistory)-1] != pixel {
|
if len(s.pixelHistory) == 0 || s.pixelHistory[len(s.pixelHistory)-1] != pixel {
|
||||||
// If not a start pixel, make the delta coord the previous one.
|
// If not a start pixel, make the delta coord the previous one.
|
||||||
if !pixel.start && len(e.pixelHistory) > 0 {
|
if !pixel.start && len(s.pixelHistory) > 0 {
|
||||||
prev := e.pixelHistory[len(e.pixelHistory)-1]
|
prev := s.pixelHistory[len(s.pixelHistory)-1]
|
||||||
pixel.dx = prev.x
|
pixel.dx = prev.x
|
||||||
pixel.dy = prev.y
|
pixel.dy = prev.y
|
||||||
}
|
}
|
||||||
|
|
||||||
e.pixelHistory = append(e.pixelHistory, pixel)
|
s.pixelHistory = append(s.pixelHistory, pixel)
|
||||||
|
|
||||||
// Save in the pixel canvas map.
|
// Save in the pixel canvas map.
|
||||||
e.canvas[pixel] = nil
|
s.canvas[pixel] = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.renderer.SetDrawColor(0, 0, 0, 255)
|
d.renderer.SetDrawColor(0, 0, 0, 255)
|
||||||
for i, pixel := range e.pixelHistory {
|
for i, pixel := range s.pixelHistory {
|
||||||
if !pixel.start && i > 0 {
|
if !pixel.start && i > 0 {
|
||||||
prev := e.pixelHistory[i-1]
|
prev := s.pixelHistory[i-1]
|
||||||
if prev.x == pixel.x && prev.y == pixel.y {
|
if prev.x == pixel.x && prev.y == pixel.y {
|
||||||
d.renderer.DrawPoint(pixel.x, pixel.y)
|
d.renderer.DrawPoint(pixel.x, pixel.y)
|
||||||
} else {
|
} else {
|
||||||
|
@ -109,9 +109,9 @@ func (e *EditorScene) Loop(d *Doodle) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadLevel loads a level from disk.
|
// LoadLevel loads a level from disk.
|
||||||
func (e *EditorScene) LoadLevel(filename string) error {
|
func (s *EditorScene) LoadLevel(filename string) error {
|
||||||
e.pixelHistory = []Pixel{}
|
s.pixelHistory = []Pixel{}
|
||||||
e.canvas = Grid{}
|
s.canvas = Grid{}
|
||||||
|
|
||||||
m, err := level.LoadJSON(filename)
|
m, err := level.LoadJSON(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,21 +126,21 @@ func (e *EditorScene) LoadLevel(filename string) error {
|
||||||
dx: point.X,
|
dx: point.X,
|
||||||
dy: point.Y,
|
dy: point.Y,
|
||||||
}
|
}
|
||||||
e.pixelHistory = append(e.pixelHistory, pixel)
|
s.pixelHistory = append(s.pixelHistory, pixel)
|
||||||
e.canvas[pixel] = nil
|
s.canvas[pixel] = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveLevel saves the level to disk.
|
// SaveLevel saves the level to disk.
|
||||||
func (e *EditorScene) SaveLevel() {
|
func (s *EditorScene) SaveLevel() {
|
||||||
m := level.Level{
|
m := level.Level{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
Title: "Alpha",
|
Title: "Alpha",
|
||||||
Author: os.Getenv("USER"),
|
Author: os.Getenv("USER"),
|
||||||
Width: e.width,
|
Width: s.width,
|
||||||
Height: e.height,
|
Height: s.height,
|
||||||
Palette: []level.Palette{
|
Palette: []level.Palette{
|
||||||
level.Palette{
|
level.Palette{
|
||||||
Color: "#000000",
|
Color: "#000000",
|
||||||
|
@ -150,7 +150,7 @@ func (e *EditorScene) SaveLevel() {
|
||||||
Pixels: []level.Pixel{},
|
Pixels: []level.Pixel{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for pixel := range e.canvas {
|
for pixel := range s.canvas {
|
||||||
for point := range draw.Line(pixel.x, pixel.y, pixel.dx, pixel.dy) {
|
for point := range draw.Line(pixel.x, pixel.y, pixel.dx, pixel.dy) {
|
||||||
m.Pixels = append(m.Pixels, level.Pixel{
|
m.Pixels = append(m.Pixels, level.Pixel{
|
||||||
X: point.X,
|
X: point.X,
|
||||||
|
@ -177,18 +177,18 @@ func (e *EditorScene) SaveLevel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Screenshot saves the level canvas to disk as a PNG image.
|
// Screenshot saves the level canvas to disk as a PNG image.
|
||||||
func (e *EditorScene) Screenshot() {
|
func (s *EditorScene) Screenshot() {
|
||||||
screenshot := image.NewRGBA(image.Rect(0, 0, int(e.width), int(e.height)))
|
screenshot := image.NewRGBA(image.Rect(0, 0, int(s.width), int(s.height)))
|
||||||
|
|
||||||
// White-out the image.
|
// White-out the image.
|
||||||
for x := 0; x < int(e.width); x++ {
|
for x := 0; x < int(s.width); x++ {
|
||||||
for y := 0; y < int(e.height); y++ {
|
for y := 0; y < int(s.height); y++ {
|
||||||
screenshot.Set(x, y, image.White)
|
screenshot.Set(x, y, image.White)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the dots we drew.
|
// Fill in the dots we drew.
|
||||||
for pixel := range e.canvas {
|
for pixel := range s.canvas {
|
||||||
// A line or a dot?
|
// A line or a dot?
|
||||||
if pixel.x == pixel.dx && pixel.y == pixel.dy {
|
if pixel.x == pixel.dx && pixel.y == pixel.dy {
|
||||||
screenshot.Set(int(pixel.x), int(pixel.y), image.Black)
|
screenshot.Set(int(pixel.x), int(pixel.y), image.Black)
|
||||||
|
|
|
@ -92,8 +92,8 @@ func (s *PlayScene) PollEvents(ev *events.State) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadLevel loads a level from disk.
|
// LoadLevel loads a level from disk.
|
||||||
func (e *PlayScene) LoadLevel(filename string) error {
|
func (s *PlayScene) LoadLevel(filename string) error {
|
||||||
e.canvas = Grid{}
|
s.canvas = Grid{}
|
||||||
|
|
||||||
m, err := level.LoadJSON(filename)
|
m, err := level.LoadJSON(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -105,7 +105,7 @@ func (e *PlayScene) LoadLevel(filename string) error {
|
||||||
x: point.X,
|
x: point.X,
|
||||||
y: point.Y,
|
y: point.Y,
|
||||||
}
|
}
|
||||||
e.canvas[pixel] = nil
|
s.canvas[pixel] = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue
Block a user