package sim // Camera är en vy över världen som följer en punkt men aldrig visar utanför // kartan. Är världen mindre än vyn centreras den i stället. type Camera struct { ViewW, ViewH float64 WorldW, WorldH float64 Margin float64 // så många pixlar utanför världen får vyn visa (räls vid kanten) X, Y float64 // vyns övre vänstra hörn i världskoordinater } // NewCamera skapar en kamera för en värld av given storlek (pixlar). func NewCamera(viewW, viewH, worldW, worldH float64) *Camera { c := &Camera{ViewW: viewW, ViewH: viewH, WorldW: worldW, WorldH: worldH} c.Follow(worldW/2, worldH/2) return c } // Follow centrerar vyn på (cx, cy) och klampar mot världens kanter (plus // Margin). func (c *Camera) Follow(cx, cy float64) { c.X = clampAxis(cx-c.ViewW/2+c.Margin, c.ViewW, c.WorldW+2*c.Margin) - c.Margin c.Y = clampAxis(cy-c.ViewH/2+c.Margin, c.ViewH, c.WorldH+2*c.Margin) - c.Margin } // Offset returnerar översättningen världs- -> skärmkoordinater. func (c *Camera) Offset() (ox, oy float64) { return -c.X, -c.Y } func clampAxis(pos, view, world float64) float64 { if world <= view { return -(view - world) / 2 // centrera en liten värld } if pos < 0 { return 0 } if max := world - view; pos > max { return max } return pos }