【Godot4.2】Rect2拓展——mRect2类

2024-03-22 03:36
文章标签 拓展 godot4.2 rect2 mrect2

本文主要是介绍【Godot4.2】Rect2拓展——mRect2类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

Rect2存在一些问题,比如难以获取除positionendcenter之外的其他点。虽然计算并不复杂,就是简单的向量加减。但每次手动计算则比较麻烦。
其实在ShapePoints静态函数库中,已经尝试返回矩形的四个顶点,用于绘制矩形。

# 返回矩形的顶点
# 注意:以(0,0)为几何中心
static func rect(size:Vector2) -> PackedVector2Array:var points:PackedVector2Array = [-size/2,-size/2 + Vector2.RIGHT * size.x,size/2,-size/2 + Vector2.DOWN * size.y,-size/2]return points

mRect2要做的是基于一个Rect2,快速返回九个位置点。

源代码

基于简单的思想,简单的实现了mRect2

# ========================================================
# 名称:mRect2
# 类型:自定义类
# 作者:巽星石
# Godot版本:4.1-stable (official) --> v4.2.1.stable.official [b09f793f5]
# 基于Rect2获取更多的边角点信息。
# 创建时间:2023-07-09 17:46:49
# 最后修改时间:202432121:09:52
# ========================================================class_name mRect2var _rect:Rect2# =================================== 构造 ===================================
func _init(rect:Rect2):_rect = rect# =================================== 静态方法 ===================================
# 根据position和size构造
static func by_size(position:Vector2,size:Vector2) -> mRect2:var rect = Rect2(position,size)return mRect2.new(rect)# 根据x,y,width,height 构造
static func by_xywh(x:float,y:float,width:float,height:float) -> mRect2:var rect = Rect2(x,y,width,height)return mRect2.new(rect)# =================================== 方法 ===================================
## 矩形 - 左上角 - 坐标
func top_left() -> Vector2:return _rect.position## 矩形 - 顶边中心 - 坐标
func top_center() -> Vector2:return _rect.position + Vector2.RIGHT * (_rect.size.x/2)## 矩形 - 顶边中心 - 坐标
func top_right() -> Vector2:return _rect.position + Vector2.RIGHT * _rect.size.x## 矩形 - 左边中心 - 坐标
func left_center() -> Vector2:return _rect.position + Vector2.DOWN * (_rect.size.y/2)## 矩形 - 矩形中心 - 坐标
func center() -> Vector2:return _rect.get_center()## 矩形 - 右边中心 - 坐标
func right_center() -> Vector2:return  _rect.get_center() + Vector2.RIGHT * (_rect.size.x/2)## 矩形 - 左下角 - 坐标
func left_bottom() -> Vector2:return _rect.position + Vector2.DOWN * _rect.size.y## 矩形 - 底边中心 - 坐标
func bottom_center() -> Vector2:return _rect.get_center()  + Vector2.DOWN * (_rect.size.y/2)## 矩形 - 右下角 - 坐标
func right_bottom() -> Vector2:return  _rect.end## 矩形 - 四个角坐标点 - 数组
## 可同于绘制矩形
func corners() -> PackedVector2Array:return [top_left(),top_right(),right_bottom(),left_bottom()]# 返回向外扩展一定距离的四个角顶点
func expend_corners(length:float) -> PackedVector2Array:var arr:PackedVector2Arrayvar v1 = - Vector2.ONE * lengtharr.append(top_left() + v1)arr.append(top_right() + v1.rotated(deg_to_rad(90)))arr.append(right_bottom() + v1.rotated(deg_to_rad(180)))arr.append(left_bottom() + v1.rotated(deg_to_rad(270)))return arr# 返回向外扩展一定距离的四个角顶点水平和垂直延伸出一定距离的点坐标
func expend_corners_lines(length:float,a:float = 10.0,b:float =10.0) -> PackedVector2Array:var arr:PackedVector2Arrayvar v1 = - Vector2.ONE * lengthvar p1 = top_left() + v1  # 第一个扩展点var v_a1 = Vector2.RIGHT * a  # 水平向量var v_b1 = Vector2.DOWN * b   # 垂直向量arr.append_array([p1,p1+v_a1]) # 添加水平线arr.append_array([p1,p1+v_b1]) # 添加垂直线# 右上角点var rad2 = deg_to_rad(90)var p2 = top_right() + v1.rotated(rad2)arr.append_array([p2,p2 - v_a1]) # 添加水平线arr.append_array([p2,p2 + v_b1]) # 添加垂直线# 右上角点var rad3 = deg_to_rad(180)var p3 = right_bottom() + v1.rotated(rad3)arr.append_array([p3,p3 - v_a1]) # 添加水平线arr.append_array([p3,p3 - v_b1]) # 添加垂直线# 右上角点var rad4 = deg_to_rad(270)var p4 = left_bottom() + v1.rotated(rad4)arr.append_array([p4,p4 + v_a1]) # 添加水平线arr.append_array([p4,p4 - v_b1]) # 添加垂直线return arr## 返回矩形对应的9个点 - 数组
func points() -> PackedVector2Array:return [top_left(),top_center(),top_right(),right_center(),right_bottom(),bottom_center(),left_bottom(),left_center(), center()]

使用

可以通过以下3种方式构建mRect2实例:

  • 可以通过给mRect2new()传入一个Rect2类型来创建mRect2实例
  • 可以通过by_size静态方法,基于positionsize2个参数创建mRect2实例
  • 可以通过by_xywh静态方法,基于xywidthheight4个参数创建mRect2实例
var rect = mRect2.new(Rect2.new())
var rect = mRect2.by_size(Vector2(100,100),Vector2(300,400))
var rect = mRect2.by_xywh(100,100,300,400)

快速获取矩形的某个特殊点坐标

mRect2中,将一个矩形的4个顶点、4个边的中点以及矩形中心点,共9个特殊点,从左上角开始,顺时针存入points方法所返回的数组中,你可以通过points()[下标]形式获取相应的点。
或者也可以通过对应名称的方法获取。

# 获取安全矩形
var rect = mRect2.new(get_draw_safety_rect())
print(rect.top_left())       # 左上角 -- 等价于rect.points()[0]
print(rect.top_center())     # 上边中点 -- 等价于rect.points()[1]
print(rect.top_right())      # 右上角	 -- 等价于rect.points()[2]
print(rect.right_center())   # 右边中点 -- 等价于rect.points()[3]
print(rect.right_bottom())   # 右下角	 -- 等价于rect.points()[4]
print(rect.bottom_center())  # 下边中点 -- 等价于rect.points()[5]
print(rect.left_bottom())    # 左下角	 -- 等价于rect.points()[6]
print(rect.left_center())    # 左边中点 -- 等价于rect.points()[7]
print(rect.center())         # 中点 -- 等价于rect.points()[8]

绘制矩形的9个特殊点

我们创建如下场景:
image.png
为根节点添加代码如下:

@tool
extends Controlfunc _draw():# 获取安全矩形var rect = mRect2.new(get_draw_safety_rect())# 绘制边框矩形draw_rect(get_draw_safety_rect(),Color.GREEN_YELLOW,false,1)# 绘制9个特殊点for point in rect.points():draw_circle(point,5,Color.GOLDENROD)# 获取绘制函数能正确使用的控件Rect2
func get_draw_safety_rect() -> Rect2:var rect = get_rect()return Rect2(rect.position - position,rect.size/scale)

可以看到绘制出的效果:
image.png
之所以大费周章的编写方法获取这9个点的位置,是因为,基于它们我们可以对矩形进行一定的修饰。比如在矩形外四个角上绘制选择框等。

在矩形的四个角外绘制特殊纹理

获取四个角向外扩展一定距离后的坐标

@tool
extends Controlfunc _draw():# 获取安全矩形var rect = mRect2.new(get_draw_safety_rect())draw_rect(get_draw_safety_rect(),Color.YELLOW_GREEN,false,2)# 获取和绘制向外扩展的四个角顶点var points = rect.expend_corners(20) # 获取向外扩展20像素后的四个角顶点坐标for point in points:draw_circle(point,5,Color.YELLOW)# 获取绘制函数能正确使用的控件Rect2
func get_draw_safety_rect() -> Rect2:var rect = get_rect()return Rect2(rect.position - position,rect.size/scale)

通过expend_corners可以获取四个角向外扩展一定距离的坐标,从而可以在矩形的4个角之外,绘制特殊的形状。这里简单的绘制了4个圆点:
image.png

获取四个角向外扩展一定距离后水平和垂直延伸的线段

expend_corners_lines更近一步,获取从扩展点水平和垂直延伸出给定长度的线段的坐标。
使用draw_multiline就可以直接绘制。

@tool
extends Controlfunc _draw():# 获取安全矩形var rect = mRect2.new(get_draw_safety_rect())draw_rect(get_draw_safety_rect(),Color.YELLOW_GREEN,false,2)# 获取和绘制向外扩展的四个角顶点var points = rect.expend_corners_lines(20,50,60) # 获取向外扩展20像素后的四个角顶点坐标draw_multiline(points,Color.YELLOW,2)# 获取绘制函数能正确使用的控件Rect2
func get_draw_safety_rect() -> Rect2:var rect = get_rect()return Rect2(rect.position - position,rect.size/scale)

绘制后的效果:
image.png
应用之一就是为Sprite2D等绘制选中框。

@tool
extends Sprite2Dfunc _draw():var rect = mRect2.new(get_rect())# 获取和绘制向外扩展的四个角顶点var points = rect.expend_corners_lines(20,50,60) # 获取向外扩展20像素后的四个角顶点坐标draw_multiline(points,Color.YELLOW,2)

image.png

总结

  • 这个类初始创建于2023年7月9日,于2024年3月21日进行了一定的改进和扩充。当然在我眼里这个类还有很大的拓展和改进空间,但是对于基础的选择框问题,也就是创造它的初衷,已经基本达到了。
  • 我不知道这个类是不是对你们有用,但是对于我自己是有一定的用途的

这篇关于【Godot4.2】Rect2拓展——mRect2类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/834437

相关文章

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

安卓玩机工具------小米工具箱扩展工具 小米机型功能拓展

小米工具箱扩展版                     小米工具箱扩展版 iO_Box_Mi_Ext是由@晨钟酱开发的一款适用于小米(MIUI)、多亲(2、2Pro)、多看(多看电纸书)的多功能工具箱。该工具所有功能均可以免root实现,使用前,请打开开发者选项中的“USB调试”  功能特点 【小米工具箱】 1:冻结MIUI全家桶,隐藏状态栏图标,修改下拉通知栏图块数量;冻结

多线程并发拓展

死锁 死锁是指两个或两个以上的进程,因争夺资源而造成一种互相等待的作用,如果没有外力作用它们都将无法推进下去,此时我们就称系统进入死锁状态 死锁必要条件 互斥条件:进程对所分配的资源进行排他性的使用,在一段时间内某资源只有一个资源占用,如果此时还有其它进程请求资源,那么请求者只能等待 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其它资源占用,此时请求进程

Python 爬虫入门 - 基础数据采集流程拓展

在网络爬虫的世界里,数据就是一切。通过爬虫技术,你可以自动化地收集各种类型的公开数据,从文本和图片到复杂的结构化信息,这些数据为各类分析和应用提供了基础。 本教程将引导你深入了解爬虫可以采集的数据种类,如何有效地获取这些数据,并探讨如何使用代理服务来规避限制与增强爬虫的灵活性。无论是初学者还是有经验的开发者,这些知识都将帮助你在网络数据采集中更加游刃有余。 文章目录 可采集的数据基本操作

linux文件的拓展属性

一、概述 文件的扩展属性(EA) 即以名称-值对形式将任意元数据与文件 i 节点关联 起来的技术。 2. EA 可用于实现访问列表(第 17 章)和文件能力(第 39 章)。 二、EA 命名空间 EA 的命名格式为 namespace.name。其中 namespace 用来把 EA 从功能上划分为截然不同的几大类,而 name 则用来在既定命名空间内唯一标识某个 EA。 可

《零散知识点 · Kafka 知识拓展》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍 文章目录 写在前面的话环境调优专栏如何防止消息丢失如何防止重复消费如何防止消息乱序如何防止消息积压零散知识收录运维常见问题总结陈词 写在前面的话 本篇文章分享一下关于

【tarjan缩点+小拓展】【POJ-2186】

用刚搞到的模板,去过了一道题 差不多是个模板题 有一群奶牛,奶牛A可以关注B,关注具有传递性,给出奶牛之间的关注关系,问有几只奶牛得到了所有其他奶牛的关注? 互相关注的可以看成一个点,所以直接tarjan算法 + 缩点 新图中,出度为0的点只能有一个,因为如果有两个,这两个新点(原连通分量)就一定是互相没有关注联系的 然后答案就是这个出度为0 的新点(原连通分量)中包含的原来点的个

Katalon recorder(谷歌浏览器拓展程序)

一、简介 katalon recorder是针对web端录制工具,同时也是一个谷歌插件,无任何环境要求,支持chrome、firefox浏览器 二、安装 (一)下载谷歌插件(扩展程序) 1.国内:CRX应用市场下载 https://www.crx4chrome.com/crx/62796/ 2.国外:Chrome应用或Firefox应用市场下载 (

活动系统开发之采用设计模式与非设计模式的区别-需求设计及拓展

通过活动系统流程图拆分成5个业务流程图 1、签到与滚动抽奖业务流程图 2、签到与答题领取奖品业务流程图 3、签到与抽奖业务流程图 4、答题与组团业务流程图 5、答题与美图分享业务流程图 6、总结         因业务流程相互嵌套,所以将每个系统模板化后可以动态组合目前的子业务。         a、签到-》答题-》组团         b、签到-》答题-》美

iOS10通知及通知拓展Extension使用详解(附Demo)

1.1-iOS10拓展简介 1.2-iOS10通知使用 1.3-iOS10通知拓展Extension使用 1.4-效果演示 如果对开发有兴趣的可以来黑马学习iOS开发:黑马程序员源代码下载地址:Deme下载 1.1-iOS10拓展简介 iOS10系统最大的一个亮点就是增加了系统应用的拓展功能Extension Extension功能可以理解为自定义系统界面本小节我们就以自定义系统通