Play Mode: Fix Level Collision w/ Scrolling
Fixes: * Move the call to CollidesWithGrid() inside the Canvas instead of outside in the PlayScene.movePlayer() so it can apply to all Actors in motion. * PlayScene.movePlayer() in turn just sets the player's Velocity so the Canvas.Loop() can move the actor itself. * When keeping the player inside the level boundaries: previously it was assuming the player Position was relative to the window, and was checking the WorldIndexAt and getting wrong results. * Canvas scrolling (loopFollowActor): check that the actor is getting close to the screen edge using the Viewport into the world, NOT the screen-relative coordinates of the Canvas bounding boxes.
This commit is contained in:
parent
5c08577214
commit
241186209c
|
@ -135,6 +135,19 @@ func (r Rect) AddPoint(other Point) Rect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubtractPoint is the inverse of AddPoint. Use this only if you need to invert
|
||||||
|
// the Point being added.
|
||||||
|
//
|
||||||
|
// This does r.X - other.X, r.Y - other.Y and keeps the width/height the same.
|
||||||
|
func (r Rect) SubtractPoint(other Point) Rect {
|
||||||
|
return Rect{
|
||||||
|
X: r.X - other.X,
|
||||||
|
Y: r.Y - other.Y,
|
||||||
|
W: r.W,
|
||||||
|
H: r.H,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Text holds information for drawing text.
|
// Text holds information for drawing text.
|
||||||
type Text struct {
|
type Text struct {
|
||||||
Text string
|
Text string
|
||||||
|
|
|
@ -75,6 +75,12 @@ func (p *Point) Add(other Point) {
|
||||||
p.Y += other.Y
|
p.Y += other.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subtract the other point from your current point.
|
||||||
|
func (p *Point) Subtract(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
|
// MarshalText to convert the point into text so that a render.Point may be used
|
||||||
// as a map key and serialized to JSON.
|
// as a map key and serialized to JSON.
|
||||||
func (p *Point) MarshalText() ([]byte, error) {
|
func (p *Point) MarshalText() ([]byte, error) {
|
||||||
|
|
|
@ -68,11 +68,14 @@ func (w *Label) Compute(e render.Engine) {
|
||||||
// Max rect to encompass all lines of text.
|
// Max rect to encompass all lines of text.
|
||||||
var maxRect = render.Rect{}
|
var maxRect = render.Rect{}
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
|
if line == "" {
|
||||||
|
line = "<empty>"
|
||||||
|
}
|
||||||
|
|
||||||
text.Text = line // only this line at this time.
|
text.Text = line // only this line at this time.
|
||||||
rect, err := e.ComputeTextRect(text)
|
rect, err := e.ComputeTextRect(text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("%s: failed to compute text rect: %s", w, err)) // TODO return an error
|
panic(fmt.Sprintf("%s: failed to compute text rect: %s", w, err)) // TODO return an error
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rect.W > maxRect.W {
|
if rect.W > maxRect.W {
|
||||||
|
|
|
@ -29,7 +29,7 @@ var (
|
||||||
|
|
||||||
// Put a border around all Canvas widgets.
|
// Put a border around all Canvas widgets.
|
||||||
DebugCanvasBorder = render.Invisible
|
DebugCanvasBorder = render.Invisible
|
||||||
DebugCanvasLabel = false // Tag the canvas with a label.
|
DebugCanvasLabel = true // Tag the canvas with a label.
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -12,7 +12,7 @@ var (
|
||||||
// Window scrolling behavior in Play Mode.
|
// Window scrolling behavior in Play Mode.
|
||||||
ScrollboxHoz = 64 // horizontal px from window border to start scrol
|
ScrollboxHoz = 64 // horizontal px from window border to start scrol
|
||||||
ScrollboxVert = 128
|
ScrollboxVert = 128
|
||||||
ScrollMaxVelocity = 24
|
ScrollMaxVelocity = 8 // 24
|
||||||
|
|
||||||
// Player speeds
|
// Player speeds
|
||||||
PlayerMaxVelocity = 8
|
PlayerMaxVelocity = 8
|
||||||
|
|
|
@ -96,7 +96,11 @@ const (
|
||||||
Right
|
Right
|
||||||
)
|
)
|
||||||
|
|
||||||
// CollidesWithGrid checks if a Doodad collides with level geometry.
|
/*
|
||||||
|
CollidesWithGrid checks if a Doodad collides with level geometry.
|
||||||
|
|
||||||
|
The `target` is the point the actor wants to move to on this tick.
|
||||||
|
*/
|
||||||
func CollidesWithGrid(d Actor, grid *level.Chunker, target render.Point) (*Collide, bool) {
|
func CollidesWithGrid(d Actor, grid *level.Chunker, target render.Point) (*Collide, bool) {
|
||||||
var (
|
var (
|
||||||
P = d.Position()
|
P = d.Position()
|
||||||
|
@ -109,10 +113,10 @@ func CollidesWithGrid(d Actor, grid *level.Chunker, target render.Point) (*Colli
|
||||||
capHeight int32 // Stop vertical movement thru a ceiling
|
capHeight int32 // Stop vertical movement thru a ceiling
|
||||||
capLeft int32 // Stop movement thru a wall
|
capLeft int32 // Stop movement thru a wall
|
||||||
capRight int32
|
capRight int32
|
||||||
|
capFloor int32 // Stop movement thru the floor
|
||||||
hitLeft bool // Has hit an obstacle on the left
|
hitLeft bool // Has hit an obstacle on the left
|
||||||
hitRight bool // or right
|
hitRight bool // or right
|
||||||
hitFloor bool
|
hitFloor bool
|
||||||
capFloor int32
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test all of the bounding boxes for a collision with level geometry.
|
// Test all of the bounding boxes for a collision with level geometry.
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
package doodads
|
|
||||||
|
|
||||||
import "git.kirsle.net/apps/doodle/lib/render"
|
|
||||||
|
|
||||||
// PlayerID is the Doodad ID for the player character.
|
|
||||||
const PlayerID = "PLAYER"
|
|
||||||
|
|
||||||
// Player is a special doodad for the player character.
|
|
||||||
type Player struct {
|
|
||||||
point render.Point
|
|
||||||
velocity render.Point
|
|
||||||
size render.Rect
|
|
||||||
grounded bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPlayer creates the special Player Character doodad.
|
|
||||||
func NewPlayer() *Player {
|
|
||||||
return &Player{
|
|
||||||
point: render.Point{
|
|
||||||
X: 100,
|
|
||||||
Y: 100,
|
|
||||||
},
|
|
||||||
size: render.Rect{
|
|
||||||
W: 32,
|
|
||||||
H: 32,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID of the Player singleton.
|
|
||||||
func (p *Player) ID() string {
|
|
||||||
return PlayerID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position of the player.
|
|
||||||
func (p *Player) Position() render.Point {
|
|
||||||
return p.point
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveBy a relative delta position.
|
|
||||||
func (p *Player) MoveBy(by render.Point) {
|
|
||||||
p.point.X += by.X
|
|
||||||
p.point.Y += by.Y
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveTo an absolute position.
|
|
||||||
func (p *Player) MoveTo(to render.Point) {
|
|
||||||
p.point = to
|
|
||||||
}
|
|
||||||
|
|
||||||
// Velocity returns the player's current velocity.
|
|
||||||
func (p *Player) Velocity() render.Point {
|
|
||||||
return p.velocity
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns the player's size.
|
|
||||||
func (p *Player) Size() render.Rect {
|
|
||||||
return p.size
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grounded returns if the player is grounded.
|
|
||||||
func (p *Player) Grounded() bool {
|
|
||||||
return p.grounded
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGrounded sets if the player is grounded.
|
|
||||||
func (p *Player) SetGrounded(v bool) {
|
|
||||||
p.grounded = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the player sprite.
|
|
||||||
func (p *Player) Draw(e render.Engine) {
|
|
||||||
e.DrawBox(render.RGBA(255, 255, 153, 255), render.Rect{
|
|
||||||
X: p.point.X,
|
|
||||||
Y: p.point.Y,
|
|
||||||
W: p.size.W,
|
|
||||||
H: p.size.H,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -76,10 +76,13 @@ func (s *EditorScene) Setup(d *Doodle) error {
|
||||||
if s.Level != nil {
|
if s.Level != nil {
|
||||||
log.Debug("EditorScene.Setup: received level from scene caller")
|
log.Debug("EditorScene.Setup: received level from scene caller")
|
||||||
s.UI.Canvas.LoadLevel(d.Engine, s.Level)
|
s.UI.Canvas.LoadLevel(d.Engine, s.Level)
|
||||||
|
s.UI.Canvas.InstallActors(s.Level.Actors)
|
||||||
} else if s.filename != "" && s.OpenFile {
|
} else if s.filename != "" && s.OpenFile {
|
||||||
log.Debug("EditorScene.Setup: Loading map from filename at %s", s.filename)
|
log.Debug("EditorScene.Setup: Loading map from filename at %s", s.filename)
|
||||||
if err := s.LoadLevel(s.filename); err != nil {
|
if err := s.LoadLevel(s.filename); err != nil {
|
||||||
d.Flash("LoadLevel error: %s", err)
|
d.Flash("LoadLevel error: %s", err)
|
||||||
|
} else {
|
||||||
|
s.UI.Canvas.InstallActors(s.Level.Actors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,10 @@ func (d *Doodle) DrawDebugOverlay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawCollisionBox draws the collision box around a Doodad.
|
// DrawCollisionBox draws the collision box around a Doodad.
|
||||||
|
//
|
||||||
|
// TODO: move inside the Canvas. Currently it takes an actor's World Position
|
||||||
|
// and draws the box as if it were a relative (to the window) position, so the
|
||||||
|
// hitbox drifts off when the level scrolls away from 0,0
|
||||||
func (d *Doodle) DrawCollisionBox(actor doodads.Actor) {
|
func (d *Doodle) DrawCollisionBox(actor doodads.Actor) {
|
||||||
if !DebugCollision {
|
if !DebugCollision {
|
||||||
return
|
return
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"git.kirsle.net/apps/doodle/lib/events"
|
"git.kirsle.net/apps/doodle/lib/events"
|
||||||
"git.kirsle.net/apps/doodle/lib/render"
|
"git.kirsle.net/apps/doodle/lib/render"
|
||||||
"git.kirsle.net/apps/doodle/pkg/balance"
|
"git.kirsle.net/apps/doodle/pkg/balance"
|
||||||
"git.kirsle.net/apps/doodle/pkg/doodads"
|
|
||||||
"git.kirsle.net/apps/doodle/pkg/doodads/dummy"
|
"git.kirsle.net/apps/doodle/pkg/doodads/dummy"
|
||||||
"git.kirsle.net/apps/doodle/pkg/level"
|
"git.kirsle.net/apps/doodle/pkg/level"
|
||||||
"git.kirsle.net/apps/doodle/pkg/log"
|
"git.kirsle.net/apps/doodle/pkg/log"
|
||||||
|
@ -56,6 +55,7 @@ func (s *PlayScene) Setup(d *Doodle) error {
|
||||||
|
|
||||||
// Initialize the drawing canvas.
|
// Initialize the drawing canvas.
|
||||||
s.drawing = uix.NewCanvas(balance.ChunkSize, false)
|
s.drawing = uix.NewCanvas(balance.ChunkSize, false)
|
||||||
|
s.drawing.Name = "play-canvas"
|
||||||
s.drawing.MoveTo(render.Origin)
|
s.drawing.MoveTo(render.Origin)
|
||||||
s.drawing.Resize(render.NewRect(int32(d.width), int32(d.height)))
|
s.drawing.Resize(render.NewRect(int32(d.width), int32(d.height)))
|
||||||
s.drawing.Compute(d.Engine)
|
s.drawing.Compute(d.Engine)
|
||||||
|
@ -92,7 +92,7 @@ func (s *PlayScene) Setup(d *Doodle) error {
|
||||||
func (s *PlayScene) Loop(d *Doodle, ev *events.State) error {
|
func (s *PlayScene) Loop(d *Doodle, ev *events.State) error {
|
||||||
// Update debug overlay values.
|
// Update debug overlay values.
|
||||||
*s.debWorldIndex = s.drawing.WorldIndexAt(render.NewPoint(ev.CursorX.Now, ev.CursorY.Now)).String()
|
*s.debWorldIndex = s.drawing.WorldIndexAt(render.NewPoint(ev.CursorX.Now, ev.CursorY.Now)).String()
|
||||||
*s.debPosition = s.Player.Position().String()
|
*s.debPosition = s.Player.Position().String() + " vel " + s.Player.Velocity().String()
|
||||||
*s.debViewport = s.drawing.Viewport().String()
|
*s.debViewport = s.drawing.Viewport().String()
|
||||||
*s.debScroll = s.drawing.Scroll.String()
|
*s.debScroll = s.drawing.Scroll.String()
|
||||||
|
|
||||||
|
@ -134,8 +134,10 @@ func (s *PlayScene) Draw(d *Doodle) error {
|
||||||
// Draw the level.
|
// Draw the level.
|
||||||
s.drawing.Present(d.Engine, s.drawing.Point())
|
s.drawing.Present(d.Engine, s.drawing.Point())
|
||||||
|
|
||||||
// Draw our hero.
|
// Draw our hero. TODO: this draws a yellow box using the player's World
|
||||||
d.Engine.DrawBox(render.RGBA(255, 255, 153, 255), render.Rect{
|
// Position as tho it were Screen Position. The player has its own canvas
|
||||||
|
// currently drawn in red
|
||||||
|
d.Engine.DrawBox(render.RGBA(255, 255, 153, 64), render.Rect{
|
||||||
X: s.Player.Position().X,
|
X: s.Player.Position().X,
|
||||||
Y: s.Player.Position().Y,
|
Y: s.Player.Position().Y,
|
||||||
W: s.Player.Size().W,
|
W: s.Player.Size().W,
|
||||||
|
@ -150,48 +152,37 @@ func (s *PlayScene) Draw(d *Doodle) error {
|
||||||
|
|
||||||
// movePlayer updates the player's X,Y coordinate based on key pressed.
|
// movePlayer updates the player's X,Y coordinate based on key pressed.
|
||||||
func (s *PlayScene) movePlayer(ev *events.State) {
|
func (s *PlayScene) movePlayer(ev *events.State) {
|
||||||
delta := s.Player.Position()
|
|
||||||
var playerSpeed = int32(balance.PlayerMaxVelocity)
|
var playerSpeed = int32(balance.PlayerMaxVelocity)
|
||||||
var gravity = int32(balance.Gravity)
|
var gravity = int32(balance.Gravity)
|
||||||
|
|
||||||
var velocity render.Point
|
var velocity render.Point
|
||||||
|
|
||||||
if ev.Down.Now {
|
if ev.Down.Now {
|
||||||
delta.Y += playerSpeed
|
|
||||||
velocity.Y = playerSpeed
|
velocity.Y = playerSpeed
|
||||||
}
|
}
|
||||||
if ev.Left.Now {
|
if ev.Left.Now {
|
||||||
delta.X -= playerSpeed
|
|
||||||
velocity.X = -playerSpeed
|
velocity.X = -playerSpeed
|
||||||
}
|
}
|
||||||
if ev.Right.Now {
|
if ev.Right.Now {
|
||||||
delta.X += playerSpeed
|
|
||||||
velocity.X = playerSpeed
|
velocity.X = playerSpeed
|
||||||
}
|
}
|
||||||
if ev.Up.Now {
|
if ev.Up.Now {
|
||||||
delta.Y -= playerSpeed
|
|
||||||
velocity.Y = -playerSpeed
|
velocity.Y = -playerSpeed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply gravity.
|
|
||||||
// var onFloor bool
|
|
||||||
|
|
||||||
info, ok := doodads.CollidesWithGrid(s.Player, s.Level.Chunker, delta)
|
|
||||||
if ok {
|
|
||||||
// Collision happened with world.
|
|
||||||
}
|
|
||||||
delta = info.MoveTo
|
|
||||||
|
|
||||||
// Apply gravity if not grounded.
|
// Apply gravity if not grounded.
|
||||||
if !s.Player.Grounded() {
|
if !s.Player.Grounded() {
|
||||||
// Gravity has to pipe through the collision checker, too, so it
|
// Gravity has to pipe through the collision checker, too, so it
|
||||||
// can't give us a cheated downward boost.
|
// can't give us a cheated downward boost.
|
||||||
delta.Y += gravity
|
|
||||||
velocity.Y += gravity
|
velocity.Y += gravity
|
||||||
}
|
}
|
||||||
|
|
||||||
// s.Player.SetVelocity(velocity)
|
s.Player.SetVelocity(velocity)
|
||||||
s.Player.MoveTo(delta)
|
}
|
||||||
|
|
||||||
|
// Drawing returns the private world drawing, for debugging with the console.
|
||||||
|
func (s *PlayScene) Drawing() *uix.Canvas {
|
||||||
|
return s.drawing
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadLevel loads a level from disk.
|
// LoadLevel loads a level from disk.
|
||||||
|
|
|
@ -31,7 +31,6 @@ func NewActor(id string, levelActor *level.Actor, doodad *doodads.Doodad) *Actor
|
||||||
size := int32(doodad.Layers[0].Chunker.Size)
|
size := int32(doodad.Layers[0].Chunker.Size)
|
||||||
can := NewCanvas(int(size), false)
|
can := NewCanvas(int(size), false)
|
||||||
can.Name = id
|
can.Name = id
|
||||||
can.actor = levelActor
|
|
||||||
|
|
||||||
// TODO: if the Background is render.Invisible it gets defaulted to
|
// TODO: if the Background is render.Invisible it gets defaulted to
|
||||||
// White somewhere and the Doodad masks the level drawing behind it.
|
// White somewhere and the Doodad masks the level drawing behind it.
|
||||||
|
@ -40,9 +39,15 @@ func NewActor(id string, levelActor *level.Actor, doodad *doodads.Doodad) *Actor
|
||||||
can.LoadDoodad(doodad)
|
can.LoadDoodad(doodad)
|
||||||
can.Resize(render.NewRect(size, size))
|
can.Resize(render.NewRect(size, size))
|
||||||
|
|
||||||
return &Actor{
|
actor := &Actor{
|
||||||
Drawing: doodads.NewDrawing(id, doodad),
|
Drawing: doodads.NewDrawing(id, doodad),
|
||||||
Actor: levelActor,
|
Actor: levelActor,
|
||||||
Canvas: can,
|
Canvas: can,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Give the Canvas a pointer to its (parent) Actor so it can draw its debug
|
||||||
|
// label and show the World Position of the actor within the world.
|
||||||
|
can.actor = actor
|
||||||
|
|
||||||
|
return actor
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,8 @@ type Canvas struct {
|
||||||
chunks *level.Chunker
|
chunks *level.Chunker
|
||||||
|
|
||||||
// Actors to superimpose on top of the drawing.
|
// Actors to superimpose on top of the drawing.
|
||||||
actor *level.Actor // if this canvas IS an actor
|
actor *Actor // if this canvas IS an actor
|
||||||
actors []*Actor
|
actors []*Actor // if this canvas CONTAINS actors (i.e., is a level)
|
||||||
|
|
||||||
// Wallpaper settings.
|
// Wallpaper settings.
|
||||||
wallpaper *Wallpaper
|
wallpaper *Wallpaper
|
||||||
|
@ -163,20 +163,35 @@ func (w *Canvas) Loop(ev *events.State) error {
|
||||||
if err := w.loopFollowActor(ev); err != nil {
|
if err := w.loopFollowActor(ev); err != nil {
|
||||||
log.Error("Follow actor: %s", err) // not fatal but nice to know
|
log.Error("Follow actor: %s", err) // not fatal but nice to know
|
||||||
}
|
}
|
||||||
w.loopConstrainScroll()
|
if err := w.loopConstrainScroll(); err != nil {
|
||||||
|
log.Debug("loopConstrainScroll: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Move any actors.
|
// Move any actors.
|
||||||
for _, a := range w.actors {
|
for _, a := range w.actors {
|
||||||
if v := a.Velocity(); v != render.Origin {
|
if v := a.Velocity(); v != render.Origin {
|
||||||
// orig := a.Drawing.Position()
|
// Create a delta point from their current location to where they
|
||||||
a.MoveBy(v)
|
// want to move to this tick.
|
||||||
|
delta := a.Position()
|
||||||
|
delta.Add(v)
|
||||||
|
|
||||||
|
// Check collision with level geometry.
|
||||||
|
info, ok := doodads.CollidesWithGrid(a, w.chunks, delta)
|
||||||
|
if ok {
|
||||||
|
// Collision happened with world.
|
||||||
|
log.Error("COLLIDE %+v", info)
|
||||||
|
}
|
||||||
|
delta = info.MoveTo // Move us back where the collision check put us
|
||||||
|
|
||||||
|
// Move the actor's World Position to the new location.
|
||||||
|
a.MoveTo(delta)
|
||||||
|
|
||||||
// Keep them contained inside the level.
|
// Keep them contained inside the level.
|
||||||
if w.wallpaper.pageType > level.Unbounded {
|
if w.wallpaper.pageType > level.Unbounded {
|
||||||
var (
|
var (
|
||||||
orig = w.WorldIndexAt(a.Drawing.Position())
|
orig = a.Position() // Actor's World Position
|
||||||
moveBy render.Point
|
moveBy render.Point
|
||||||
size = a.Canvas.Size()
|
size = a.Size()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bound it on the top left edges.
|
// Bound it on the top left edges.
|
||||||
|
|
|
@ -20,7 +20,12 @@ func (w *Canvas) InstallActors(actors level.ActorMap) error {
|
||||||
return fmt.Errorf("InstallActors: %s", err)
|
return fmt.Errorf("InstallActors: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.actors = append(w.actors, NewActor(id, actor, doodad))
|
// Create the "live" Actor to exist in the world, and set its world
|
||||||
|
// position to the Point defined in the level data.
|
||||||
|
liveActor := NewActor(id, actor, doodad)
|
||||||
|
liveActor.MoveTo(actor.Point)
|
||||||
|
|
||||||
|
w.actors = append(w.actors, liveActor)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -46,10 +51,9 @@ func (w *Canvas) drawActors(e render.Engine, p render.Point) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
actor = a.Actor // Static Actor instance from Level file, DO NOT CHANGE
|
|
||||||
can = a.Canvas // Canvas widget that draws the actor
|
can = a.Canvas // Canvas widget that draws the actor
|
||||||
actorPoint = actor.Point // XXX TODO: DO NOT CHANGE
|
actorPoint = a.Position()
|
||||||
actorSize = can.Size()
|
actorSize = a.Size()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create a box of World Coordinates that this actor occupies. The
|
// Create a box of World Coordinates that this actor occupies. The
|
||||||
|
@ -87,7 +91,7 @@ func (w *Canvas) drawActors(e render.Engine, p render.Point) {
|
||||||
// Hitting the left edge. Cap the X coord and shrink the width.
|
// Hitting the left edge. Cap the X coord and shrink the width.
|
||||||
delta := p.X - drawAt.X // positive number
|
delta := p.X - drawAt.X // positive number
|
||||||
drawAt.X = p.X
|
drawAt.X = p.X
|
||||||
// scrollTo.X -= delta // TODO
|
// scrollTo.X -= delta / 2 // TODO
|
||||||
resizeTo.W -= delta
|
resizeTo.W -= delta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,11 +149,17 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
// Viewport.W, Viewport.H,
|
// Viewport.W, Viewport.H,
|
||||||
// ),
|
// ),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw the actor's position details.
|
||||||
|
// LP = Level Position, where the Actor starts at in the level data
|
||||||
|
// WP = World Position, the Actor's current position in the level
|
||||||
if w.actor != nil {
|
if w.actor != nil {
|
||||||
rows = append(rows,
|
rows = append(rows,
|
||||||
fmt.Sprintf("WP=%s", w.actor.Point),
|
fmt.Sprintf("LP=%s", w.actor.Actor.Point),
|
||||||
|
fmt.Sprintf("WP=%s", w.actor.Position()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
label := ui.NewLabel(ui.Label{
|
label := ui.NewLabel(ui.Label{
|
||||||
Text: strings.Join(rows, "\n"),
|
Text: strings.Join(rows, "\n"),
|
||||||
Font: render.Text{
|
Font: render.Text{
|
||||||
|
|
|
@ -110,8 +110,7 @@ func (w *Canvas) loopFollowActor(ev *events.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
P = w.Point()
|
VP = w.Viewport()
|
||||||
S = w.Size()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Find the actor.
|
// Find the actor.
|
||||||
|
@ -121,19 +120,18 @@ func (w *Canvas) loopFollowActor(ev *events.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
actor.Canvas.SetBorderSize(2)
|
actor.Canvas.SetBorderSize(2)
|
||||||
actor.Canvas.SetBorderColor(render.Cyan)
|
actor.Canvas.SetBorderColor(render.Red)
|
||||||
actor.Canvas.SetBorderStyle(ui.BorderSolid)
|
actor.Canvas.SetBorderStyle(ui.BorderSolid)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
APosition = actor.Position() // relative to screen
|
APosition = actor.Position() // absolute world position
|
||||||
APoint = actor.Drawing.Position()
|
|
||||||
ASize = actor.Drawing.Size()
|
ASize = actor.Drawing.Size()
|
||||||
scrollBy render.Point
|
scrollBy render.Point
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scroll left
|
// Scroll left
|
||||||
if APosition.X-P.X <= int32(balance.ScrollboxHoz) {
|
if APosition.X-VP.X <= int32(balance.ScrollboxHoz) {
|
||||||
var delta = APoint.X - P.X
|
var delta = APosition.X - VP.X
|
||||||
if delta > int32(balance.ScrollMaxVelocity) {
|
if delta > int32(balance.ScrollMaxVelocity) {
|
||||||
delta = int32(balance.ScrollMaxVelocity)
|
delta = int32(balance.ScrollMaxVelocity)
|
||||||
}
|
}
|
||||||
|
@ -146,8 +144,8 @@ func (w *Canvas) loopFollowActor(ev *events.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll right
|
// Scroll right
|
||||||
if APosition.X >= S.W-ASize.W-int32(balance.ScrollboxHoz) {
|
if APosition.X >= VP.W-ASize.W-int32(balance.ScrollboxHoz) {
|
||||||
var delta = S.W - ASize.W - int32(balance.ScrollboxHoz)
|
var delta = VP.W - ASize.W - int32(balance.ScrollboxHoz)
|
||||||
if delta > int32(balance.ScrollMaxVelocity) {
|
if delta > int32(balance.ScrollMaxVelocity) {
|
||||||
delta = int32(balance.ScrollMaxVelocity)
|
delta = int32(balance.ScrollMaxVelocity)
|
||||||
}
|
}
|
||||||
|
@ -155,8 +153,8 @@ func (w *Canvas) loopFollowActor(ev *events.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll up
|
// Scroll up
|
||||||
if APosition.Y-P.Y <= int32(balance.ScrollboxVert) {
|
if APosition.Y-VP.Y <= int32(balance.ScrollboxVert) {
|
||||||
var delta = APoint.Y - P.Y
|
var delta = APosition.Y - VP.Y
|
||||||
if delta > int32(balance.ScrollMaxVelocity) {
|
if delta > int32(balance.ScrollMaxVelocity) {
|
||||||
delta = int32(balance.ScrollMaxVelocity)
|
delta = int32(balance.ScrollMaxVelocity)
|
||||||
}
|
}
|
||||||
|
@ -168,8 +166,8 @@ func (w *Canvas) loopFollowActor(ev *events.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll down
|
// Scroll down
|
||||||
if APosition.Y >= S.H-ASize.H-int32(balance.ScrollboxVert) {
|
if APosition.Y >= VP.H-ASize.H-int32(balance.ScrollboxVert) {
|
||||||
var delta = S.H - ASize.H - int32(balance.ScrollboxVert)
|
var delta = VP.H - ASize.H - int32(balance.ScrollboxVert)
|
||||||
if delta > int32(balance.ScrollMaxVelocity) {
|
if delta > int32(balance.ScrollMaxVelocity) {
|
||||||
delta = int32(balance.ScrollMaxVelocity)
|
delta = int32(balance.ScrollMaxVelocity)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user