Skip to content

Commit d541a9b

Browse files
committed
Make sure camera zoom is not lower than minimal allowed zoom when smooth tracking is disabled.
See #65
1 parent 3f20d91 commit d541a9b

File tree

5 files changed

+77
-24
lines changed

5 files changed

+77
-24
lines changed

changelog.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
---------------------------------------------------------------------------------------------------
2+
Version: 2.0.2
3+
4+
Bugfixes:
5+
- Make sure camera zoom is not lower than minimal allowed zoom when smooth tracking is disabled.
6+
---------------------------------------------------------------------------------------------------
27
Version: 2.0.1
38
Date: 22-10-204
49
Bugfixes:

scripts/camera.lua

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ function Camera.followTracker(playerSettings, player, camera, tracker, disableSm
166166
else
167167
camera.centerPos = tracker.centerPos
168168
camera.zoom = Camera.zoom(camera, tracker)
169+
Camera.sanitizeZoom(camera, playerSettings, player)
169170
end
170171

171172
Camera.refreshChartTags(player, camera, captureBox, camera.centerPos, camera.zoom)
@@ -196,19 +197,7 @@ function Camera.followTrackerSmooth(playerSettings, player, camera, tracker)
196197
transitionData.transitionTicksLeft = transitionData.transitionTicksLeft - 1
197198

198199
camera.centerPos, camera.zoom = Camera.CameraTransition.lerp(transitionData)
199-
200-
if camera.zoom < minZoom then
201-
if playerSettings.noticeMaxZoom == nil then
202-
player.print({ "max-zoom" }, { r = 1 })
203-
player.print({ "msg-once" })
204-
playerSettings.noticeMaxZoom = true
205-
end
206-
207-
camera.zoom = minZoom
208-
else
209-
-- Max (min actually) zoom is not reached (anymore)
210-
playerSettings.noticeMaxZoom = nil
211-
end
200+
Camera.sanitizeZoom(camera, playerSettings, player)
212201

213202
if transitionData.transitionTicksLeft <= 0 then
214203
-- Transition finished
@@ -241,6 +230,25 @@ function Camera.zoom(camera, tracker)
241230
return math.min(zoomX, zoomY, maxZoom)
242231
end
243232

233+
-- Check if the camera zoom is valid
234+
--- @param camera Camera.camera
235+
--- @param playerSettings playerSettings
236+
--- @param player LuaPlayer
237+
function Camera.sanitizeZoom(camera, playerSettings, player)
238+
if camera.zoom < minZoom then
239+
if playerSettings.noticeMaxZoom == nil then
240+
player.print({ "max-zoom" }, { r = 1 })
241+
player.print({ "msg-once" })
242+
playerSettings.noticeMaxZoom = true
243+
end
244+
245+
camera.zoom = minZoom
246+
else
247+
-- Max (min actually) zoom is not reached (anymore)
248+
playerSettings.noticeMaxZoom = nil
249+
end
250+
end
251+
244252
---@param camera Camera.camera
245253
---@param activeTracker Tracker.tracker
246254
function Camera.getScreenshotInterval(camera, activeTracker)
@@ -254,7 +262,12 @@ function Camera.getScreenshotInterval(camera, activeTracker)
254262
return camera.screenshotInterval
255263
end
256264

257-
function Camera.setWidth(camera, width)
265+
-- Set the camera (resolution) width
266+
--- @param playerSettings playerSettings
267+
--- @param player LuaPlayer
268+
--- @param camera Camera.camera
269+
--- @param width any Camera (resolution) width
270+
function Camera.setWidth(playerSettings, player, camera, width)
258271
width = tonumber(width)
259272

260273
if width == nil or width < 320 then
@@ -268,13 +281,17 @@ function Camera.setWidth(camera, width)
268281
local _, activeTracker = Tracker.findActiveTracker(camera.trackers, camera.surfaceName)
269282
if activeTracker ~= nil then
270283
-- Force update zoom level to make sure the tracked area stays the same
271-
---@diagnostic disable-next-line: param-type-mismatch player(Data) can be nil when disableSmooth is true
272-
Camera.followTracker(nil, nil, camera, activeTracker, true)
284+
Camera.followTracker(playerSettings, player, camera, activeTracker, true)
273285
end
274286
end
275287
end
276288

277-
function Camera.setHeight(camera, height)
289+
-- Set the camera (resolution) height
290+
--- @param playerSettings playerSettings
291+
--- @param player LuaPlayer
292+
--- @param camera Camera.camera
293+
--- @param height any Camera (resolution) height
294+
function Camera.setHeight(playerSettings, player, camera, height)
278295
height = tonumber(height)
279296

280297
if height == nil or height < 240 then
@@ -288,8 +305,7 @@ function Camera.setHeight(camera, height)
288305
local _, activeTracker = Tracker.findActiveTracker(camera.trackers, camera.surfaceName)
289306
if activeTracker ~= nil then
290307
-- Force update zoom level to make sure the tracked area stays the same
291-
---@diagnostic disable-next-line: param-type-mismatch player(Data) can be nil when disableSmooth is true
292-
Camera.followTracker(nil, nil, camera, activeTracker, true)
308+
Camera.followTracker(playerSettings, player, camera, activeTracker, true)
293309
end
294310
end
295311
end

scripts/gui.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,11 +549,13 @@ function GUI.onTextChanged(event)
549549
playerSettings.cameras[playerSettings.guiPersist.selectedCamera]
550550
)
551551
elseif event.element.name == "camera-resolution-x" then
552-
Camera.setWidth(playerSettings.cameras[playerSettings.guiPersist.selectedCamera], event.element.text)
552+
Camera.setWidth(playerSettings, playerSettings.cameras[playerSettings.guiPersist.selectedCamera],
553+
event.element.text)
553554
GUI.updateCameraInfo(playerSettings.gui.cameraInfo,
554555
playerSettings.cameras[playerSettings.guiPersist.selectedCamera])
555556
elseif event.element.name == "camera-resolution-y" then
556-
Camera.setHeight(playerSettings.cameras[playerSettings.guiPersist.selectedCamera], event.element.text)
557+
Camera.setHeight(playerSettings, playerSettings.cameras[playerSettings.guiPersist.selectedCamera],
558+
event.element.text)
557559
GUI.updateCameraInfo(playerSettings.gui.cameraInfo,
558560
playerSettings.cameras[playerSettings.guiPersist.selectedCamera])
559561
elseif event.element.name == "camera-frame-rate" then

tests/camera.lua

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ function TestCamera:SetUp()
8282
-- Make cameras easier to test
8383
self.testCameraPlayer1 = storage.playerSettings[1].cameras[1]
8484
self.testCameraPlayer2 = storage.playerSettings[2].cameras[1]
85+
self.testPlayer1 = storage.playerSettings[1]
8586
for _, playerSettings in pairs(storage.playerSettings) do
8687
for _, camera in pairs(playerSettings.cameras) do
8788
for k, v in pairs(
@@ -191,12 +192,14 @@ function TestCamera:TestResolutionChange()
191192

192193
-- force set camera position and zoom
193194
---@diagnostic disable-next-line: param-type-mismatch player(Data) can be nil when disableSmooth is true
194-
TLBE.Camera.followTracker(nil, nil, self.testCameraPlayer1, baseTracker, true)
195+
TLBE.Camera.followTracker(self.testPlayer1, nil, self.testCameraPlayer1, baseTracker, true)
195196
local oldZoom = self.testCameraPlayer1.zoom;
196197
local oldCenterPos = self.testCameraPlayer1.centerPos;
197198

198-
TLBE.Camera.setWidth(self.testCameraPlayer1, self.testCameraPlayer1.width * 2)
199-
TLBE.Camera.setHeight(self.testCameraPlayer1, self.testCameraPlayer1.height * 2)
199+
---@diagnostic disable-next-line: param-type-mismatch player(Data) can be nil when minZoom is not reached
200+
TLBE.Camera.setWidth(self.testPlayer1, nil, self.testCameraPlayer1, self.testCameraPlayer1.width * 2)
201+
---@diagnostic disable-next-line: param-type-mismatch player(Data) can be nil when minZoom is not reached
202+
TLBE.Camera.setHeight(self.testPlayer1, nil, self.testCameraPlayer1, self.testCameraPlayer1.height * 2)
200203

201204
lu.assertEquals(self.testCameraPlayer1.centerPos.x, oldCenterPos.x, "expected centerpos to be the same")
202205
lu.assertEquals(self.testCameraPlayer1.centerPos.y, oldCenterPos.y, "expected centerpos to be the same")

tests/camera_follow-tracker.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,33 @@ function TestCameraFollowTracker:TestZoom()
9797
lu.assertEquals(self.testCamera.zoom, 0.5, "expected that zoom halved")
9898
end
9999

100+
function TestCameraFollowTracker:TestMinZoom()
101+
self.testTracker.smooth = false
102+
self.testTracker.size = { -- Large enough to hit the minZoom
103+
x = self.testCamera.width / tileSize * 2000,
104+
y = self.testCamera.height / tileSize * 2000
105+
}
106+
107+
local ticks = ConvergenceTester({}, { print = function() end }, self.testCamera, self.testTracker)
108+
109+
lu.assertEquals(ticks, 1, "expected to converge immediately")
110+
111+
lu.assertEquals(self.testCamera.zoom, 0.03125, "expected that zoom is at minZoom")
112+
end
113+
114+
function TestCameraFollowTracker:TestMinZoomSmooth()
115+
self.testTracker.size = { -- Large enough to hit the minZoom
116+
x = self.testCamera.width / tileSize * 2000,
117+
y = self.testCamera.height / tileSize * 2000
118+
}
119+
120+
local ticks = ConvergenceTester({}, { print = function() end }, self.testCamera, self.testTracker)
121+
122+
lu.assertEquals(ticks, self.testCamera.transitionTicks, "couldn't converge in expected 14 ticks")
123+
124+
lu.assertEquals(self.testCamera.zoom, 0.03125, "expected that zoom is at minZoom")
125+
end
126+
100127
function TestCameraFollowTracker:TestConvergenceDiagonal()
101128
self.testTracker.centerPos = { x = 10, y = 6 }
102129

0 commit comments

Comments
 (0)