Node2D.gd: 于 2022-01-05 编辑
extends Node2D
var ball = preload("res://Area2D.tscn")
var prv
onready var viewSize = get_viewport_rect().size
class Sorter:
static func sort(a, b):
if a["collider"].get_index() > b["collider"].get_index():
return true
return false
func _ready():
randomize()
for i in 200:
new(i > 100)
func _input(event):
if event is InputEventMouseButton:
match event.button_index:
BUTTON_LEFT:
if event.is_pressed():
#这里可以应用各种规则来提高效率,比如减少intersect_point检测数量,减少intersect_point触发次数
var stime = OS.get_ticks_msec()
var shapes = get_world_2d().direct_space_state.intersect_point(get_global_mouse_position(), 9999, [], 0x7fffffff, false, true)
var size = shapes.size()
if size > 0:
if size > 1:
shapes.sort_custom(Sorter, "sort")
var etime = OS.get_ticks_msec() - stime
print("检测耗时(毫秒)", etime)
var collider = shapes[0]["collider"]
if collider.has_method("_on_drag"):
if collider.get_index() < collider.get_parent().get_child_count() - 1:
collider.raise()
print("置顶", collider.get_instance_id())
prv = collider
collider._on_drag(true)
else:
print("intersect_point zero")
else:
if prv:
prv._on_drag(false)
prv = null
BUTTON_RIGHT:
if event.is_pressed():
new(false)
func new(rnd):
var node = ball.instance()
var size = node.get_node("Sprite").texture.get_size()
if rnd:
node.position = Vector2(rand_range(size.x * 4, viewSize.x - size.x), rand_range(size.y, viewSize.y - size.y))
else:
node.position = size
add_child(node)
Area2D.gd:
extends Area2D
var isDrag = false
var offset
onready var label = $Label
onready var sprite = $Sprite
onready var id = self.get_instance_id()
func _ready():
label.text = str(id);
sprite.self_modulate = Color(randf(), randf(), randf(), 1)
func _process(delta):
if isDrag:
self.position = get_global_mouse_position() + offset
func _on_drag(state):
if state:
offset = self.position - get_global_mouse_position()
isDrag = true
print("开始拖动", id)
else:
if isDrag:
isDrag = false
print("结束拖动", id)
#func _on_Area2D_input_event(viewport, event, shape_idx):
# if isDrag:
# if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
# if not event.is_pressed():
# isDrag = false
# print("内部结束(实例id)", id)
于 2022-01-05 补充
direct_space_state属于物理系统,在input输入事件中使用可能存在时序问题,改为在physics_process回调中使用更加合适
其它安全问题参考:https://docs.godotengine.org/zh_CN/stable/tutorials/physics/ray-casting.html
Node2D.gd:
func _physics_process(delta):
if Input.is_action_just_pressed("ui_mouse_left"):
#这里可以应用各种规则来提高效率,比如减少intersect_point检测数量,减少intersect_point触发次数
var stime = OS.get_ticks_msec()
var shapes = get_world_2d().direct_space_state.intersect_point(get_global_mouse_position(), 9999, [], 0x7fffffff, false, true)
var size = shapes.size()
if size > 0:
if size > 1:
shapes.sort_custom(Sorter, "sort")
var etime = OS.get_ticks_msec() - stime
print("检测耗时(毫秒)", etime)
var collider = shapes[0]["collider"]
if collider.has_method("_on_drag"):
if collider.get_index() < collider.get_parent().get_child_count() - 1:
collider.raise()
print("置顶", collider.get_instance_id())
prv = collider
collider._on_drag(true)
else:
print("intersect_point zero")
elif Input.is_action_just_released("ui_mouse_left"):
if prv:
prv._on_drag(false)
prv = null
if Input.is_action_just_pressed("ui_mouse_right"):
new(false)