commit e0dd81ac35ef47da72ef7afda665fc1df8f3923e
parent c909df6dd91353320591b79101cb0c7bc0af897b
Author: bsandro <brian.drosan@gmail.com>
Date: Mon, 11 Oct 2021 00:03:23 +0300
render only tiles that are on screen (or adjacent)
Diffstat:
3 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/camera.go b/camera.go
@@ -5,13 +5,16 @@ import (
)
type Camera struct {
- x, y float64
- maxWidth, maxHeight float64
+ x, y float64 // current position (top left corner)
+ maxWidth, maxHeight float64 // global browsable area size
+ width, height float64 // viewport size
}
-func (cam *Camera) Init(maxWidth, maxHeight float64) {
- cam.maxWidth = maxWidth
- cam.maxHeight = maxHeight
+func (cam *Camera) Init(width, height, maxWidth, maxHeight float64) {
+ cam.width = width
+ cam.height = height
+ cam.maxWidth = maxWidth - width
+ cam.maxHeight = maxHeight - height
}
func (cam *Camera) ChangeX(diff float64) {
diff --git a/gamemap.go b/gamemap.go
@@ -33,6 +33,7 @@ type Tile struct {
Options *ebiten.DrawImageOptions
Image *ebiten.Image
Gid uint32
+ x, y float64 // position coordinates
}
type Layer struct {
@@ -96,7 +97,9 @@ func (l *Layer) Init(gamemap *Gamemap) error {
// shifting picture back after rotating the matrix
tile.Options.GeoM.Translate(float64(t_width)/2, float64(t_height)/2)
// setting tile coordinates on the map
- tile.Options.GeoM.Translate(float64((uint32(i)%gamemap.Width)*t_width), float64((uint32(i)/gamemap.Width)*t_height))
+ tile.x = float64((uint32(i) % gamemap.Width) * t_width)
+ tile.y = float64((uint32(i) / gamemap.Width) * t_height)
+ tile.Options.GeoM.Translate(tile.x, tile.y)
sx := int((tile.Gid % tileset.Columns) * t_width)
sy := int((tile.Gid / tileset.Columns) * t_height)
tile.Image = tileset.Atlas.SubImage(image.Rect(sx, sy, sx+int(t_width), sy+int(t_height))).(*ebiten.Image)
@@ -159,3 +162,13 @@ func (m *Gamemap) findTileset(gid uint32) *Tileset {
}
return ret
}
+
+func (t *Tile) IsOnScreen(cam *Camera, gamemap *Gamemap) bool {
+ var left float64 = cam.x - float64(gamemap.TileWidth)
+ var right float64 = cam.x + float64(gamemap.TileWidth) + cam.width
+ var top float64 = cam.y - float64(gamemap.TileHeight)
+ var bottom float64 = cam.y + float64(gamemap.TileHeight) + cam.height
+
+ return t.x >= left && t.x < right && t.y >= top && t.y < bottom
+
+}
diff --git a/main.go b/main.go
@@ -12,10 +12,10 @@ import (
)
const (
- screenW = 1280
- screenH = 480
- magnification = 2
- cameraStep = 10
+ screenW = 1280
+ screenH = 480
+ scale = 2
+ cameraStep = 10
)
type Game struct {
@@ -37,7 +37,7 @@ func (g *Game) Init() error {
return err
}
- g.Cam.Init(g.Map.RealWidth-screenW/magnification, g.Map.RealHeight-screenH/magnification)
+ g.Cam.Init(screenW/scale, screenH/scale, g.Map.RealWidth, g.Map.RealHeight)
return nil
}
@@ -66,16 +66,20 @@ func (g *Game) Update() error {
func (g *Game) Draw(screen *ebiten.Image) {
for _, layer := range g.Map.Layers {
for _, t := range layer.Tiles {
- opts := *t.Options
- opts.GeoM.Translate(-g.Cam.x, -g.Cam.y)
- screen.DrawImage(t.Image, &opts)
+ if t.IsOnScreen(&g.Cam, g.Map) {
+ // render options for that tile are being copied into opts so the cam
+ // movement transformations are not dragged back into the tile itself.
+ opts := *t.Options
+ opts.GeoM.Translate(-g.Cam.x, -g.Cam.y)
+ screen.DrawImage(t.Image, &opts)
+ }
}
}
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f, screen: %v", ebiten.CurrentTPS(), g.Cam))
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
- return screenW / magnification, screenH / magnification
+ return screenW / scale, screenH / scale
}
func main() {