diff --git a/components/FreeCameraComponent.tscn b/components/FreeCameraComponent.tscn new file mode 100644 index 0000000..e834611 --- /dev/null +++ b/components/FreeCameraComponent.tscn @@ -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 diff --git a/components/scripts/free_camera_component.gd b/components/scripts/free_camera_component.gd new file mode 100644 index 0000000..f8b1a24 --- /dev/null +++ b/components/scripts/free_camera_component.gd @@ -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 diff --git a/entities/glowing.tscn b/entities/glowing.tscn index ccd06b2..1c6cd02 100644 --- a/entities/glowing.tscn +++ b/entities/glowing.tscn @@ -63,5 +63,3 @@ energy = 0.7 shadow_filter = 2 shadow_filter_smooth = 7.5 texture = ExtResource("2_s3xbi") - -[node name="Camera2D" type="Camera2D" parent="."] diff --git a/levels/test_level.tscn b/levels/test_level.tscn index 94ab73d..a710a5d 100644 --- a/levels/test_level.tscn +++ b/levels/test_level.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=114 format=3 uid="uid://cbiwnafhckchl"] +[gd_scene load_steps=115 format=3 uid="uid://cbiwnafhckchl"] [ext_resource type="Texture2D" uid="uid://cwkjk7hh7csea" path="res://resources/sCaveTile.png" id="1_au2ii"] [ext_resource type="Material" uid="uid://bpverily2kmvm" path="res://levels/resources/material_desaturate_tileset.tres" id="1_iph1s"] @@ -14,6 +14,7 @@ [ext_resource type="PackedScene" uid="uid://qgxsbmcv0nqh" path="res://components/CrystalGlowComponent.tscn" id="10_8n1hc"] [ext_resource type="PackedScene" uid="uid://c87qvtq8ho3bb" path="res://components/MushroomGlowComponent.tscn" id="13_uwl47"] [ext_resource type="PackedScene" uid="uid://mawos5ss1cod" path="res://components/WaterEffectComponent.tscn" id="14_x3ue3"] +[ext_resource type="PackedScene" uid="uid://rnfx7djn5qik" path="res://components/FreeCameraComponent.tscn" id="15_xajk3"] [sub_resource type="Environment" id="Environment_ct14l"] background_mode = 3 @@ -4033,3 +4034,5 @@ position = Vector2(2167, 319) [node name="CanvasModulate" type="CanvasModulate" parent="."] color = Color(0.301961, 0.45098, 1, 1) + +[node name="FreeCameraComponent" parent="." instance=ExtResource("15_xajk3")]