Refactor variable name for Scene implementors

This commit is contained in:
Noah 2018-07-21 15:11:00 -07:00
parent 90f1704886
commit cf6d5d999c
3 changed files with 88 additions and 34 deletions

View File

@ -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

View File

@ -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)

View File

@ -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