lints, loading fix

This commit is contained in:
Josh Deprez 2021-10-11 17:33:06 +11:00
parent f2f9b9dd6f
commit 1ff0694049
17 changed files with 92 additions and 46 deletions

View file

@ -52,6 +52,7 @@ type DebugToast struct {
Text string
}
// Draw uses DebugPrintAt to draw d.Text at the position d.Pos.
func (d *DebugToast) Draw(screen *ebiten.Image, _ *ebiten.DrawImageOptions) {
ebitenutil.DebugPrintAt(screen, d.Text, d.Pos.X, d.Pos.Y)
}
@ -60,12 +61,14 @@ func (d *DebugToast) String() string {
return fmt.Sprintf("DebugToast@%v", d.Pos)
}
// Toast sets the text to appear for 2 seconds.
func (d *DebugToast) Toast(text string) {
d.Text = text
d.Timer = 120
d.Hides = false
}
// Update hides the toast text once the timer is exhausted.
func (d *DebugToast) Update() error {
if d.Hides = d.Timer <= 0; !d.Hides {
d.Timer--
@ -78,6 +81,7 @@ type PerfDisplay struct {
Hides
}
// Draw uses DebugPrint to print the TPS and FPS in the top-left.
func (p PerfDisplay) Draw(screen *ebiten.Image, _ *ebiten.DrawImageOptions) {
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f FPS: %0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS()))
}

View file

@ -43,6 +43,8 @@ type DrawDFS struct {
game *Game
}
// Draw draws all descendant components (that are not managed by some other
// DrawManager) in a pre-order traversal.
func (d *DrawDFS) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
stack := []ebiten.DrawImageOptions{*opts}
d.game.Query(d, DrawerType,
@ -81,6 +83,7 @@ func (d *DrawDFS) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
// DrawManager.
func (DrawDFS) ManagesDrawingSubcomponents() {}
// Prepare saves a reference to g.
func (d *DrawDFS) Prepare(g *Game) error {
d.game = g
return nil

View file

@ -39,12 +39,13 @@ func init() {
// Fill fills the screen with a colour.
type Fill struct {
ID
Color color.Color
Colour color.Color
Hides
}
// Draw fills the screen with the colour.
func (f *Fill) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
screen.Fill(opts.ColorM.Apply(f.Color))
screen.Fill(opts.ColorM.Apply(f.Colour))
}
func (f *Fill) String() string { return "Fill" }

View file

@ -22,19 +22,25 @@ import (
"time"
)
// LoadingSwitch switches between two subcomponents. While After is being
// loaded asynchronously, During is shown. Once loading is complete, During
// is hidden and After is shown.
type LoadingSwitch struct {
During Hider
After Hider
During, After interface {
Disabler
Hider
}
assets fs.FS
}
// Scan only scans s.During, thus, only s.During is loaded by Game directly.
// Scan only scans s.During. Only s.During is loaded automatically - s.After is
// loaded asynchronously from Prepare below.
func (s *LoadingSwitch) Scan(visit VisitFunc) error {
return visit(s.During)
}
// Load stores a copy of assets to use later.
// Load stores a copy of assets to pass to s.After.Load later.
func (s *LoadingSwitch) Load(assets fs.FS) error {
s.assets = assets
return nil
@ -43,7 +49,11 @@ func (s *LoadingSwitch) Load(assets fs.FS) error {
// Prepare loads, registers, and prepares.After in a separate goroutine. Once
// ready, LoadingSwitch hides s.During and shows s.After.
func (s *LoadingSwitch) Prepare(game *Game) error {
go func() {
go s.loadAfter(game)
return nil
}
func (s *LoadingSwitch) loadAfter(game *Game) {
startLoad := time.Now()
if err := game.Load(s.After, s.assets); err != nil {
log.Printf("Couldn't load: %v", err)
@ -51,6 +61,9 @@ func (s *LoadingSwitch) Prepare(game *Game) error {
}
log.Printf("LoadingSwitch: finished loading in %v", time.Since(startLoad))
s.After.Disable()
s.After.Hide()
startBuild := time.Now()
if err := game.Register(s.After, s); err != nil {
log.Printf("Couldn't register: %v", err)
@ -65,8 +78,8 @@ func (s *LoadingSwitch) Prepare(game *Game) error {
log.Printf("LoadingSwitch: finished preparing in %v", time.Since(startPrep))
// TODO: better scene transitions
s.During.Disable()
s.During.Hide()
s.After.Enable()
s.After.Show()
}()
return nil
}

View file

@ -28,11 +28,13 @@ func init() {
gob.Register(&SolidRect{})
}
// SolidRect is a minimal implementation of a Collider defined by a single Box.
type SolidRect struct {
ID
geom.Box
}
// CollidesWith reports if r overlaps with s.Box.
func (s SolidRect) CollidesWith(r geom.Box) bool {
return s.Box.Overlaps(r)
}

View file

@ -159,6 +159,7 @@ type Tile interface {
// StaticTile returns a fixed tile index.
type StaticTile int
// Cell returns s as an int.
func (s StaticTile) Cell() int { return int(s) }
// AnimatedTile uses an Anim to choose a tile index.
@ -168,6 +169,7 @@ type AnimatedTile struct {
anim *Anim
}
// Cell returns the value of Cell provided by the animation.
func (a *AnimatedTile) Cell() int { return a.anim.Cell() }
// Scan visits a.anim.

View file

@ -126,6 +126,7 @@ func (u *WallUnit) Scan(visit VisitFunc) error {
return visit(u.Tile)
}
// Transform returns a translation by the position and offset.
func (u *WallUnit) Transform() (opts ebiten.DrawImageOptions) {
opts.GeoM.Translate(geom.CFloat(
geom.CMul(u.pos, u.wall.UnitSize).Add(u.wall.UnitOffset),

View file

@ -81,21 +81,21 @@ func main() {
Projection: geom.SimpleProjection{},
VoxelScale: geom.Float3{
// Each voxel counts for this much (Euclidean) space.
X: 1,
Y: 1,
Z: math.Sqrt(3),
X: 1, Y: 1, Z: math.Sqrt(3),
},
Root: &engine.DrawDFS{
Child: engine.MakeContainer(
&engine.Fill{
ID: "bg_fill",
Color: color.Gray{100},
Colour: color.Gray{100},
},
&engine.LoadingSwitch{
During: &engine.Billboard{
ID: "loading_screen",
During: &engine.Scene{
ID: "loading_scene",
Child: &engine.Billboard{
Src: engine.ImageRef{Path: "assets/loading.png"},
},
},
After: &engine.Camera{
ID: "game_camera",
Child: lev1,

View file

@ -20,5 +20,6 @@ package example
import "embed"
// Assets is the embedded assets FS.
//go:embed assets
var Assets embed.FS

View file

@ -65,6 +65,8 @@ type Awakeman struct {
// Ident returns "awakeman". There should be only one!
func (aw *Awakeman) Ident() string { return "awakeman" }
// Update updates Awakeman, including capturing input, applying gravity and
// movement, and repositioning the camera.
func (aw *Awakeman) Update() error {
// TODO: better cheat for noclip
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
@ -257,6 +259,7 @@ func (aw *Awakeman) realUpdate() error {
return nil
}
// Prepare captures necessary references to other game components.
func (aw *Awakeman) Prepare(game *engine.Game) error {
aw.game = game
cam, ok := game.Component(aw.CameraID).(*engine.Camera)
@ -275,6 +278,7 @@ func (aw *Awakeman) Prepare(game *engine.Game) error {
return nil
}
// Scan visits &aw.Sprite.
func (aw *Awakeman) Scan(visit engine.VisitFunc) error {
return visit(&aw.Sprite)
}

View file

@ -31,6 +31,7 @@ var _ interface {
engine.Updater
} = &Bubble{}
// Bubble implements a single bubble within a simple particle system.
type Bubble struct {
Life int
Sprite engine.Sprite
@ -38,6 +39,8 @@ type Bubble struct {
game *engine.Game
}
// NewBubble creates a bubble. Before it can be used, the return value needs to
// be loaded, registered, and prepared.
func NewBubble(pos geom.Int3) *Bubble {
return &Bubble{
Life: 60,
@ -72,6 +75,7 @@ func NewBubble(pos geom.Int3) *Bubble {
}
}
// Scan visits &b.sprite.
func (b *Bubble) Scan(visit engine.VisitFunc) error {
return visit(&b.Sprite)
}
@ -80,11 +84,14 @@ func (b *Bubble) String() string {
return fmt.Sprintf("Bubble@%v", b.Sprite.Actor.Pos)
}
// Prepare saves a reference to g.
func (b *Bubble) Prepare(g *engine.Game) error {
b.game = g
return nil
}
// Update moves the bubble randomly, and handles unregistering the bubble when
// it has "popped".
func (b *Bubble) Update() error {
b.Life--
if b.Life <= 0 {

View file

@ -26,7 +26,7 @@ type Int3 struct {
X, Y, Z int
}
// Pt3(x, y, z) is shorthand for Int3{x, y, z}.
// Pt3 returns Int3{x, y, z}.
func Pt3(x, y, z int) Int3 {
return Int3{x, y, z}
}

View file

@ -98,7 +98,7 @@ func (a IntMatrix2x3) Apply(v Int3) image.Point {
// RatMatrix3 implements a 3x3 matrix with rational number entries.
type RatMatrix3 [3][3]Rat
// IdentityRatMatrix3x4 is the identity matrix for RatMatrix3x4.
// IdentityRatMatrix3 is the identity matrix for RatMatrix3.
var IdentityRatMatrix3 = RatMatrix3{
0: [3]Rat{0: {1, 1}},
1: [3]Rat{1: {1, 1}},

View file

@ -40,6 +40,11 @@ func Dot(p, q image.Point) int {
return p.X*q.X + p.Y*q.Y
}
// CSign applies Sign componentwise to the Point.
func CSign(p image.Point) image.Point {
return image.Point{X: Sign(p.X), Y: Sign(p.Y)}
}
// ---------- Some other helpers ----------
// FSign returns the sign of the float64 (-1, 0, or 1).

View file

@ -21,6 +21,7 @@ import (
"math"
)
// Cardinal directions, as used in the return from PolygonExtrema.
const (
East = iota
North

View file

@ -54,6 +54,7 @@ func (SimpleProjection) Project(z int) image.Point { return image.Pt(0, z) }
// Projection uses two floats to define a custom projection.
type Projection struct{ X, Y float64 }
// Sign returns the componentwise sign of π.
func (π Projection) Sign() image.Point {
return image.Pt(int(FSign(π.X)), int(FSign(π.Y)))
}
@ -71,7 +72,8 @@ func (π Projection) Project(z int) image.Point {
// be used in e.g. a diametric projection (IntProjection{X:0, Y:2}).
type IntProjection image.Point
func (π IntProjection) Sign() image.Point { return image.Point(π) }
// Sign returns CSign(π).
func (π IntProjection) Sign() image.Point { return CSign(image.Point(π)) }
// Project returns (z/π.X, z/π.Y), unless π.X or π.Y are 0, in which case that
// component is zero

View file

@ -51,7 +51,7 @@ func (s *LinearSpline) Prepare() error {
return nil
}
// Interpolate, given x, returns y where (x,y) is a point on the spline.
// Interpolate returns y where (x,y) is a point on the spline.
// If x is outside the spline, it extrapolates from either the first or
// last segments of the spline.
func (s *LinearSpline) Interpolate(x float64) float64 {
@ -236,9 +236,9 @@ func (s *CubicSpline) Prepare() error {
return nil
}
// Interpolate, given x, returns y where (x,y) is a point on the spline.
// If x is outside the spline, it extrapolates from either the first or
// last segments of the spline.
// Interpolate returns y where (x,y) is a point on the spline.
// If x is outside the spline, it extrapolates from the first or last point
// together with s.Preslope or s.Postslope.
func (s *CubicSpline) Interpolate(x float64) float64 {
N := len(s.Points)
if x < s.Points[0].X {