camera responsible for drawing scene
This commit is contained in:
parent
cdcad14245
commit
a50731023a
2 changed files with 37 additions and 15 deletions
|
@ -6,8 +6,9 @@ import (
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Camera models a camera that is viewing a scene. Changes to the
|
// Camera models a camera that is viewing a scene.
|
||||||
// configuration take effect immediately.
|
// Changes to the configuration take effect immediately.
|
||||||
|
// Camera ignores Scene.Draw and calls Scene's children's Draw.
|
||||||
type Camera struct {
|
type Camera struct {
|
||||||
ID
|
ID
|
||||||
Scene *Scene
|
Scene *Scene
|
||||||
|
@ -15,16 +16,20 @@ type Camera struct {
|
||||||
// Camera controls
|
// Camera controls
|
||||||
Bounds image.Rectangle // world coordinates
|
Bounds image.Rectangle // world coordinates
|
||||||
Centre image.Point // world coordinates
|
Centre image.Point // world coordinates
|
||||||
//Rotation float64 // radians
|
|
||||||
Zoom float64 // unitless
|
|
||||||
|
|
||||||
Filter ebiten.Filter
|
Filter ebiten.Filter
|
||||||
|
Zoom float64 // unitless
|
||||||
|
|
||||||
game *Game
|
game *Game
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw applies transformations to opts, then calls c.Scene.Draw with it.
|
// Draw applies transformations to opts, then calls c.Scene.Draw with it.
|
||||||
func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||||
|
if c.Scene.Hidden {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the geometry matrix for the camera controls.
|
||||||
|
|
||||||
// The lower bound on zoom is the larger of
|
// The lower bound on zoom is the larger of
|
||||||
// { (ScreenWidth / BoundsWidth), (ScreenHeight / BoundsHeight) }
|
// { (ScreenWidth / BoundsWidth), (ScreenHeight / BoundsHeight) }
|
||||||
zoom := c.Zoom
|
zoom := c.Zoom
|
||||||
|
@ -54,19 +59,30 @@ func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||||
centre.Y = c.Bounds.Max.Y - shz
|
centre.Y = c.Bounds.Max.Y - shz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply camera controls to geom.
|
|
||||||
// 1. Move centre to the origin
|
|
||||||
opts.GeoM.Translate(-float64(centre.X), -float64(centre.Y))
|
|
||||||
// 2. Zoom and rotate
|
|
||||||
opts.GeoM.Scale(zoom, zoom)
|
|
||||||
//geom.Rotate(c.Rotation)
|
|
||||||
// 3. Move the origin to the centre of screen space.
|
|
||||||
opts.GeoM.Translate(sw2, sh2)
|
|
||||||
|
|
||||||
// Apply other options
|
// Apply other options
|
||||||
opts.Filter = c.Filter
|
opts.Filter = c.Filter
|
||||||
|
|
||||||
c.Scene.Draw(screen, opts)
|
// Draw everything.
|
||||||
|
og := opts.GeoM
|
||||||
|
for _, i := range c.Scene.Components {
|
||||||
|
if d, ok := i.(Drawer); ok {
|
||||||
|
cs := 1.0
|
||||||
|
if s, ok := i.(CoordScaler); ok {
|
||||||
|
cs = s.CoordScale()
|
||||||
|
}
|
||||||
|
var geom ebiten.GeoM
|
||||||
|
// 1. Move centre to the origin, subject to CoordScale
|
||||||
|
geom.Translate(-float64(centre.X)*cs, -float64(centre.Y)*cs)
|
||||||
|
// 2. Zoom (this is also where rotation would be)
|
||||||
|
geom.Scale(zoom, zoom)
|
||||||
|
// 3. Move the origin to the centre of screen space.
|
||||||
|
geom.Translate(sw2, sh2)
|
||||||
|
// 4. Apply transforms from the caller.
|
||||||
|
geom.Concat(og)
|
||||||
|
opts.GeoM = geom
|
||||||
|
d.Draw(screen, opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update passes the call to c.Scene.
|
// Update passes the call to c.Scene.
|
||||||
|
|
|
@ -11,6 +11,12 @@ type Collider interface {
|
||||||
CollidesWith(image.Rectangle) bool
|
CollidesWith(image.Rectangle) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CoordScaler components have a scaling factor. This is used for
|
||||||
|
// e.g. parallax layers in a scene, and can be thought of as 1/distance.
|
||||||
|
type CoordScaler interface {
|
||||||
|
CoordScale() float64
|
||||||
|
}
|
||||||
|
|
||||||
// Drawer components can draw themselves. Draw is called often.
|
// Drawer components can draw themselves. Draw is called often.
|
||||||
// Each component is responsible for calling Draw on its child components
|
// Each component is responsible for calling Draw on its child components
|
||||||
// (so that hiding the parent can hide the children, etc).
|
// (so that hiding the parent can hide the children, etc).
|
||||||
|
|
Loading…
Reference in a new issue