|
|
|
|
Reply From: |
Aaron |
I came up with a camera script that limits the camera to the current level’s size, including handling of the camera’s zoom.
If the viewport is smaller than the level either horizontally or vertically, the viewport is kept inside the level. If the viewport is bigger than the level, the level is centred.
extends Camera2D
export(Vector2) var world_size setget _world_size_changed
func _world_size_changed(size):
world_size = size
_sync_bounds()
func _ready():
_sync_bounds()
get_viewport().connect("size_changed", self, "_sync_bounds")
func _sync_bounds():
var viewport = get_viewport()
if viewport != null:
var zoom = get_zoom()
var scale = Vector2(1 / zoom.x, 1 / zoom.y)
var resolution = viewport.get_rect().size
if (world_size.x * scale.x) > resolution.width:
_set_big_margins(world_size.x, resolution.width, scale.x, MARGIN_LEFT, MARGIN_RIGHT)
else:
_set_small_margins(world_size.x, resolution.width, scale.x, MARGIN_LEFT, MARGIN_RIGHT)
if (world_size.y * scale.y) > resolution.height:
_set_big_margins(world_size.y, resolution.height, scale.y, MARGIN_TOP, MARGIN_BOTTOM)
else:
_set_small_margins(world_size.y, resolution.height, scale.y, MARGIN_TOP, MARGIN_BOTTOM)
func _set_big_margins(world_size, screen_size, scale, margin_neg, margin_pos):
set_limit(margin_neg, 0)
var diff = (world_size * scale) - screen_size
diff /= scale
set_limit(margin_pos, ceil(screen_size + diff))
func _set_small_margins(world_size, screen_size, scale, margin_neg, margin_pos):
var margin = (screen_size - (world_size * scale)) / 2
set_limit(margin_neg, floor(-margin / scale))
set_limit(margin_pos, ceil((margin / scale) - world_size))
TileMap itself doesn’t have a way to get the bounds though, so you’ll have to calculate that yourself.