[gd_scene load_steps=8 format=3 uid="uid://524sv8spw6go"] [ext_resource type="Texture2D" uid="uid://q1rdbr8uh78r" path="res://textures/cursor_default.tres" id="1_50ts1"] [ext_resource type="Texture2D" uid="uid://bdstohvc7pvot" path="res://textures/cursor_click.tres" id="1_h0do2"] [ext_resource type="Texture2D" uid="uid://buxws7r3kn0d7" path="res://textures/cursor_grab_01.tres" id="3_fj3w4"] [ext_resource type="Texture2D" uid="uid://pbahcjllgjjq" path="res://textures/cursor_grab_02.tres" id="4_153q8"] [ext_resource type="Texture2D" uid="uid://6fajq480n7se" path="res://textures/cursor_grab_03.tres" id="5_tsejy"] [sub_resource type="GDScript" id="GDScript_h2l04"] script/source = "extends Node2D const Speed:float = 900 var spaceState var query : PhysicsPointQueryParameters2D var CastResult var hoveredObjects : Array var hoveredObject var hoveredSticker var grabbedSticker enum CURSOR_STATE {DEFAULT, CLICK, GRAB, GRABBED} var currentCursorState:CURSOR_STATE var oldCursorState:CURSOR_STATE # Called when the node enters the scene tree for the first time. func _ready(): if not OS.is_debug_build(): Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED_HIDDEN) query = PhysicsPointQueryParameters2D.new() spaceState = get_world_2d() # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): #region Mouse Position position = get_global_mouse_position() #endregion pointcast() cursor_look() func isSticker(selectedObject:Node): var _isSticker:bool = false var _tags = getTags(selectedObject) if (_tags.size() > 0): if (_tags.find(\"sticker\") != -1): _isSticker = true return _isSticker func getTags(selectedObject:Node): var _tags: Array if (selectedObject.has_meta(\"tags\")): _tags = selectedObject.get_meta(\"tags\") return _tags else: printerr(\"no tags inside %\",selectedObject) return _tags func pointcast(): query.collide_with_areas = true query.position = get_global_mouse_position() CastResult = spaceState.direct_space_state.intersect_point(query) # CastResult is not reliable. Objects are added randomly in the array # so we need to filter/sort the trace result if ( CastResult.size() > 0): hoveredObjects.clear() for _object in CastResult: if(_object.collider.input_pickable == true): hoveredObjects.append(_object.collider.get_parent()) if (hoveredObjects.size() > 0): if (hoveredObjects.size() >= 2): sortByPosY(hoveredObjects,false) hoveredObject = hoveredObjects[0] print(\"Current hovered object :\", hoveredObject) if (CastResult.size() == 0 and !grabbedSticker ): CastResult.clear() hoveredSticker = null hoveredObjects.clear() hoveredObject = null func sortByPosY(objects: Array, ascending_order: bool = true): var _tempArray :Array _tempArray = objects # Inline comparison function _tempArray.sort_custom(comparePosY) # Reverse if descending order is required if not ascending_order: _tempArray.reverse() objects = _tempArray func comparePosY(a, b): #print(\"Compare \",a,\" at \",a.position.y, \" and \",b,\" at \",b.position.y ) return a.position.y < b.position.y func cursor_look(): if (Input.is_action_pressed(\"select\")): if (hoveredSticker): currentCursorState = CURSOR_STATE.GRABBED if ($GrabTimer.is_stopped()): $GrabTimer.start() else: currentCursorState = CURSOR_STATE.CLICK else: if (hoveredSticker): currentCursorState = CURSOR_STATE.GRAB else: currentCursorState = CURSOR_STATE.DEFAULT $GrabTimer.stop() if (currentCursorState != oldCursorState): oldCursorState = currentCursorState match oldCursorState: CURSOR_STATE.DEFAULT: $AnimatedSprite2D.play(\"default\") CURSOR_STATE.CLICK: $AnimatedSprite2D.play(\"click\") CURSOR_STATE.GRAB: $AnimatedSprite2D.play(\"grab_intro\") CURSOR_STATE.GRABBED: $AnimatedSprite2D.play(\"grab\") func _on_grab_timer_timeout(): if (hoveredSticker): grabbedSticker = hoveredSticker " [sub_resource type="SpriteFrames" id="SpriteFrames_u3xkr"] resource_local_to_scene = true animations = [{ "frames": [{ "duration": 1.0, "texture": ExtResource("1_h0do2") }], "loop": true, "name": &"click", "speed": 5.0 }, { "frames": [{ "duration": 1.0, "texture": ExtResource("1_50ts1") }], "loop": true, "name": &"default", "speed": 5.0 }, { "frames": [{ "duration": 1.0, "texture": ExtResource("3_fj3w4") }, { "duration": 1.0, "texture": ExtResource("4_153q8") }, { "duration": 1.0, "texture": ExtResource("5_tsejy") }], "loop": false, "name": &"grab", "speed": 7.0 }, { "frames": [{ "duration": 1.0, "texture": ExtResource("3_fj3w4") }], "loop": true, "name": &"grab_intro", "speed": 5.0 }] [node name="Cursor" type="Node2D"] top_level = true script = SubResource("GDScript_h2l04") [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] scale = Vector2(1.5, 1.5) sprite_frames = SubResource("SpriteFrames_u3xkr") animation = &"grab" autoplay = "grab" frame = 2 frame_progress = 1.0 centered = false offset = Vector2(-80, -190) [node name="GrabTimer" type="Timer" parent="."] wait_time = 0.5 [connection signal="timeout" from="GrabTimer" to="." method="_on_grab_timer_timeout"]