Noah Petherbridge
e25869644c
* Edit Mode now uses the Level object itself to keep the drawing data rather than pull its Palette and Chunks out, so it can hang on to more information. The Canvas widget is given references to the Level.Palette and Level.Chunker via Canvas.LoadLevel() * Fix the handoff between Edit Mode and Play Mode. They pass the Level object back and forth and the Filename, because it's not part of the Level. You can save the map with its original settings after returning from Play Mode. * Fix the collision detection in Play Mode. It broke previously when palettes were added because of the difference between a render.Point and a level.Pixel and it couldn't easily look up coordinates. The new Chunker system provides a render.Point lookup API. * All pixels are solid for collision right now, TODO is to return Swatch information from the pixels touching the player character and react accordingly (non-solid, fire flag, etc.) * Remove the level.Grid type as it has been replaced by the Chunker. * Clean up some unused variables and functions.
100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
package render
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Point holds an X,Y coordinate value.
|
|
type Point struct {
|
|
X int32
|
|
Y int32
|
|
}
|
|
|
|
// Common points.
|
|
var (
|
|
Origin Point
|
|
)
|
|
|
|
// NewPoint makes a new Point at an X,Y coordinate.
|
|
func NewPoint(x, y int32) Point {
|
|
return Point{
|
|
X: x,
|
|
Y: y,
|
|
}
|
|
}
|
|
|
|
func (p Point) String() string {
|
|
return fmt.Sprintf("%d,%d", p.X, p.Y)
|
|
}
|
|
|
|
// ParsePoint to parse a point from its string representation.
|
|
func ParsePoint(v string) (Point, error) {
|
|
halves := strings.Split(v, ",")
|
|
if len(halves) != 2 {
|
|
return Point{}, fmt.Errorf("'%s': not a valid coordinate string", v)
|
|
}
|
|
x, errX := strconv.Atoi(halves[0])
|
|
y, errY := strconv.Atoi(halves[1])
|
|
if errX != nil || errY != nil {
|
|
return Point{}, fmt.Errorf("invalid coordinate string (X: %v; Y: %v)",
|
|
errX,
|
|
errY,
|
|
)
|
|
}
|
|
return Point{
|
|
X: int32(x),
|
|
Y: int32(y),
|
|
}, nil
|
|
}
|
|
|
|
// IsZero returns if the point is the zero value.
|
|
func (p Point) IsZero() bool {
|
|
return p.X == 0 && p.Y == 0
|
|
}
|
|
|
|
// Inside returns whether the Point falls inside the rect.
|
|
func (p Point) Inside(r Rect) bool {
|
|
var (
|
|
x1 = r.X
|
|
y1 = r.Y
|
|
x2 = r.X + r.W
|
|
y2 = r.Y + r.H
|
|
)
|
|
return p.X >= x1 && p.X <= x2 && p.Y >= y1 && p.Y <= y2
|
|
}
|
|
|
|
// Add (or subtract) the other point to your current point.
|
|
func (p *Point) Add(other Point) {
|
|
p.X += other.X
|
|
p.Y += other.Y
|
|
}
|
|
|
|
// MarshalText to convert the point into text so that a render.Point may be used
|
|
// as a map key and serialized to JSON.
|
|
func (p *Point) MarshalText() ([]byte, error) {
|
|
return []byte(fmt.Sprintf("%d,%d", p.X, p.Y)), nil
|
|
}
|
|
|
|
// UnmarshalText to restore it from text.
|
|
func (p *Point) UnmarshalText(b []byte) error {
|
|
halves := strings.Split(strings.Trim(string(b), `"`), ",")
|
|
if len(halves) != 2 {
|
|
return fmt.Errorf("'%s': not a valid coordinate string", b)
|
|
}
|
|
|
|
x, errX := strconv.Atoi(halves[0])
|
|
y, errY := strconv.Atoi(halves[1])
|
|
if errX != nil || errY != nil {
|
|
return fmt.Errorf("Point.UnmarshalJSON: Atoi errors (X=%s Y=%s)",
|
|
errX,
|
|
errY,
|
|
)
|
|
}
|
|
|
|
p.X = int32(x)
|
|
p.Y = int32(y)
|
|
return nil
|
|
}
|