소스 검색

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.

David Nikdel 4 달 전
부모
커밋
5afb64e167
1개의 변경된 파일34개의 추가작업 그리고 18개의 파일을 삭제
  1. 34 18
      scene/2d/camera_2d.cpp

+ 34 - 18
scene/2d/camera_2d.cpp

@@ -219,20 +219,28 @@ Transform2D Camera2D::get_camera_transform() {
 		Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);
 
 		if (limit_enabled && limit_smoothing_enabled) {
-			if (screen_rect.position.x < limit[SIDE_LEFT]) {
+			// Apply horizontal limiting.
+			if (screen_rect.size.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) {
+				// Split the limit difference horizontally.
+				camera_pos.x -= screen_rect.position.x + (screen_rect.size.x - limit[SIDE_RIGHT] - limit[SIDE_LEFT]) / 2;
+			} else if (screen_rect.position.x < limit[SIDE_LEFT]) {
+				// Only apply left limit.
 				camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT];
-			}
-
-			if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) {
+			} else if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) {
+				// Only apply the right limit.
 				camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[SIDE_RIGHT];
 			}
 
-			if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) {
-				camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM];
-			}
-
-			if (screen_rect.position.y < limit[SIDE_TOP]) {
+			// Apply vertical limiting.
+			if (screen_rect.size.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) {
+				// Split the limit difference vertically.
+				camera_pos.y -= screen_rect.position.y + (screen_rect.size.y - limit[SIDE_BOTTOM] - limit[SIDE_TOP]) / 2;
+			} else if (screen_rect.position.y < limit[SIDE_TOP]) {
+				// Only apply the top limit.
 				camera_pos.y -= screen_rect.position.y - limit[SIDE_TOP];
+			} else if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) {
+				// Only apply the bottom limit.
+				camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM];
 			}
 		}
 
@@ -273,20 +281,28 @@ Transform2D Camera2D::get_camera_transform() {
 
 	if (limit_enabled && (!position_smoothing_enabled || !limit_smoothing_enabled)) {
 		Point2 bottom_right_corner = Point2(screen_rect.position + 2.0 * (camera_pos - screen_rect.position));
-		if (screen_rect.position.x < limit[SIDE_LEFT]) {
+		// Apply horizontal limiting.
+		if (bottom_right_corner.x - screen_rect.position.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) {
+			// Split the difference horizontally (center it).
+			screen_rect.position.x = (limit[SIDE_LEFT] + limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x)) / 2;
+		} else if (screen_rect.position.x < limit[SIDE_LEFT]) {
+			// Only apply left limit.
 			screen_rect.position.x = limit[SIDE_LEFT];
-		}
-
-		if (bottom_right_corner.x > limit[SIDE_RIGHT]) {
+		} else if (bottom_right_corner.x > limit[SIDE_RIGHT]) {
+			// Only apply right limit.
 			screen_rect.position.x = limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x);
 		}
 
-		if (bottom_right_corner.y > limit[SIDE_BOTTOM]) {
-			screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y);
-		}
-
-		if (screen_rect.position.y < limit[SIDE_TOP]) {
+		// Apply vertical limiting.
+		if (bottom_right_corner.y - screen_rect.position.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) {
+			// Split the limit difference vertically.
+			screen_rect.position.y = (limit[SIDE_TOP] + limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y)) / 2;
+		} else if (screen_rect.position.y < limit[SIDE_TOP]) {
+			// Only apply the top limit.
 			screen_rect.position.y = limit[SIDE_TOP];
+		} else if (bottom_right_corner.y > limit[SIDE_BOTTOM]) {
+			// Only apply the bottom limit.
+			screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y);
 		}
 	}