概述
Rect2
是2D场景中比较重要的一种数据类型。
Rect2
的本质含义是2D场景的轴对齐包围盒,而不是可以自由变换的矩形。
Rect2
提供了一些方法,可以方便的判断Rect2
之间是否重叠、包含等,并可以获得重叠的区域。也可以获得两个Rect2
的包围盒。
结合绘图函数,在区域填色、鼠标框选、布局以及某些交互逻辑方面有很多的应用。
merge
@tool
extends Control
var rect1 = Rect2(50,50,100,100)
var rect2 = Rect2(300,200,100,100)
func _draw() -> void:
draw_rect(rect1,Color.AQUA)
draw_rect(rect2,Color.AQUAMARINE)
var rect3 = rect2.merge(rect1)
draw_rect(rect3,Color.ORANGE_RED,false,2)
intersection
@tool
extends Control
var rect1 = Rect2(50,50,100,100)
var rect2 = Rect2(90,100,100,100)
func _draw() -> void:
draw_rect(rect1,Color.AQUA)
draw_rect(rect2,Color.AQUAMARINE)
var rect3 = rect2.intersection(rect1)
draw_rect(rect3,Color.ORANGE_RED,false,2)
expand
extends Control
var rect1 = Rect2(300,300,100,100)
var pos:Vector2
func _process(delta: float) -> void:
pos = get_global_mouse_position()
queue_redraw()
func _draw() -> void:
draw_rect(rect1,Color.AQUA)
if pos:
draw_rect(rect1.expand(pos),Color.WHITE,false,2)
Support
返回此矩形在给定方向上最远的顶点位置。这一点通常被称为碰撞检测算法中的支持点。
extends Control
var rect1 = Rect2(100,100,100,100)
var pos:Vector2
func _process(delta: float) -> void:
pos = get_global_mouse_position()
queue_redraw()
func _draw() -> void:
draw_rect(rect1,Color.AQUA)
if pos:
var center = rect1.get_center()
var dir = center.direction_to(pos)
draw_circle(rect1.get_support(dir),3,Color.RED)
技巧
用position和end指定的Rect2
在绘制鼠标选框时,用Rect2
和绘图函数实现是最简单的。
而鼠标框选会存在一个负尺寸的问题,通过直接设定position
和end
指定Rect2
的形式可以避免。
extends Control
var rect1 = Rect2()
var end:Vector2
func _process(delta: float) -> void:
end = get_global_mouse_position()
queue_redraw()
func _draw() -> void:
rect1.position = Vector2(100,100)
if end:
rect1.end = end
draw_rect(rect1,Color.AQUA)
简单的鼠标框选
extends Control
var rect1 = Rect2(100,100,100,100)
var is_selecting:bool
var start:Vector2
var end:Vector2
var sel_rect:Rect2
var selected:bool # rect1是否被选中
func _input(event: InputEvent) -> void:
if event.is_action_pressed("L_Press"):
start = get_global_mouse_position()
is_selecting = true
if is_selecting:
end = get_global_mouse_position()
queue_redraw()
if event.is_action_released("L_Press"):
is_selecting = false
selected = sel_rect.encloses(rect1) # 完全包含
queue_redraw()
func _draw() -> void:
if selected:
draw_rect(rect1,Color.RED)
else:
draw_rect(rect1,Color.AQUA)
if is_selecting:
sel_rect.position =start
sel_rect.end = end
draw_rect(sel_rect,Color.AQUA,false,1)