A new component, FreeCameraComponent, has been added to the project. This component allows for more flexible camera control including key movement, edge scrolling, mouse dragging and zooming. The camera's speed, margin and zoom limits can be adjusted as needed. The old Camera2D node in the glowing.tscn file has been removed and replaced with this new component in test_level.tscn.
106 lines
3.5 KiB
GDScript
106 lines
3.5 KiB
GDScript
extends Camera2D
|
|
|
|
@export var key : bool = true
|
|
@export var drag : bool = true
|
|
@export var edge : bool = false
|
|
@export var wheel : bool = true
|
|
|
|
@export var zoom_in_limit : float = 2.5 # The max vector2 zoom value
|
|
|
|
@export var camera_speed : int = 450 # Camera speed in px/s
|
|
@export var camera_margin : int = 50 # Pixels around edge of screen where the mouse will start moving the camera
|
|
|
|
# Initial zoom value taken from Editor.
|
|
var camera_zoom : Vector2 = zoom
|
|
|
|
const camera_zoom_speed = Vector2(0.5, 0.5)
|
|
var camera_movement : Vector2 = Vector2.ZERO
|
|
var _prev_mouse_pos : Vector2 = Vector2.ZERO
|
|
|
|
# INPUTS
|
|
|
|
# Right mouse button was or is pressed.
|
|
var __rmbk : bool = false
|
|
# Move camera by keys: left, top, right, bottom.
|
|
var __keys : Array[bool] = [false, false, false, false]
|
|
|
|
func _ready() -> void:
|
|
set_drag_horizontal_enabled(false)
|
|
set_drag_vertical_enabled(false)
|
|
set_position_smoothing_enabled(true)
|
|
set_position_smoothing_speed(4)
|
|
|
|
func _physics_process(delta : float) -> void:
|
|
|
|
# Move camera by keys defined in InputMap (ui_left/top/right/bottom).
|
|
if key:
|
|
if __keys[0]:
|
|
camera_movement.x -= camera_speed * delta
|
|
if __keys[1]:
|
|
camera_movement.y -= camera_speed * delta
|
|
if __keys[2]:
|
|
camera_movement.x += camera_speed * delta
|
|
if __keys[3]:
|
|
camera_movement.y += camera_speed * delta
|
|
|
|
# Move camera by mouse, when it's on the margin (defined by camera_margin).
|
|
if edge:
|
|
var rec : Rect2 = get_viewport().get_visible_rect()
|
|
var v : Vector2 = get_local_mouse_position() + rec.size/2
|
|
if rec.size.x - v.x <= camera_margin:
|
|
camera_movement.x += camera_speed * delta
|
|
if v.x <= camera_margin:
|
|
camera_movement.x -= camera_speed * delta
|
|
if rec.size.y - v.y <= camera_margin:
|
|
camera_movement.y += camera_speed * delta
|
|
if v.y <= camera_margin:
|
|
camera_movement.y -= camera_speed * delta
|
|
|
|
# When RMB is pressed, move camera by difference of mouse position
|
|
if drag and __rmbk:
|
|
camera_movement = _prev_mouse_pos - get_local_mouse_position()
|
|
|
|
# Update position of the camera.
|
|
position += camera_movement * get_zoom()
|
|
|
|
# Set camera movement to zero, update old mouse position.
|
|
camera_movement = Vector2(0,0)
|
|
_prev_mouse_pos = get_local_mouse_position()
|
|
|
|
func _unhandled_input( event : InputEvent) ->void:
|
|
if event is InputEventMouseButton:
|
|
var mouse_event : InputEventMouseButton = event as InputEventMouseButton
|
|
if drag and\
|
|
mouse_event.button_index == MOUSE_BUTTON_RIGHT:
|
|
# Control by right mouse button.
|
|
if mouse_event.pressed: __rmbk = true
|
|
else: __rmbk = false
|
|
# Check if mouse wheel was used. Not handled by InputMap!
|
|
if wheel:
|
|
if mouse_event.button_index == MOUSE_BUTTON_WHEEL_DOWN and\
|
|
camera_zoom.x - camera_zoom_speed.x > 0 and\
|
|
camera_zoom.y - camera_zoom_speed.y > 0:
|
|
camera_zoom -= camera_zoom_speed
|
|
set_zoom(camera_zoom)
|
|
if mouse_event.button_index == MOUSE_BUTTON_WHEEL_UP and\
|
|
camera_zoom.x + camera_zoom_speed.x < zoom_in_limit and\
|
|
camera_zoom.y + camera_zoom_speed.y < zoom_in_limit:
|
|
camera_zoom += camera_zoom_speed
|
|
set_zoom(camera_zoom)
|
|
# Control by keyboard handled by InpuMap.
|
|
if event.is_action_pressed("ui_left"):
|
|
__keys[0] = true
|
|
if event.is_action_pressed("ui_up"):
|
|
__keys[1] = true
|
|
if event.is_action_pressed("ui_right"):
|
|
__keys[2] = true
|
|
if event.is_action_pressed("ui_down"):
|
|
__keys[3] = true
|
|
if event.is_action_released("ui_left"):
|
|
__keys[0] = false
|
|
if event.is_action_released("ui_up"):
|
|
__keys[1] = false
|
|
if event.is_action_released("ui_right"):
|
|
__keys[2] = false
|
|
if event.is_action_released("ui_down"):
|
|
__keys[3] = false
|