Skip to content

Commit 69a987b

Browse files
committed
Added: Right(), Bottom(), SetTopLeft()
1 parent b116164 commit 69a987b

File tree

1 file changed

+59
-35
lines changed

1 file changed

+59
-35
lines changed

camera.go

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ const (
2626
//
2727
// Use the `Camera.LookAt()` to align the center of the camera to the target.
2828
type Camera struct {
29-
29+
// Top-left X position of camera
30+
TopLeftX float64
31+
// Top-left Y position of camera
32+
TopLeftY float64
3033
// ZoomFactor is the camera zoom (scaling) factor. Default is 1.
3134
ZoomFactor float64
3235

@@ -46,11 +49,11 @@ type Camera struct {
4649
ShakeOptions *ShakeOptions
4750

4851
// private
49-
drawOptions *ebiten.DrawImageOptions
50-
drawOptionsCM *colorm.DrawImageOptions
51-
angle, actualAngle, tickSpeed, tick, trauma, w, h, zoomFactorShake float64
52-
tempTargetX, centerOffsetX, topLeftX, traumaOffsetX, currentVelocityX float64
53-
tempTargetY, centerOffsetY, topLeftY, traumaOffsetY, currentVelocityY float64
52+
drawOptions *ebiten.DrawImageOptions
53+
drawOptionsCM *colorm.DrawImageOptions
54+
angle, actualAngle, tickSpeed, tick, trauma, w, h, zoomFactorShake float64
55+
tempTargetX, centerOffsetX, traumaOffsetX, currentVelocityX float64
56+
tempTargetY, centerOffsetY, traumaOffsetY, currentVelocityY float64
5457
}
5558

5659
// NewCamera returns new Camera
@@ -174,48 +177,50 @@ func (cam *Camera) smoothDampY(targetY float64) float64 {
174177
}
175178

176179
// LookAt aligns the midpoint of the camera viewport to the target.
180+
//
181+
// Camera motion smoothing is only applied with this method.
177182
// Use this function only once in Update() and change only the (targetX, targetY)
178183
func (cam *Camera) LookAt(targetX, targetY float64) {
179184
switch cam.SmoothType {
180185
case SmoothDamp:
181186
if !cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
182187
cam.tempTargetX = cam.smoothDampX(targetX)
183188
cam.tempTargetY = cam.smoothDampY(targetY)
184-
cam.topLeftX = cam.tempTargetX
185-
cam.topLeftY = cam.tempTargetY
189+
cam.TopLeftX = cam.tempTargetX
190+
cam.TopLeftY = cam.tempTargetY
186191
} else if !cam.XAxisSmoothingDisabled && cam.YAxisSmoothingDisabled {
187192
cam.tempTargetX = cam.smoothDampX(targetX)
188-
cam.topLeftX = cam.tempTargetX
189-
cam.topLeftY = targetY
193+
cam.TopLeftX = cam.tempTargetX
194+
cam.TopLeftY = targetY
190195
} else if cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
191196
cam.tempTargetY = cam.smoothDampY(targetY)
192-
cam.topLeftY = cam.tempTargetY
193-
cam.topLeftX = targetX
197+
cam.TopLeftY = cam.tempTargetY
198+
cam.TopLeftX = targetX
194199
} else {
195-
cam.topLeftX = targetX
196-
cam.topLeftY = targetY
200+
cam.TopLeftX = targetX
201+
cam.TopLeftY = targetY
197202
}
198203
case Lerp:
199204
if !cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
200205
cam.tempTargetX = lerp(cam.tempTargetX, targetX, cam.SmoothOptions.LerpSpeedX)
201206
cam.tempTargetY = lerp(cam.tempTargetY, targetY, cam.SmoothOptions.LerpSpeedY)
202-
cam.topLeftX = cam.tempTargetX
203-
cam.topLeftY = cam.tempTargetY
207+
cam.TopLeftX = cam.tempTargetX
208+
cam.TopLeftY = cam.tempTargetY
204209
} else if !cam.XAxisSmoothingDisabled && cam.YAxisSmoothingDisabled {
205210
cam.tempTargetX = lerp(cam.tempTargetX, targetX, cam.SmoothOptions.LerpSpeedX)
206-
cam.topLeftX = cam.tempTargetX
207-
cam.topLeftY = targetY
211+
cam.TopLeftX = cam.tempTargetX
212+
cam.TopLeftY = targetY
208213
} else if cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
209214
cam.tempTargetY = lerp(cam.tempTargetY, targetY, cam.SmoothOptions.LerpSpeedY)
210-
cam.topLeftY = cam.tempTargetY
211-
cam.topLeftX = targetX
215+
cam.TopLeftY = cam.tempTargetY
216+
cam.TopLeftX = targetX
212217
} else {
213-
cam.topLeftX = targetX
214-
cam.topLeftY = targetY
218+
cam.TopLeftX = targetX
219+
cam.TopLeftY = targetY
215220
}
216221
default:
217-
cam.topLeftX = targetX
218-
cam.topLeftY = targetY
222+
cam.TopLeftX = targetX
223+
cam.TopLeftY = targetY
219224
}
220225
if cam.ShakeEnabled {
221226
if cam.trauma > 0 {
@@ -243,8 +248,8 @@ func (cam *Camera) LookAt(targetX, targetY float64) {
243248

244249
// offset
245250
cam.actualAngle += cam.angle
246-
cam.topLeftX += cam.traumaOffsetX
247-
cam.topLeftY += cam.traumaOffsetY
251+
cam.TopLeftX += cam.traumaOffsetX
252+
cam.TopLeftY += cam.traumaOffsetY
248253

249254
// tick
250255
cam.tick += cam.tickSpeed
@@ -256,8 +261,8 @@ func (cam *Camera) LookAt(targetX, targetY float64) {
256261
cam.zoomFactorShake = cam.ZoomFactor
257262
cam.actualAngle = cam.angle
258263

259-
cam.topLeftX += cam.centerOffsetX
260-
cam.topLeftY += cam.centerOffsetY
264+
cam.TopLeftX += cam.centerOffsetX
265+
cam.TopLeftY += cam.centerOffsetY
261266

262267
cam.trauma = 0
263268
cam.traumaOffsetX, cam.traumaOffsetY = 0, 0
@@ -271,14 +276,33 @@ func (cam *Camera) AddTrauma(factor float64) {
271276
}
272277
}
273278

274-
// TopLeft returns top left position of the camera in world-space
279+
// TopLeft returns top-left position of the camera in world-space
275280
func (cam *Camera) TopLeft() (X float64, Y float64) {
276-
return cam.topLeftX, cam.topLeftY
281+
return cam.TopLeftX, cam.TopLeftY
282+
}
283+
284+
// Right returns the right edge position of the camera in world-space.
285+
func (cam *Camera) Right() float64 {
286+
return cam.TopLeftX + cam.w
287+
}
288+
289+
// Bottom returns the bottom edge position of the camera in world-space.
290+
func (cam *Camera) Bottom() float64 {
291+
return cam.TopLeftY + cam.h
292+
}
293+
294+
// SetTopLeft sets top-left position of the camera in world-space.
295+
//
296+
// Unlike the LookAt() method, the position is set directly without any smoothing.
297+
//
298+
// Useful for static cameras.
299+
func (cam *Camera) SetTopLeft(x, y float64) {
300+
cam.TopLeftX, cam.TopLeftY = x, y
277301
}
278302

279303
// Center returns center point of the camera in world-space
280304
func (cam *Camera) Center() (X float64, Y float64) {
281-
return cam.topLeftX - cam.centerOffsetX, cam.topLeftY - cam.centerOffsetY
305+
return cam.TopLeftX - cam.centerOffsetX, cam.TopLeftY - cam.centerOffsetY
282306
}
283307

284308
// ActualAngle returns camera rotation angle (including the angle of trauma shaking.).
@@ -310,7 +334,7 @@ func (cam *Camera) Height() float64 {
310334
return cam.h
311335
}
312336

313-
// SetSize sets camera rectangle size
337+
// SetSize sets camera rectangle size from center.
314338
func (cam *Camera) SetSize(w, h float64) {
315339
cx, cy := cam.Center()
316340
cam.w, cam.h = w, h
@@ -351,8 +375,8 @@ func (cam *Camera) String() string {
351375

352376
return fmt.Sprintf(
353377
cameraStats,
354-
cam.topLeftX-cam.centerOffsetX,
355-
cam.topLeftY-cam.centerOffsetY,
378+
cam.TopLeftX-cam.centerOffsetX,
379+
cam.TopLeftY-cam.centerOffsetY,
356380
cam.actualAngle,
357381
cam.zoomFactorShake,
358382
cam.ShakeEnabled,
@@ -389,7 +413,7 @@ func (cam *Camera) ApplyCameraTransformToPoint(x, y float64) (float64, float64)
389413

390414
// ApplyCameraTransform applies geometric transformation to given geoM
391415
func (cam *Camera) ApplyCameraTransform(geoM *ebiten.GeoM) {
392-
geoM.Translate(-cam.topLeftX, -cam.topLeftY) // camera movement
416+
geoM.Translate(-cam.TopLeftX, -cam.TopLeftY) // camera movement
393417
geoM.Translate(cam.centerOffsetX, cam.centerOffsetY) // rotate and scale from center.
394418
geoM.Rotate(cam.actualAngle) // rotate
395419
geoM.Scale(cam.zoomFactorShake, cam.zoomFactorShake) // apply zoom factor

0 commit comments

Comments
 (0)