@@ -26,7 +26,10 @@ const (
26
26
//
27
27
// Use the `Camera.LookAt()` to align the center of the camera to the target.
28
28
type Camera struct {
29
-
29
+ // Top-left X position of camera
30
+ TopLeftX float64
31
+ // Top-left Y position of camera
32
+ TopLeftY float64
30
33
// ZoomFactor is the camera zoom (scaling) factor. Default is 1.
31
34
ZoomFactor float64
32
35
@@ -46,11 +49,11 @@ type Camera struct {
46
49
ShakeOptions * ShakeOptions
47
50
48
51
// 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
54
57
}
55
58
56
59
// NewCamera returns new Camera
@@ -174,48 +177,50 @@ func (cam *Camera) smoothDampY(targetY float64) float64 {
174
177
}
175
178
176
179
// LookAt aligns the midpoint of the camera viewport to the target.
180
+ //
181
+ // Camera motion smoothing is only applied with this method.
177
182
// Use this function only once in Update() and change only the (targetX, targetY)
178
183
func (cam * Camera ) LookAt (targetX , targetY float64 ) {
179
184
switch cam .SmoothType {
180
185
case SmoothDamp :
181
186
if ! cam .XAxisSmoothingDisabled && ! cam .YAxisSmoothingDisabled {
182
187
cam .tempTargetX = cam .smoothDampX (targetX )
183
188
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
186
191
} else if ! cam .XAxisSmoothingDisabled && cam .YAxisSmoothingDisabled {
187
192
cam .tempTargetX = cam .smoothDampX (targetX )
188
- cam .topLeftX = cam .tempTargetX
189
- cam .topLeftY = targetY
193
+ cam .TopLeftX = cam .tempTargetX
194
+ cam .TopLeftY = targetY
190
195
} else if cam .XAxisSmoothingDisabled && ! cam .YAxisSmoothingDisabled {
191
196
cam .tempTargetY = cam .smoothDampY (targetY )
192
- cam .topLeftY = cam .tempTargetY
193
- cam .topLeftX = targetX
197
+ cam .TopLeftY = cam .tempTargetY
198
+ cam .TopLeftX = targetX
194
199
} else {
195
- cam .topLeftX = targetX
196
- cam .topLeftY = targetY
200
+ cam .TopLeftX = targetX
201
+ cam .TopLeftY = targetY
197
202
}
198
203
case Lerp :
199
204
if ! cam .XAxisSmoothingDisabled && ! cam .YAxisSmoothingDisabled {
200
205
cam .tempTargetX = lerp (cam .tempTargetX , targetX , cam .SmoothOptions .LerpSpeedX )
201
206
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
204
209
} else if ! cam .XAxisSmoothingDisabled && cam .YAxisSmoothingDisabled {
205
210
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
208
213
} else if cam .XAxisSmoothingDisabled && ! cam .YAxisSmoothingDisabled {
209
214
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
212
217
} else {
213
- cam .topLeftX = targetX
214
- cam .topLeftY = targetY
218
+ cam .TopLeftX = targetX
219
+ cam .TopLeftY = targetY
215
220
}
216
221
default :
217
- cam .topLeftX = targetX
218
- cam .topLeftY = targetY
222
+ cam .TopLeftX = targetX
223
+ cam .TopLeftY = targetY
219
224
}
220
225
if cam .ShakeEnabled {
221
226
if cam .trauma > 0 {
@@ -243,8 +248,8 @@ func (cam *Camera) LookAt(targetX, targetY float64) {
243
248
244
249
// offset
245
250
cam .actualAngle += cam .angle
246
- cam .topLeftX += cam .traumaOffsetX
247
- cam .topLeftY += cam .traumaOffsetY
251
+ cam .TopLeftX += cam .traumaOffsetX
252
+ cam .TopLeftY += cam .traumaOffsetY
248
253
249
254
// tick
250
255
cam .tick += cam .tickSpeed
@@ -256,8 +261,8 @@ func (cam *Camera) LookAt(targetX, targetY float64) {
256
261
cam .zoomFactorShake = cam .ZoomFactor
257
262
cam .actualAngle = cam .angle
258
263
259
- cam .topLeftX += cam .centerOffsetX
260
- cam .topLeftY += cam .centerOffsetY
264
+ cam .TopLeftX += cam .centerOffsetX
265
+ cam .TopLeftY += cam .centerOffsetY
261
266
262
267
cam .trauma = 0
263
268
cam .traumaOffsetX , cam .traumaOffsetY = 0 , 0
@@ -271,14 +276,33 @@ func (cam *Camera) AddTrauma(factor float64) {
271
276
}
272
277
}
273
278
274
- // TopLeft returns top left position of the camera in world-space
279
+ // TopLeft returns top- left position of the camera in world-space
275
280
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
277
301
}
278
302
279
303
// Center returns center point of the camera in world-space
280
304
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
282
306
}
283
307
284
308
// ActualAngle returns camera rotation angle (including the angle of trauma shaking.).
@@ -310,7 +334,7 @@ func (cam *Camera) Height() float64 {
310
334
return cam .h
311
335
}
312
336
313
- // SetSize sets camera rectangle size
337
+ // SetSize sets camera rectangle size from center.
314
338
func (cam * Camera ) SetSize (w , h float64 ) {
315
339
cx , cy := cam .Center ()
316
340
cam .w , cam .h = w , h
@@ -351,8 +375,8 @@ func (cam *Camera) String() string {
351
375
352
376
return fmt .Sprintf (
353
377
cameraStats ,
354
- cam .topLeftX - cam .centerOffsetX ,
355
- cam .topLeftY - cam .centerOffsetY ,
378
+ cam .TopLeftX - cam .centerOffsetX ,
379
+ cam .TopLeftY - cam .centerOffsetY ,
356
380
cam .actualAngle ,
357
381
cam .zoomFactorShake ,
358
382
cam .ShakeEnabled ,
@@ -389,7 +413,7 @@ func (cam *Camera) ApplyCameraTransformToPoint(x, y float64) (float64, float64)
389
413
390
414
// ApplyCameraTransform applies geometric transformation to given geoM
391
415
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
393
417
geoM .Translate (cam .centerOffsetX , cam .centerOffsetY ) // rotate and scale from center.
394
418
geoM .Rotate (cam .actualAngle ) // rotate
395
419
geoM .Scale (cam .zoomFactorShake , cam .zoomFactorShake ) // apply zoom factor
0 commit comments