Skip to content

Commit 5afb64e

Browse files
committed
Fix for camera limits
This commit makes 2D camera limits have a well defined behavior for cases when the limits are smaller than the screen rect. Presently the RIGHT and TOP limit take prescidence simply because they are applied second. This change adjusts behavior to split the difference in cases where both the LEFT/RIGHT or TOP/BOTTOM limits would both apply.
1 parent be3ecae commit 5afb64e

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

scene/2d/camera_2d.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,28 @@ Transform2D Camera2D::get_camera_transform() {
219219
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);
220220

221221
if (limit_enabled && limit_smoothing_enabled) {
222-
if (screen_rect.position.x < limit[SIDE_LEFT]) {
222+
// Apply horizontal limiting.
223+
if (screen_rect.size.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) {
224+
// Split the limit difference horizontally.
225+
camera_pos.x -= screen_rect.position.x + (screen_rect.size.x - limit[SIDE_RIGHT] - limit[SIDE_LEFT]) / 2;
226+
} else if (screen_rect.position.x < limit[SIDE_LEFT]) {
227+
// Only apply left limit.
223228
camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT];
224-
}
225-
226-
if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) {
229+
} else if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) {
230+
// Only apply the right limit.
227231
camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[SIDE_RIGHT];
228232
}
229233

230-
if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) {
231-
camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM];
232-
}
233-
234-
if (screen_rect.position.y < limit[SIDE_TOP]) {
234+
// Apply vertical limiting.
235+
if (screen_rect.size.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) {
236+
// Split the limit difference vertically.
237+
camera_pos.y -= screen_rect.position.y + (screen_rect.size.y - limit[SIDE_BOTTOM] - limit[SIDE_TOP]) / 2;
238+
} else if (screen_rect.position.y < limit[SIDE_TOP]) {
239+
// Only apply the top limit.
235240
camera_pos.y -= screen_rect.position.y - limit[SIDE_TOP];
241+
} else if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) {
242+
// Only apply the bottom limit.
243+
camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM];
236244
}
237245
}
238246

@@ -273,20 +281,28 @@ Transform2D Camera2D::get_camera_transform() {
273281

274282
if (limit_enabled && (!position_smoothing_enabled || !limit_smoothing_enabled)) {
275283
Point2 bottom_right_corner = Point2(screen_rect.position + 2.0 * (camera_pos - screen_rect.position));
276-
if (screen_rect.position.x < limit[SIDE_LEFT]) {
284+
// Apply horizontal limiting.
285+
if (bottom_right_corner.x - screen_rect.position.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) {
286+
// Split the difference horizontally (center it).
287+
screen_rect.position.x = (limit[SIDE_LEFT] + limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x)) / 2;
288+
} else if (screen_rect.position.x < limit[SIDE_LEFT]) {
289+
// Only apply left limit.
277290
screen_rect.position.x = limit[SIDE_LEFT];
278-
}
279-
280-
if (bottom_right_corner.x > limit[SIDE_RIGHT]) {
291+
} else if (bottom_right_corner.x > limit[SIDE_RIGHT]) {
292+
// Only apply right limit.
281293
screen_rect.position.x = limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x);
282294
}
283295

284-
if (bottom_right_corner.y > limit[SIDE_BOTTOM]) {
285-
screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y);
286-
}
287-
288-
if (screen_rect.position.y < limit[SIDE_TOP]) {
296+
// Apply vertical limiting.
297+
if (bottom_right_corner.y - screen_rect.position.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) {
298+
// Split the limit difference vertically.
299+
screen_rect.position.y = (limit[SIDE_TOP] + limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y)) / 2;
300+
} else if (screen_rect.position.y < limit[SIDE_TOP]) {
301+
// Only apply the top limit.
289302
screen_rect.position.y = limit[SIDE_TOP];
303+
} else if (bottom_right_corner.y > limit[SIDE_BOTTOM]) {
304+
// Only apply the bottom limit.
305+
screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y);
290306
}
291307
}
292308

0 commit comments

Comments
 (0)