From 7654833a6e1e1b3f3c5122032db738f30fde872d Mon Sep 17 00:00:00 2001 From: Techwizz Date: Mon, 20 Mar 2023 21:33:15 -0600 Subject: [PATCH] Testing touchscreen support --- joystick/textures/joystick_base_outline.png | Bin 0 -> 4827 bytes .../textures/joystick_base_outline.png.import | 34 ++++ joystick/textures/joystick_tip.png | Bin 0 -> 1780 bytes joystick/textures/joystick_tip.png.import | 34 ++++ joystick/textures/joystick_tip_arrows.png | Bin 0 -> 2229 bytes .../textures/joystick_tip_arrows.png.import | 34 ++++ joystick/virtual_joystick.gd | 178 ++++++++++++++++++ joystick/virtual_joystick.tscn | 68 +++++++ scenes/tutorial.tscn | 5 +- 9 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 joystick/textures/joystick_base_outline.png create mode 100644 joystick/textures/joystick_base_outline.png.import create mode 100644 joystick/textures/joystick_tip.png create mode 100644 joystick/textures/joystick_tip.png.import create mode 100644 joystick/textures/joystick_tip_arrows.png create mode 100644 joystick/textures/joystick_tip_arrows.png.import create mode 100644 joystick/virtual_joystick.gd create mode 100644 joystick/virtual_joystick.tscn diff --git a/joystick/textures/joystick_base_outline.png b/joystick/textures/joystick_base_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..7cae462a42a4cea25b231f28587b41b03775128c GIT binary patch literal 4827 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 BPWAu* literal 0 HcmV?d00001 diff --git a/joystick/textures/joystick_base_outline.png.import b/joystick/textures/joystick_base_outline.png.import new file mode 100644 index 0000000..1bf2644 --- /dev/null +++ b/joystick/textures/joystick_base_outline.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c13dhmpklvcb4" +path="res://.godot/imported/joystick_base_outline.png-483e8f1ac02a5b9a594f81d7e341a76f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://joystick/textures/joystick_base_outline.png" +dest_files=["res://.godot/imported/joystick_base_outline.png-483e8f1ac02a5b9a594f81d7e341a76f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/joystick/textures/joystick_tip.png b/joystick/textures/joystick_tip.png new file mode 100644 index 0000000000000000000000000000000000000000..28c57acd8e3b022312f6d3f4a4d6bb6d81e048b3 GIT binary patch literal 1780 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 DtkNO? literal 0 HcmV?d00001 diff --git a/joystick/textures/joystick_tip_arrows.png.import b/joystick/textures/joystick_tip_arrows.png.import new file mode 100644 index 0000000..d99b4f8 --- /dev/null +++ b/joystick/textures/joystick_tip_arrows.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bprmb464pp766" +path="res://.godot/imported/joystick_tip_arrows.png-c9482441a78cf839baf32238aae88b91.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://joystick/textures/joystick_tip_arrows.png" +dest_files=["res://.godot/imported/joystick_tip_arrows.png-c9482441a78cf839baf32238aae88b91.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/joystick/virtual_joystick.gd b/joystick/virtual_joystick.gd new file mode 100644 index 0000000..ac67ede --- /dev/null +++ b/joystick/virtual_joystick.gd @@ -0,0 +1,178 @@ +class_name VirtualJoystick + +extends Control + +# https://github.com/MarcoFazioRandom/Virtual-Joystick-Godot + +#### EXPORTED VARIABLE #### + +## The color modulation of the button when the joystick is in use. See [member CanvasItem.modulate]. +@export var pressed_color: Color = Color.GRAY + +## If the input is inside this range, the output is zero. +@export_range(0, 200, 1) var deadzone_size : float = 10 + +## The max distance the tip can reach. +@export_range(0, 500, 1) var clampzone_size : float = 75 + +enum JoystickMode { + FIXED, ## The joystick doesn't move. Default. + DYNAMIC ## Every time the joystick area is pressed, the joystick position is set on the touched position. +} + +## Whether the joystick should move on pressed. +@export var joystick_mode: JoystickMode = JoystickMode.FIXED + +enum VisibilityMode { + ALWAYS, ## Always visible. Default. + TOUCHSCREEN_ONLY ## Visible on touch screens only. +} + +## Whether or not the joystick is visible if there is no touchscreen +@export var visibility_mode: VisibilityMode = VisibilityMode.ALWAYS + +## If [code]true[/code], the value returned from [method Input.get_axis] using +## [member action_left], [member action_right], [member action_up], and [member action_down] +## are overridden with [member output] for each axis such that +## [code]Input.get_axis(action_left, action_right)[/code] should always equal [member output.x] and +## [code]Input.get_axis(action_up, action_down)[/code] should always equal [member output.y][br] +## See [b]Project → Project Settings → Input Map[/b][br] +## If you want to change the hotkeys for the default actions make sure [b]Show Built-in Action[/b] is checked. +@export var use_input_actions := true + +## Input action for left direction +@export var action_left := "ui_left" +## Input action for right direction +@export var action_right := "ui_right" +## Input action for up direction +@export var action_up := "ui_up" +## Input action for down direction +@export var action_down := "ui_down" + +#### PUBLIC VARIABLES #### + +## If [code]true[/code], the joystick's state is pressed. Means the joystick will receive inputs. +var pressed := false : get = is_pressed + +func is_pressed() -> bool: + return pressed + +## Current position of the joystick. The value's length ranges from [code]0[/code] to [code]1.0[/code]. +var output := Vector2.ZERO : get = get_output + +func get_output() -> Vector2: + return output + +#### PRIVATE VARIABLES #### + +var _touch_index : int = -1 + +@onready var _base := $Base +@onready var _tip := $Base/Tip + +@onready var _base_radius = _base.size * _base.get_global_transform_with_canvas().get_scale() / 2 + +@onready var _base_default_position : Vector2 = _base.position +@onready var _tip_default_position : Vector2 = _tip.position + +@onready var _default_color : Color = _tip.modulate + +#### FUNCTIONS #### + +func _ready() -> void: + if not DisplayServer.is_touchscreen_available() and visibility_mode == VisibilityMode.TOUCHSCREEN_ONLY: + hide() + +func _input(event: InputEvent) -> void: + if event is InputEventScreenTouch: + if event.pressed: + if _is_point_inside_joystick_area(event.position) and _touch_index == -1: + if joystick_mode == JoystickMode.DYNAMIC or (joystick_mode == JoystickMode.FIXED and _is_point_inside_base(event.position)): + if joystick_mode == JoystickMode.DYNAMIC: + _move_base(event.position) + _touch_index = event.index + _tip.modulate = pressed_color + _update_joystick(event.position) + get_viewport().set_input_as_handled() + elif event.index == _touch_index: + _reset() + get_viewport().set_input_as_handled() + elif event is InputEventScreenDrag: + if event.index == _touch_index: + _update_joystick(event.position) + get_viewport().set_input_as_handled() + +func _move_base(new_position: Vector2) -> void: + _base.global_position = new_position - _base.pivot_offset * get_global_transform_with_canvas().get_scale() + +func _move_tip(new_position: Vector2) -> void: + _tip.global_position = new_position - _tip.pivot_offset * _base.get_global_transform_with_canvas().get_scale() + +func _is_point_inside_joystick_area(point: Vector2) -> bool: + var x: bool = point.x >= global_position.x and point.x <= global_position.x + (size.x * get_global_transform_with_canvas().get_scale().x) + var y: bool = point.y >= global_position.y and point.y <= global_position.y + (size.y * get_global_transform_with_canvas().get_scale().y) + return x and y + +func _is_point_inside_base(point: Vector2) -> bool: + var center : Vector2 = _base.global_position + _base_radius + var vector : Vector2 = point - center + if vector.length_squared() <= _base_radius.x * _base_radius.x: + return true + else: + return false + +func _update_joystick(touch_position: Vector2) -> void: + var center : Vector2 = _base.global_position + _base_radius + var vector : Vector2 = touch_position - center + vector = vector.limit_length(clampzone_size) + + _move_tip(center + vector) + + if vector.length_squared() > deadzone_size * deadzone_size: + pressed = true + output = (vector - (vector.normalized() * deadzone_size)) / (clampzone_size - deadzone_size) + else: + pressed = false + output = Vector2.ZERO + + if use_input_actions: + _update_input_actions() + +func _update_input_actions(): + if output.x < 0: + Input.action_press(action_left, -output.x) + elif Input.is_action_pressed(action_left): + Input.action_release(action_left) + if output.x > 0: + Input.action_press(action_right, output.x) + elif Input.is_action_pressed(action_right): + Input.action_release(action_right) + if output.y < 0: + Input.action_press(action_up, -output.y) + elif Input.is_action_pressed(action_up): + Input.action_release(action_up) + if output.y > 0: + Input.action_press(action_down, output.y) + elif Input.is_action_pressed(action_down): + Input.action_release(action_down) + +func _reset(): + pressed = false + output = Vector2.ZERO + _touch_index = -1 + _tip.modulate = _default_color + _base.position = _base_default_position + _tip.position = _tip_default_position + if use_input_actions: + if Input.is_action_pressed(action_left): + Input.action_release(action_left) + if Input.is_action_pressed(action_right): + Input.action_release(action_right) + if Input.is_action_pressed(action_down): + Input.action_release(action_down) + if Input.is_action_pressed(action_up): + Input.action_release(action_up) + + +func _on_button_pressed(): + Input.action_press("jump") diff --git a/joystick/virtual_joystick.tscn b/joystick/virtual_joystick.tscn new file mode 100644 index 0000000..6c9cb68 --- /dev/null +++ b/joystick/virtual_joystick.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=4 format=3 uid="uid://buyvavyuwmccw"] + +[ext_resource type="Texture2D" uid="uid://c13dhmpklvcb4" path="res://joystick/textures/joystick_base_outline.png" id="1"] +[ext_resource type="Texture2D" uid="uid://bprmb464pp766" path="res://joystick/textures/joystick_tip_arrows.png" id="2"] +[ext_resource type="Script" path="res://joystick/virtual_joystick.gd" id="3"] + +[node name="Virtual joystick" type="Control"] +modulate = Color(1, 1, 1, 0.509804) +layout_mode = 3 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 50.0 +offset_top = -250.0 +offset_right = 250.0 +offset_bottom = -50.0 +grow_vertical = 0 +script = ExtResource("3") +action_left = "player_left" +action_right = "player_right" +action_up = "player_forward" +action_down = "player_backward" + +[node name="Base" type="TextureRect" parent="."] +layout_mode = 0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -100.0 +offset_top = -100.0 +offset_right = 100.0 +offset_bottom = 100.0 +grow_horizontal = 2 +grow_vertical = 2 +pivot_offset = Vector2(100, 100) +size_flags_horizontal = 4 +size_flags_vertical = 4 +texture = ExtResource("1") +stretch_mode = 6 + +[node name="Tip" type="TextureRect" parent="Base"] +layout_mode = 0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -50.0 +offset_top = -50.0 +offset_right = 50.0 +offset_bottom = 50.0 +grow_horizontal = 2 +grow_vertical = 2 +pivot_offset = Vector2(50, 50) +size_flags_horizontal = 4 +size_flags_vertical = 4 +texture = ExtResource("2") +stretch_mode = 6 + +[node name="Button" type="Button" parent="."] +layout_mode = 0 +offset_left = 794.0 +offset_top = 17.0 +offset_right = 1068.0 +offset_bottom = 222.0 +text = "JUMP" + +[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] diff --git a/scenes/tutorial.tscn b/scenes/tutorial.tscn index 49eee1d..f68813c 100644 --- a/scenes/tutorial.tscn +++ b/scenes/tutorial.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=9 format=3 uid="uid://dkokyp5lwhks4"] +[gd_scene load_steps=10 format=3 uid="uid://dkokyp5lwhks4"] [ext_resource type="Script" path="res://scripts/maps/tutorial.gd" id="1_40ws8"] [ext_resource type="PackedScene" uid="uid://dp1q51kvd8uow" path="res://scenes/Teddy.tscn" id="1_081si"] [ext_resource type="PackedScene" uid="uid://ytbacsuahxie" path="res://scenes/HUD.tscn" id="2_s3v8n"] [ext_resource type="PackedScene" uid="uid://y3fffh5cdbks" path="res://scenes/AI.tscn" id="4_fttoe"] [ext_resource type="PackedScene" uid="uid://c1y6p4m0sktfj" path="res://scenes/farmland-map.tscn" id="5_imhi6"] +[ext_resource type="PackedScene" uid="uid://buyvavyuwmccw" path="res://joystick/virtual_joystick.tscn" id="6_p8th3"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_i5hsu"] sky_top_color = Color(1, 1, 1, 1) @@ -39,3 +40,5 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.17483, 1.039, 2.08165e-12) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.21775, 1.22338, -28.4151) [node name="Farmland" parent="." instance=ExtResource("5_imhi6")] + +[node name="Virtual joystick" parent="." instance=ExtResource("6_p8th3")]