Noah Petherbridge
e141203c4b
Known bugs: * The Pixel format in the Grid has DX and DY attributes and it wreaks havoc on collision detection in Play Mode when you come straight from the editor. Reloading the map from disk to play is OK cuz it lacks these attrs.
148 lines
2.8 KiB
Go
148 lines
2.8 KiB
Go
package doodle
|
|
|
|
import (
|
|
"git.kirsle.net/apps/doodle/doodads"
|
|
"git.kirsle.net/apps/doodle/events"
|
|
"git.kirsle.net/apps/doodle/level"
|
|
"git.kirsle.net/apps/doodle/render"
|
|
)
|
|
|
|
// PlayScene manages the "Edit Level" game mode.
|
|
type PlayScene struct {
|
|
// Configuration attributes.
|
|
Filename string
|
|
Canvas render.Grid
|
|
|
|
// Private variables.
|
|
canvas render.Grid
|
|
|
|
// Canvas size
|
|
width int32
|
|
height int32
|
|
|
|
// Player character
|
|
player doodads.Doodad
|
|
}
|
|
|
|
// Name of the scene.
|
|
func (s *PlayScene) Name() string {
|
|
return "Play"
|
|
}
|
|
|
|
// Setup the play scene.
|
|
func (s *PlayScene) Setup(d *Doodle) error {
|
|
// Given a filename or map data to play?
|
|
if s.Canvas != nil {
|
|
log.Debug("PlayScene.Setup: loading map from given canvas")
|
|
s.canvas = s.Canvas
|
|
|
|
} else if s.Filename != "" {
|
|
log.Debug("PlayScene.Setup: loading map from file %s", s.Filename)
|
|
s.LoadLevel(s.Filename)
|
|
s.Filename = ""
|
|
}
|
|
|
|
s.player = doodads.NewPlayer()
|
|
|
|
if s.canvas == nil {
|
|
log.Debug("PlayScene.Setup: no grid given, initializing empty grid")
|
|
s.canvas = render.Grid{}
|
|
}
|
|
|
|
s.width = d.width // TODO: canvas width = copy the window size
|
|
s.height = d.height
|
|
|
|
d.Flash("Entered Play Mode. Press 'E' to edit this map.")
|
|
|
|
return nil
|
|
}
|
|
|
|
// Loop the editor scene.
|
|
func (s *PlayScene) Loop(d *Doodle, ev *events.State) error {
|
|
// Switching to Edit Mode?
|
|
if ev.KeyName.Read() == "e" {
|
|
log.Info("Edit Mode, Go!")
|
|
d.Goto(&EditorScene{
|
|
Canvas: s.canvas,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
s.movePlayer(ev)
|
|
return nil
|
|
}
|
|
|
|
// Draw the pixels on this frame.
|
|
func (s *PlayScene) Draw(d *Doodle) error {
|
|
// Clear the canvas and fill it with white.
|
|
d.Engine.Clear(render.White)
|
|
|
|
s.canvas.Draw(d.Engine)
|
|
|
|
// Draw our hero.
|
|
s.player.Draw(d.Engine)
|
|
|
|
return nil
|
|
}
|
|
|
|
// movePlayer updates the player's X,Y coordinate based on key pressed.
|
|
func (s *PlayScene) movePlayer(ev *events.State) {
|
|
delta := s.player.Position()
|
|
var playerSpeed int32 = 8
|
|
var gravity int32 = 2
|
|
|
|
if ev.Down.Now {
|
|
delta.Y += playerSpeed
|
|
}
|
|
if ev.Left.Now {
|
|
delta.X -= playerSpeed
|
|
}
|
|
if ev.Right.Now {
|
|
delta.X += playerSpeed
|
|
}
|
|
if ev.Up.Now {
|
|
delta.Y -= playerSpeed
|
|
}
|
|
|
|
// Apply gravity.
|
|
delta.Y += gravity
|
|
|
|
// Draw a ray and check for collision.
|
|
var lastOk = s.player.Position()
|
|
for point := range render.IterLine2(s.player.Position(), delta) {
|
|
s.player.MoveTo(point)
|
|
if _, ok := doodads.CollidesWithGrid(s.player, &s.canvas); ok {
|
|
s.player.MoveTo(lastOk)
|
|
} else {
|
|
lastOk = s.player.Position()
|
|
}
|
|
}
|
|
|
|
s.player.MoveTo(lastOk)
|
|
}
|
|
|
|
// LoadLevel loads a level from disk.
|
|
func (s *PlayScene) LoadLevel(filename string) error {
|
|
s.canvas = render.Grid{}
|
|
|
|
m, err := level.LoadJSON(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, point := range m.Pixels {
|
|
pixel := render.Pixel{
|
|
X: point.X,
|
|
Y: point.Y,
|
|
}
|
|
s.canvas[pixel] = nil
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Destroy the scene.
|
|
func (s *PlayScene) Destroy() error {
|
|
return nil
|
|
}
|