MoveZ, etc

This commit is contained in:
Josh Deprez 2021-09-02 16:55:12 +10:00
parent 09167208ea
commit db7590f767
6 changed files with 67 additions and 24 deletions

View file

@ -2,14 +2,10 @@ package engine
import ( import (
"encoding/gob" "encoding/gob"
"image"
) )
// Ensure Actor satisfies interfaces. // Ensure Actor satisfies interfaces.
var _ interface { var _ Prepper = &Actor{}
Bounder
Prepper
} = &Actor{}
func init() { func init() {
gob.Register(&Actor{}) gob.Register(&Actor{})
@ -21,17 +17,14 @@ func init() {
// Actor handles basic movement. // Actor handles basic movement.
type Actor struct { type Actor struct {
CollisionDomain string // id of component to look for colliders inside of CollisionDomain string // id of component to look for colliders inside of
Pos image.Point Pos, Size Point3
Size image.Point xRem, yRem, zRem float64
xRem, yRem float64
game *Game game *Game
} }
func (a *Actor) BoundingRect() image.Rectangle { return image.Rectangle{a.Pos, a.Pos.Add(a.Size)} } func (a *Actor) CollidesAt(p Point3) bool {
bounds := Box{Min: p, Max: p.Add(a.Size)}.XY() // TODO: 3D collision
func (a *Actor) CollidesAt(p image.Point) bool {
bounds := image.Rectangle{Min: p, Max: p.Add(a.Size)}
for c := range a.game.Query(a.CollisionDomain, ColliderType) { for c := range a.game.Query(a.CollisionDomain, ColliderType) {
if c.(Collider).CollidesWith(bounds) { if c.(Collider).CollidesWith(bounds) {
return true return true
@ -49,7 +42,7 @@ func (a *Actor) MoveX(dx float64, onCollide func()) {
a.xRem -= float64(move) a.xRem -= float64(move)
sign := sign(move) sign := sign(move)
for move != 0 { for move != 0 {
if a.CollidesAt(a.Pos.Add(image.Pt(sign, 0))) { if a.CollidesAt(a.Pos.Add(Pt3(sign, 0, 0))) {
if onCollide != nil { if onCollide != nil {
onCollide() onCollide()
} }
@ -69,7 +62,7 @@ func (a *Actor) MoveY(dy float64, onCollide func()) {
a.yRem -= float64(move) a.yRem -= float64(move)
sign := sign(move) sign := sign(move)
for move != 0 { for move != 0 {
if a.CollidesAt(a.Pos.Add(image.Pt(0, sign))) { if a.CollidesAt(a.Pos.Add(Pt3(0, sign, 0))) {
if onCollide != nil { if onCollide != nil {
onCollide() onCollide()
} }
@ -80,6 +73,26 @@ func (a *Actor) MoveY(dy float64, onCollide func()) {
} }
} }
func (a *Actor) MoveZ(dz float64, onCollide func()) {
a.yRem += dz
move := int(a.zRem + 0.5)
if move == 0 {
return
}
a.zRem -= float64(move)
sign := sign(move)
for move != 0 {
if a.CollidesAt(a.Pos.Add(Pt3(0, 0, 0))) {
if onCollide != nil {
onCollide()
}
return
}
a.Pos.Z += sign
move -= sign
}
}
func (a *Actor) Prepare(g *Game) error { func (a *Actor) Prepare(g *Game) error {
a.game = g a.game = g
return nil return nil

View file

@ -150,6 +150,34 @@ func (b Box) Size() Point3 {
return b.Max.Sub(b.Min) return b.Max.Sub(b.Min)
} }
// Back returns an image.Rectangle representing the back of the box, using
// the given projection π.
func (b Box) Back(π image.Point) image.Rectangle {
b.Max.Z = b.Min.Z
return image.Rectangle{
Min: b.Min.IsoProject(π),
Max: b.Max.IsoProject(π),
}
}
// Front returns an image.Rectangle representing the front of the box, using
// the given projection π.
func (b Box) Front(π image.Point) image.Rectangle {
b.Min.Z = b.Max.Z
return image.Rectangle{
Min: b.Min.IsoProject(π),
Max: b.Max.IsoProject(π),
}
}
// XY returns the image.Rectangle representing the box if we forgot about Z.
func (b Box) XY() image.Rectangle {
return image.Rectangle{
Min: b.Min.XY(),
Max: b.Max.XY(),
}
}
// IsoVoxmap implements a voxel map, painted using flat images in 2D. // IsoVoxmap implements a voxel map, painted using flat images in 2D.
type IsoVoxmap struct { type IsoVoxmap struct {
ID ID

View file

@ -25,7 +25,6 @@ type Sprite struct {
FrameOffset image.Point FrameOffset image.Point
Hidden Hidden
Sheet Sheet Sheet Sheet
ZOrder
anim *Anim anim *Anim
} }
@ -35,6 +34,11 @@ func (s *Sprite) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
screen.DrawImage(s.Sheet.SubImage(s.anim.Cell()), opts) screen.DrawImage(s.Sheet.SubImage(s.anim.Cell()), opts)
} }
// DrawOrder returns the Z position from Actor.Pos, and 0 bias.
func (s *Sprite) DrawOrder() (int, int) {
return s.Actor.Pos.Z, 0
}
// Scan returns the Actor and the Sheet. // Scan returns the Actor and the Sheet.
func (s *Sprite) Scan() []interface{} { func (s *Sprite) Scan() []interface{} {
return []interface{}{ return []interface{}{
@ -54,7 +58,7 @@ func (s *Sprite) SetAnim(a *Anim) {
// Transform returns a translation by the FrameOffset. // Transform returns a translation by the FrameOffset.
func (s *Sprite) Transform() (opts ebiten.DrawImageOptions) { func (s *Sprite) Transform() (opts ebiten.DrawImageOptions) {
opts.GeoM.Translate(cfloat(s.Actor.Pos.Add(s.FrameOffset))) opts.GeoM.Translate(cfloat(s.Actor.Pos.XY().Add(s.FrameOffset)))
return opts return opts
} }

Binary file not shown.

View file

@ -4,7 +4,6 @@ import (
"encoding/gob" "encoding/gob"
"errors" "errors"
"fmt" "fmt"
"image"
"math" "math"
"drjosh.dev/gurgle/engine" "drjosh.dev/gurgle/engine"
@ -71,7 +70,7 @@ func (aw *Awakeman) Update() error {
if ebiten.IsKeyPressed(ebiten.KeyShift) { if ebiten.IsKeyPressed(ebiten.KeyShift) {
z = 2.0 z = 2.0
} }
aw.camera.PointAt(aw.Sprite.Actor.Pos.Add(aw.Sprite.Actor.Size.Div(2)), z) aw.camera.PointAt(aw.Sprite.Actor.Pos.XY().Add(aw.Sprite.Actor.Size.XY().Div(2)), z)
return nil return nil
} }
@ -116,7 +115,7 @@ func (aw *Awakeman) realUpdate() error {
ux, uy := aw.vx, aw.vy ux, uy := aw.vx, aw.vy
// Has traction? // Has traction?
if aw.Sprite.Actor.CollidesAt(aw.Sprite.Actor.Pos.Add(image.Pt(0, 1))) { if aw.Sprite.Actor.CollidesAt(aw.Sprite.Actor.Pos.Add(engine.Pt3(0, 1, 0))) {
// Not falling. // Not falling.
// Instantly decelerate (AW absorbs all kinetic E in legs, or something) // Instantly decelerate (AW absorbs all kinetic E in legs, or something)
if aw.jumpBuffer > 0 { if aw.jumpBuffer > 0 {

View file

@ -187,8 +187,8 @@ func writeLevel1() {
Sprite: engine.Sprite{ Sprite: engine.Sprite{
Actor: engine.Actor{ Actor: engine.Actor{
CollisionDomain: "level_1", CollisionDomain: "level_1",
Pos: image.Pt(100, 100), Pos: engine.Pt3(100, 100, 9),
Size: image.Pt(8, 16), Size: engine.Pt3(8, 16, 8),
}, },
FrameOffset: image.Pt(-1, 0), FrameOffset: image.Pt(-1, 0),
Sheet: engine.Sheet{ Sheet: engine.Sheet{
@ -228,7 +228,6 @@ func writeLevel1() {
CellSize: image.Pt(10, 16), CellSize: image.Pt(10, 16),
Src: engine.ImageRef{Path: "assets/aw.png"}, Src: engine.ImageRef{Path: "assets/aw.png"},
}, },
ZOrder: 9,
}, },
}, },
}, },