Godot用Area2D实现带层次拖动

效果
Node2D.gd:

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)

猜你喜欢

转载自blog.csdn.net/a363533090/article/details/115803102
今日推荐