Introduced FreeCameraComponent

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.
This commit is contained in:
Dan 2024-06-06 09:39:03 +01:00
parent 1d04d27969
commit cec9227b67
4 changed files with 121 additions and 3 deletions

View file

@ -0,0 +1,11 @@
[gd_scene load_steps=2 format=3 uid="uid://rnfx7djn5qik"]
[ext_resource type="Script" path="res://components/scripts/free_camera_component.gd" id="1_isqof"]
[node name="FreeCameraComponent" type="Node2D"]
[node name="GameCamera" type="Camera2D" parent="."]
script = ExtResource("1_isqof")
zoom_out_limit = 10
camera_speed = 400
camera_margin = 10

View file

@ -0,0 +1,106 @@
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