citylimits-next/scripts/CameraZoom2D.gd
2023-02-15 14:01:22 +02:00

135 lines
3.8 KiB
GDScript

# Class handles the camera zoom and movement in the game
class_name CameraZoom2D
extends Camera2D
var is_panning_camera = false
var tween
var _timer:Timer
var camera_bounds:Array = [Vector2(0,0), Vector2(256*16, 256*16)]
var chunk_in_px:Vector2i = Vector2i(Globals.CHUNK_SIZE.x*Globals.TILE_SIZE_X, Globals.CHUNK_SIZE.y*Globals.TILE_SIZE_Y)
var game_res = DisplayServer.window_get_size(0)
var x_min_limit = self.game_res.x/2 - chunk_in_px.x
func _on_main_worldgen_ready() -> void:
# set camera bounds to map size, with chunk_in_px room to go over
self.set_limit(SIDE_LEFT, -chunk_in_px.x)
self.set_limit(SIDE_RIGHT, Globals.map_size*Globals.TILE_SIZE_X + chunk_in_px.x)
self.set_limit(SIDE_TOP, -chunk_in_px.y)
self.set_limit(SIDE_BOTTOM, Globals.map_size*Globals.TILE_SIZE_Y + chunk_in_px.y)
# create timer for repeating camera rotation
if !_timer:
_timer = Timer.new()
_timer.set_wait_time(0.1)
_timer.set_one_shot(false)
add_child(_timer)
var is_camera_rotating: bool = false
func rotate_camera(step:float) -> void:
self.rotation_degrees += step
func _on_set_camera_position(pos: Vector2) -> void:
self.position = pos
func _process(_delta) -> void:
Globals.CAMERA_POSITION = self.position
while Input.is_action_pressed("camera_rotate_left_stepless"):
rotate_camera(-0.1)
await get_tree().create_timer(0.2).timeout
while Input.is_action_pressed("camera_rotate_right_stepless"):
rotate_camera(0.1)
await get_tree().create_timer(0.2).timeout
func _ready() -> void:
pass
func _set_camera_zoom_level(value: float) -> void:
Globals.CAMERA_ZOOM_LEVEL = clamp(value, Globals.CAMERA_MIN_ZOOM_LEVEL, Globals.CAMERA_MAX_ZOOM_LEVEL)
#interpolate frames between zoom levels to make zooming look smoother
tween = get_tree().create_tween()
tween.tween_property(
self,
"zoom",
Vector2(Globals.CAMERA_ZOOM_LEVEL, Globals.CAMERA_ZOOM_LEVEL),
Globals.CAMERA_ZOOM_DURATION
)
func _unhandled_input(event):
if event.is_action_pressed("camera_zoom_in"):
camera_zoom_in()
if event.is_action_pressed("camera_zoom_out"):
camera_zoom_out()
if event.is_action_pressed("camera_rotate_left_fixed_step"):
rotate_camera(-45)
if event.is_action_pressed("camera_rotate_right_fixed_step"):
rotate_camera(45)
if event.is_action_pressed("camera_reset_rotation"):
reset_camera_rotation()
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
if !is_panning_camera and event.pressed:
is_panning_camera = true
if is_panning_camera and !event.pressed:
is_panning_camera = false
if event is InputEventMouseMotion and is_panning_camera:
#var new_x = x + d * cos(theta)
#var new_y = y + d * sin(theta)
#self.position -= event.relative * Globals.CAMERA_PAN_MULTI
# √[(x₂ - x₁)² + (y₂ - y₁)²]
var d = sqrt(pow(event.position.x - 2560/2, 2) + pow(event.position.y - 1440/2, 2))
var new_x = self.position.x + d * cos(self.rotation)
var new_y = self.position.y + d * sin(self.rotation)
#var new_vect = Vector2(new_x, new_y)
#print ("distance: " , d, " ", new_x, " ", new_y)
self.position = Vector2(new_x, new_y)
#self.position -= event.relative * Globals.CAMERA_PAN_MULTI
# prevent camera from going overboard
self.position.x = clamp(
self.position.x,
x_min_limit,
Globals.map_size*Globals.TILE_SIZE_X - chunk_in_px.x
);
self.position.y = clamp(
self.position.y,
0,
Globals.map_size*Globals.TILE_SIZE_Y
);
func camera_zoom_in() -> void:
_set_camera_zoom_level(Globals.CAMERA_ZOOM_LEVEL - Globals.CAMERA_ZOOM_FACTOR)
func camera_zoom_out() -> void:
_set_camera_zoom_level(Globals.CAMERA_ZOOM_LEVEL + Globals.CAMERA_ZOOM_DURATION)
func get_camera_position():
return self.position
func reset_camera_rotation() -> void:
self.rotation_degrees = 0