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"
|
||||
)
|
||||
|
||||
// Camera models a camera that is viewing a scene. Changes to the
|
||||
// configuration take effect immediately.
|
||||
// Camera models a camera that is viewing a scene.
|
||||
// Changes to the configuration take effect immediately.
|
||||
// Camera ignores Scene.Draw and calls Scene's children's Draw.
|
||||
type Camera struct {
|
||||
ID
|
||||
Scene *Scene
|
||||
|
@ -15,16 +16,20 @@ type Camera struct {
|
|||
// Camera controls
|
||||
Bounds image.Rectangle // world coordinates
|
||||
Centre image.Point // world coordinates
|
||||
//Rotation float64 // radians
|
||||
Zoom float64 // unitless
|
||||
|
||||
Filter ebiten.Filter
|
||||
Zoom float64 // unitless
|
||||
|
||||
game *Game
|
||||
}
|
||||
|
||||
// Draw applies transformations to opts, then calls c.Scene.Draw with it.
|
||||
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
|
||||
// { (ScreenWidth / BoundsWidth), (ScreenHeight / BoundsHeight) }
|
||||
zoom := c.Zoom
|
||||
|
@ -54,19 +59,30 @@ func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
|||
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
|
||||
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.
|
||||
|
|
|
@ -11,6 +11,12 @@ type Collider interface {
|
|||
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.
|
||||
// Each component is responsible for calling Draw on its child components
|
||||
// (so that hiding the parent can hide the children, etc).
|
||||
|
|
Loading…
Reference in a new issue