Skip to content

Commit b116164

Browse files
committed
Added:
smoothDampX() smoothDampY() XAxisSmoothingDisabled bool YAxisSmoothingDisabled bool
1 parent e068166 commit b116164

File tree

2 files changed

+88
-45
lines changed

2 files changed

+88
-45
lines changed

camera.go

Lines changed: 85 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ type Camera struct {
3939
// If ShakeEnabled is false, AddTrauma() has no effect and shake is always 0.
4040
//
4141
// The default value is false
42-
ShakeEnabled bool
43-
42+
ShakeEnabled bool
43+
XAxisSmoothingDisabled bool
44+
YAxisSmoothingDisabled bool
4445
// ShakeOptions holds the camera shake options.
4546
ShakeOptions *ShakeOptions
4647

@@ -92,90 +93,129 @@ func DefaultCameraShakeOptions() *ShakeOptions {
9293
return opt
9394
}
9495

95-
// smoothDamp gradually changes a value towards a desired goal over time.
96-
func (cam *Camera) smoothDamp(targetX, targetY float64) (float64, float64) {
97-
// Ensure smooth times are not too small to avoid division by zero
96+
// smoothDampX gradually changes a value towards a desired goal over time for X axis.
97+
func (cam *Camera) smoothDampX(targetX float64) float64 {
98+
// Ensure smooth time is not too small to avoid division by zero
9899
smoothTimeX := math.Max(0.0001, cam.SmoothOptions.SmoothDampTimeX)
99-
smoothTimeY := math.Max(0.0001, cam.SmoothOptions.SmoothDampTimeY)
100100

101-
// Calculate exponential decay factors for X and Y
101+
// Calculate exponential decay factor for X
102102
omegaX := 2.0 / smoothTimeX
103-
omegaY := 2.0 / smoothTimeY
104-
105103
xX := omegaX * 0.016666666666666666
106-
xY := omegaY * 0.016666666666666666
107-
108104
expX := 1.0 / (1.0 + xX + 0.48*xX*xX + 0.235*xX*xX*xX)
109-
expY := 1.0 / (1.0 + xY + 0.48*xY*xY + 0.235*xY*xY*xY)
110105

111-
// Calculate change with independent max speeds
106+
// Calculate change with max speed
112107
changeX := cam.tempTargetX - targetX
113-
changeY := cam.tempTargetY - targetY
114-
115108
originalToX := targetX
116-
originalToY := targetY
117-
118109
maxChangeX := cam.SmoothOptions.SmoothDampMaxSpeedX * smoothTimeX
119-
maxChangeY := cam.SmoothOptions.SmoothDampMaxSpeedY * smoothTimeY
120-
121110
maxChangeXSq := maxChangeX * maxChangeX
122-
maxChangeYSq := maxChangeY * maxChangeY
123111

124-
// Limit change independently for X and Y
112+
// Limit change
125113
if changeX*changeX > maxChangeXSq {
126114
changeX = math.Copysign(maxChangeX, changeX)
127115
}
128116

117+
targetX = cam.tempTargetX - changeX
118+
119+
// Calculate velocity and output with exponential decay
120+
tempVelocityX := (cam.currentVelocityX + changeX*omegaX) * 0.016666666666666666
121+
cam.currentVelocityX = (cam.currentVelocityX - tempVelocityX*omegaX) * expX
122+
outputX := targetX + (changeX+tempVelocityX)*expX
123+
124+
// Check if we've overshot the target
125+
origMinusCurrentX := originalToX - cam.tempTargetX
126+
outMinusOrigX := outputX - originalToX
127+
128+
if origMinusCurrentX*outMinusOrigX > 0 {
129+
outputX = originalToX
130+
cam.currentVelocityX = (outputX - originalToX) / 0.016666666666666666
131+
}
132+
133+
return outputX
134+
}
135+
136+
// smoothDampY gradually changes a value towards a desired goal over time for Y axis.
137+
func (cam *Camera) smoothDampY(targetY float64) float64 {
138+
// Ensure smooth time is not too small to avoid division by zero
139+
smoothTimeY := math.Max(0.0001, cam.SmoothOptions.SmoothDampTimeY)
140+
141+
// Calculate exponential decay factor for Y
142+
omegaY := 2.0 / smoothTimeY
143+
xY := omegaY * 0.016666666666666666
144+
expY := 1.0 / (1.0 + xY + 0.48*xY*xY + 0.235*xY*xY*xY)
145+
146+
// Calculate change with max speed
147+
changeY := cam.tempTargetY - targetY
148+
originalToY := targetY
149+
maxChangeY := cam.SmoothOptions.SmoothDampMaxSpeedY * smoothTimeY
150+
maxChangeYSq := maxChangeY * maxChangeY
151+
152+
// Limit change
129153
if changeY*changeY > maxChangeYSq {
130154
changeY = math.Copysign(maxChangeY, changeY)
131155
}
132156

133-
targetX = cam.tempTargetX - changeX
134157
targetY = cam.tempTargetY - changeY
135158

136-
// Calculate velocity and output with independent exponential decay
137-
tempVelocityX := (cam.currentVelocityX + changeX*omegaX) * 0.016666666666666666
159+
// Calculate velocity and output with exponential decay
138160
tempVelocityY := (cam.currentVelocityY + changeY*omegaY) * 0.016666666666666666
139-
140-
cam.currentVelocityX = (cam.currentVelocityX - tempVelocityX*omegaX) * expX
141161
cam.currentVelocityY = (cam.currentVelocityY - tempVelocityY*omegaY) * expY
142-
143-
outputX := targetX + (changeX+tempVelocityX)*expX
144162
outputY := targetY + (changeY+tempVelocityY)*expY
145163

146-
origMinusCurrentX := originalToX - cam.tempTargetX
164+
// Check if we've overshot the target
147165
origMinusCurrentY := originalToY - cam.tempTargetY
148-
149-
outMinusOrigX := outputX - originalToX
150166
outMinusOrigY := outputY - originalToY
151167

152-
dot := origMinusCurrentX*outMinusOrigX + origMinusCurrentY*outMinusOrigY
153-
154-
if dot > 0 {
155-
outputX = originalToX
168+
if origMinusCurrentY*outMinusOrigY > 0 {
156169
outputY = originalToY
157-
cam.currentVelocityX = (outputX - originalToX) / 0.016666666666666666
158170
cam.currentVelocityY = (outputY - originalToY) / 0.016666666666666666
159171
}
160172

161-
return outputX, outputY
173+
return outputY
162174
}
163175

164176
// LookAt aligns the midpoint of the camera viewport to the target.
165177
// Use this function only once in Update() and change only the (targetX, targetY)
166178
func (cam *Camera) LookAt(targetX, targetY float64) {
167179
switch cam.SmoothType {
168180
case SmoothDamp:
169-
cam.tempTargetX, cam.tempTargetY = cam.smoothDamp(targetX, targetY)
170-
cam.topLeftX = cam.tempTargetX
171-
cam.topLeftY = cam.tempTargetY
172-
181+
if !cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
182+
cam.tempTargetX = cam.smoothDampX(targetX)
183+
cam.tempTargetY = cam.smoothDampY(targetY)
184+
cam.topLeftX = cam.tempTargetX
185+
cam.topLeftY = cam.tempTargetY
186+
} else if !cam.XAxisSmoothingDisabled && cam.YAxisSmoothingDisabled {
187+
cam.tempTargetX = cam.smoothDampX(targetX)
188+
cam.topLeftX = cam.tempTargetX
189+
cam.topLeftY = targetY
190+
} else if cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
191+
cam.tempTargetY = cam.smoothDampY(targetY)
192+
cam.topLeftY = cam.tempTargetY
193+
cam.topLeftX = targetX
194+
} else {
195+
cam.topLeftX = targetX
196+
cam.topLeftY = targetY
197+
}
173198
case Lerp:
174-
cam.tempTargetX = lerp(cam.tempTargetX, targetX, cam.SmoothOptions.LerpSpeedX)
175-
cam.tempTargetY = lerp(cam.tempTargetY, targetY, cam.SmoothOptions.LerpSpeedY)
176-
cam.topLeftX, cam.topLeftY = cam.tempTargetX, cam.tempTargetY
199+
if !cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
200+
cam.tempTargetX = lerp(cam.tempTargetX, targetX, cam.SmoothOptions.LerpSpeedX)
201+
cam.tempTargetY = lerp(cam.tempTargetY, targetY, cam.SmoothOptions.LerpSpeedY)
202+
cam.topLeftX = cam.tempTargetX
203+
cam.topLeftY = cam.tempTargetY
204+
} else if !cam.XAxisSmoothingDisabled && cam.YAxisSmoothingDisabled {
205+
cam.tempTargetX = lerp(cam.tempTargetX, targetX, cam.SmoothOptions.LerpSpeedX)
206+
cam.topLeftX = cam.tempTargetX
207+
cam.topLeftY = targetY
208+
} else if cam.XAxisSmoothingDisabled && !cam.YAxisSmoothingDisabled {
209+
cam.tempTargetY = lerp(cam.tempTargetY, targetY, cam.SmoothOptions.LerpSpeedY)
210+
cam.topLeftY = cam.tempTargetY
211+
cam.topLeftX = targetX
212+
} else {
213+
cam.topLeftX = targetX
214+
cam.topLeftY = targetY
215+
}
177216
default:
178-
cam.topLeftX, cam.topLeftY = targetX, targetY
217+
cam.topLeftX = targetX
218+
cam.topLeftY = targetY
179219
}
180220
if cam.ShakeEnabled {
181221
if cam.trauma > 0 {

examples/platformer/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var ScreenWidth, ScreenHeight = 512, 512
2828
const crossHairLength float32 = 200.0
2929

3030
func main() {
31+
3132
ebiten.SetWindowSize(ScreenWidth, ScreenHeight)
3233
if err := ebiten.RunGame(&Game{}); err != nil {
3334
log.Fatal(err)
@@ -48,6 +49,8 @@ func init() {
4849
Controller.SetPhyicsScale(2.2)
4950
cam.SmoothType = kamera.SmoothDamp
5051
cam.SmoothOptions.SmoothDampTimeY = 1
52+
// cam.YAxisSmoothingDisabled = true
53+
// cam.XAxisSmoothingDisabled = true
5154
}
5255

5356
func Translate(box *[4]float64, x, y float64) {

0 commit comments

Comments
 (0)