lints, loading fix
This commit is contained in:
parent
f2f9b9dd6f
commit
1ff0694049
17 changed files with 92 additions and 46 deletions
|
@ -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()))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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),
|
||||
|
|
12
example.go
12
example.go
|
@ -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,
|
||||
|
|
|
@ -20,5 +20,6 @@ package example
|
|||
|
||||
import "embed"
|
||||
|
||||
// Assets is the embedded assets FS.
|
||||
//go:embed assets
|
||||
var Assets embed.FS
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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}},
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"math"
|
||||
)
|
||||
|
||||
// Cardinal directions, as used in the return from PolygonExtrema.
|
||||
const (
|
||||
East = iota
|
||||
North
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue