extends Node2D var spaceState var query : PhysicsPointQueryParameters2D var CastResult : Array var hoveredObjects : Array var hoveredObject var hoveredSticker var grabbedSticker enum CURSOR_STATE {DEFAULT, CLICK, GRAB, GRABBED} var currentCursorState:CURSOR_STATE = CURSOR_STATE.DEFAULT var oldCursorState:CURSOR_STATE = CURSOR_STATE.DEFAULT var cursorPlaying:bool # 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 Cursor 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(): resetCast() 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 and (grabbedSticker == null)): #region Fill HoveredObjects for _object in CastResult: if(_object.collider.input_pickable == true): hoveredObjects.append(_object.collider.get_parent()) #endregion if (hoveredObjects.size() > 0): if (hoveredObjects.size() >= 2): sortByPosY(hoveredObjects,false) if (hoveredObjects[0] != hoveredObject): if (hoveredObject and hoveredObject.has_method("on_unhover")): hoveredObject.on_unhover() hoveredObject = hoveredObjects[0] if (hoveredObject and hoveredObject.has_method("on_hover")): hoveredObject.on_hover() print("Current hovered object :", hoveredObject) if (isSticker(hoveredObject)): hoveredSticker = hoveredObject print("Current hovered sticker :", hoveredSticker) else: hoveredSticker = null else: resetCast(true) else: resetCast(true) func resetCast(bFull = false): CastResult.clear() hoveredObjects.clear() if bFull: if (hoveredObject and hoveredObject.has_method("on_unhover")): hoveredObject.on_unhover() hoveredObject = null hoveredSticker = 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 _input(rawInputEvent:InputEvent): if (rawInputEvent.is_action_pressed("select")): cursorClick() $GrabTimer.start() if (rawInputEvent.is_action_released("select")): $GrabTimer.stop() if (grabbedSticker): grab_end() func grab_start(): if (hoveredSticker): grabbedSticker = hoveredSticker print("Grabbed ", grabbedSticker) func grab_end(): grabbedSticker.on_released() print("stopg grabbin at ",query.position ) DebugDraw.points.append(query.position) DebugDraw.drawPoints() #TODO: Drop the sticker or maybe he will auto-drop ? grabbedSticker = null func cursorClick(): if (hoveredObject and hoveredObject.has_method("on_click")): hoveredObject.on_click() func cursor_look(): if (grabbedSticker ): currentCursorState = CURSOR_STATE.GRABBED elif (hoveredSticker): if (!($GrabTimer.is_stopped())): currentCursorState = CURSOR_STATE.GRABBED else: currentCursorState = CURSOR_STATE.GRAB elif (!($GrabTimer.is_stopped())): currentCursorState = CURSOR_STATE.CLICK else: currentCursorState = CURSOR_STATE.DEFAULT 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(): grab_start() func _on_animated_sprite_2d_animation_changed(): cursorPlaying = true func _on_animated_sprite_2d_animation_finished(): cursorPlaying = false