Refactor grid to use level.Pixel and clean up collision between Edit and Play
This commit is contained in:
parent
e141203c4b
commit
c3fd2e63cb
|
@ -1,6 +1,7 @@
|
||||||
package doodads
|
package doodads
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.kirsle.net/apps/doodle/level"
|
||||||
"git.kirsle.net/apps/doodle/render"
|
"git.kirsle.net/apps/doodle/render"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ func CollidesWithGrid(d Doodad, grid *render.Grid) (Collide, bool) {
|
||||||
|
|
||||||
// Bottom edge.
|
// Bottom edge.
|
||||||
for point := range render.IterLine2(bottomLeft, bottomRight) {
|
for point := range render.IterLine2(bottomLeft, bottomRight) {
|
||||||
if grid.Exists(render.Pixel{
|
if grid.Exists(level.Pixel{
|
||||||
X: point.X,
|
X: point.X,
|
||||||
Y: point.Y,
|
Y: point.Y,
|
||||||
}) {
|
}) {
|
||||||
|
@ -71,7 +72,7 @@ func CollidesWithGrid(d Doodad, grid *render.Grid) (Collide, bool) {
|
||||||
|
|
||||||
// Top edge.
|
// Top edge.
|
||||||
for point := range render.IterLine2(topLeft, topRight) {
|
for point := range render.IterLine2(topLeft, topRight) {
|
||||||
if grid.Exists(render.Pixel{
|
if grid.Exists(level.Pixel{
|
||||||
X: point.X,
|
X: point.X,
|
||||||
Y: point.Y,
|
Y: point.Y,
|
||||||
}) {
|
}) {
|
||||||
|
@ -84,7 +85,7 @@ func CollidesWithGrid(d Doodad, grid *render.Grid) (Collide, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for point := range render.IterLine2(topLeft, bottomLeft) {
|
for point := range render.IterLine2(topLeft, bottomLeft) {
|
||||||
if grid.Exists(render.Pixel{
|
if grid.Exists(level.Pixel{
|
||||||
X: point.X,
|
X: point.X,
|
||||||
Y: point.Y,
|
Y: point.Y,
|
||||||
}) {
|
}) {
|
||||||
|
@ -97,7 +98,7 @@ func CollidesWithGrid(d Doodad, grid *render.Grid) (Collide, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for point := range render.IterLine2(topRight, bottomRight) {
|
for point := range render.IterLine2(topRight, bottomRight) {
|
||||||
if grid.Exists(render.Pixel{
|
if grid.Exists(level.Pixel{
|
||||||
X: point.X,
|
X: point.X,
|
||||||
Y: point.Y,
|
Y: point.Y,
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.kirsle.net/apps/doodle/draw"
|
|
||||||
"git.kirsle.net/apps/doodle/events"
|
"git.kirsle.net/apps/doodle/events"
|
||||||
"git.kirsle.net/apps/doodle/level"
|
"git.kirsle.net/apps/doodle/level"
|
||||||
"git.kirsle.net/apps/doodle/render"
|
"git.kirsle.net/apps/doodle/render"
|
||||||
|
@ -22,7 +21,8 @@ type EditorScene struct {
|
||||||
Canvas render.Grid
|
Canvas render.Grid
|
||||||
|
|
||||||
// History of all the pixels placed by the user.
|
// History of all the pixels placed by the user.
|
||||||
pixelHistory []render.Pixel
|
pixelHistory []level.Pixel
|
||||||
|
lastPixel *level.Pixel // last pixel placed while mouse down and dragging
|
||||||
canvas render.Grid
|
canvas render.Grid
|
||||||
filename string // Last saved filename.
|
filename string // Last saved filename.
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ func (s *EditorScene) Setup(d *Doodle) error {
|
||||||
d.Flash("Editor Mode. Press 'P' to play this map.")
|
d.Flash("Editor Mode. Press 'P' to play this map.")
|
||||||
|
|
||||||
if s.pixelHistory == nil {
|
if s.pixelHistory == nil {
|
||||||
s.pixelHistory = []render.Pixel{}
|
s.pixelHistory = []level.Pixel{}
|
||||||
}
|
}
|
||||||
if s.canvas == nil {
|
if s.canvas == nil {
|
||||||
log.Debug("EditorScene: Setting default canvas to an empty grid")
|
log.Debug("EditorScene: Setting default canvas to an empty grid")
|
||||||
|
@ -92,33 +92,37 @@ func (s *EditorScene) Loop(d *Doodle, ev *events.State) error {
|
||||||
|
|
||||||
// Clicking? Log all the pixels while doing so.
|
// Clicking? Log all the pixels while doing so.
|
||||||
if ev.Button1.Now {
|
if ev.Button1.Now {
|
||||||
log.Warn("Button1: %+v", ev.Button1)
|
// log.Warn("Button1: %+v", ev.Button1)
|
||||||
pixel := render.Pixel{
|
lastPixel := s.lastPixel
|
||||||
Start: ev.Button1.Pressed(),
|
pixel := level.Pixel{
|
||||||
X: ev.CursorX.Now,
|
X: ev.CursorX.Now,
|
||||||
Y: ev.CursorY.Now,
|
Y: ev.CursorY.Now,
|
||||||
DX: ev.CursorX.Last,
|
|
||||||
DY: ev.CursorY.Last,
|
|
||||||
}
|
|
||||||
if pixel.Start {
|
|
||||||
log.Warn("START PIXEL %+v", pixel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append unique new pixels.
|
// Append unique new pixels.
|
||||||
if len(s.pixelHistory) == 0 || s.pixelHistory[len(s.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 lastPixel != nil {
|
||||||
if !pixel.Start && len(s.pixelHistory) > 0 {
|
// Draw the pixels in between.
|
||||||
prev := s.pixelHistory[len(s.pixelHistory)-1]
|
if *lastPixel != pixel {
|
||||||
pixel.DY = prev.Y
|
for point := range render.IterLine(lastPixel.X, lastPixel.Y, pixel.X, pixel.Y) {
|
||||||
pixel.DX = prev.X
|
dot := level.Pixel{
|
||||||
|
X: point.X,
|
||||||
|
Y: point.Y,
|
||||||
|
Palette: lastPixel.Palette,
|
||||||
|
}
|
||||||
|
s.canvas[dot] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.lastPixel = &pixel
|
||||||
s.pixelHistory = append(s.pixelHistory, pixel)
|
s.pixelHistory = append(s.pixelHistory, pixel)
|
||||||
|
|
||||||
// Save in the pixel canvas map.
|
// Save in the pixel canvas map.
|
||||||
fmt.Printf("%+v", pixel)
|
|
||||||
s.canvas[pixel] = nil
|
s.canvas[pixel] = nil
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
s.lastPixel = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -126,25 +130,6 @@ func (s *EditorScene) Loop(d *Doodle, ev *events.State) error {
|
||||||
|
|
||||||
// Draw the current frame.
|
// Draw the current frame.
|
||||||
func (s *EditorScene) Draw(d *Doodle) error {
|
func (s *EditorScene) Draw(d *Doodle) error {
|
||||||
// for i, pixel := range s.pixelHistory {
|
|
||||||
// if !pixel.Start && i > 0 {
|
|
||||||
// prev := s.pixelHistory[i-1]
|
|
||||||
// if prev.X == pixel.X && prev.Y == pixel.Y {
|
|
||||||
// d.Engine.DrawPoint(
|
|
||||||
// render.Black,
|
|
||||||
// render.Point{pixel.X, pixel.Y},
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// d.Engine.DrawLine(
|
|
||||||
// render.Black,
|
|
||||||
// render.Point{pixel.X, pixel.Y},
|
|
||||||
// render.Point{prev.X, prev.Y},
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// d.Engine.DrawPoint(render.Black, render.Point{pixel.X, pixel.Y})
|
|
||||||
// }
|
|
||||||
|
|
||||||
s.canvas.Draw(d.Engine)
|
s.canvas.Draw(d.Engine)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -153,7 +138,7 @@ func (s *EditorScene) Draw(d *Doodle) error {
|
||||||
// LoadLevel loads a level from disk.
|
// LoadLevel loads a level from disk.
|
||||||
func (s *EditorScene) LoadLevel(filename string) error {
|
func (s *EditorScene) LoadLevel(filename string) error {
|
||||||
s.filename = filename
|
s.filename = filename
|
||||||
s.pixelHistory = []render.Pixel{}
|
s.pixelHistory = []level.Pixel{}
|
||||||
s.canvas = render.Grid{}
|
s.canvas = render.Grid{}
|
||||||
|
|
||||||
m, err := level.LoadJSON(filename)
|
m, err := level.LoadJSON(filename)
|
||||||
|
@ -162,12 +147,9 @@ func (s *EditorScene) LoadLevel(filename string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, point := range m.Pixels {
|
for _, point := range m.Pixels {
|
||||||
pixel := render.Pixel{
|
pixel := level.Pixel{
|
||||||
Start: true,
|
|
||||||
X: point.X,
|
X: point.X,
|
||||||
Y: point.Y,
|
Y: point.Y,
|
||||||
DX: point.X,
|
|
||||||
DY: point.Y,
|
|
||||||
}
|
}
|
||||||
s.pixelHistory = append(s.pixelHistory, pixel)
|
s.pixelHistory = append(s.pixelHistory, pixel)
|
||||||
s.canvas[pixel] = nil
|
s.canvas[pixel] = nil
|
||||||
|
@ -195,21 +177,11 @@ func (s *EditorScene) SaveLevel(filename string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for pixel := range s.canvas {
|
for pixel := range s.canvas {
|
||||||
if pixel.DX == 0 && pixel.DY == 0 {
|
|
||||||
m.Pixels = append(m.Pixels, level.Pixel{
|
m.Pixels = append(m.Pixels, level.Pixel{
|
||||||
X: pixel.X,
|
X: pixel.X,
|
||||||
Y: pixel.Y,
|
Y: pixel.Y,
|
||||||
Palette: 0,
|
Palette: 0,
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
for point := range render.IterLine(pixel.X, pixel.Y, pixel.DX, pixel.DY) {
|
|
||||||
m.Pixels = append(m.Pixels, level.Pixel{
|
|
||||||
X: point.X,
|
|
||||||
Y: point.Y,
|
|
||||||
Palette: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json, err := m.ToJSON()
|
json, err := m.ToJSON()
|
||||||
|
@ -238,14 +210,7 @@ func (s *EditorScene) Screenshot() {
|
||||||
|
|
||||||
// Fill in the dots we drew.
|
// Fill in the dots we drew.
|
||||||
for pixel := range s.canvas {
|
for pixel := range s.canvas {
|
||||||
// A line or a dot?
|
|
||||||
if pixel.DX == 0 && pixel.DY == 0 {
|
|
||||||
screenshot.Set(int(pixel.X), int(pixel.Y), image.Black)
|
screenshot.Set(int(pixel.X), int(pixel.Y), image.Black)
|
||||||
} else {
|
|
||||||
for point := range draw.Line(pixel.X, pixel.Y, pixel.DX, pixel.DY) {
|
|
||||||
screenshot.Set(int(point.X), int(point.Y), image.Black)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the screenshot directory.
|
// Create the screenshot directory.
|
||||||
|
|
|
@ -131,7 +131,7 @@ func (s *PlayScene) LoadLevel(filename string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, point := range m.Pixels {
|
for _, point := range m.Pixels {
|
||||||
pixel := render.Pixel{
|
pixel := level.Pixel{
|
||||||
X: point.X,
|
X: point.X,
|
||||||
Y: point.Y,
|
Y: point.Y,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,14 @@
|
||||||
package render
|
package render
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"git.kirsle.net/apps/doodle/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pixel TODO: not a global
|
|
||||||
// TODO get rid of this ugly thing.
|
|
||||||
type Pixel struct {
|
|
||||||
Start bool
|
|
||||||
X int32
|
|
||||||
Y int32
|
|
||||||
DX int32
|
|
||||||
DY int32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Pixel) String() string {
|
|
||||||
return fmt.Sprintf("(%d,%d) delta (%d,%d)",
|
|
||||||
p.X, p.Y,
|
|
||||||
p.DX, p.DY,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grid is a 2D grid of pixels in X,Y notation.
|
// Grid is a 2D grid of pixels in X,Y notation.
|
||||||
type Grid map[Pixel]interface{}
|
type Grid map[level.Pixel]interface{}
|
||||||
|
|
||||||
// Exists returns true if the point exists on the grid.
|
// Exists returns true if the point exists on the grid.
|
||||||
func (g *Grid) Exists(p Pixel) bool {
|
func (g *Grid) Exists(p level.Pixel) bool {
|
||||||
if _, ok := (*g)[p]; ok {
|
if _, ok := (*g)[p]; ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -35,15 +18,9 @@ func (g *Grid) Exists(p Pixel) bool {
|
||||||
// Draw the grid efficiently.
|
// Draw the grid efficiently.
|
||||||
func (g *Grid) Draw(e Engine) {
|
func (g *Grid) Draw(e Engine) {
|
||||||
for pixel := range *g {
|
for pixel := range *g {
|
||||||
if pixel.DX == 0 && pixel.DY == 0 {
|
|
||||||
e.DrawPoint(Black, Point{
|
e.DrawPoint(Black, Point{
|
||||||
X: pixel.X,
|
X: pixel.X,
|
||||||
Y: pixel.Y,
|
Y: pixel.Y,
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
for point := range IterLine(pixel.X, pixel.Y, pixel.DX, pixel.DY) {
|
|
||||||
e.DrawPoint(Black, point)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,6 +141,7 @@ func IterLine(x1, y1, x2, y2 int32) chan Point {
|
||||||
return generator
|
return generator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IterLine2 works with two Points rather than four coordinates.
|
||||||
func IterLine2(p1 Point, p2 Point) chan Point {
|
func IterLine2(p1 Point, p2 Point) chan Point {
|
||||||
return IterLine(p1.X, p1.Y, p2.X, p2.Y)
|
return IterLine(p1.X, p1.Y, p2.X, p2.Y)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user