如何从精灵区域获取 CollisionPolygon2D

发布于 2025-01-20 14:55:08 字数 2252 浏览 1 评论 0原文

我正在尝试从 Sprite 创建的 CollisionPolygon2D 同级中获取 polygon 数据(以便我可以将其添加到我的自定义节点)代码:

在此处输入图像描述

但我遇到了多个问题:

  1. 如何通过代码创建 CollisionPolygon2D 同级

  2. 当我选择 Region Enabled 作为 true 然后创建时,它会给出一个奇怪的偏移量,如下所示:

在此处输入图像描述

  1. 必须首先创建一个 CollisionPolygon2D 同级,它是多边形然后删除它很耗电,有没有办法可以直接获取多边形?

为了避免 XY 问题,请允许我解释一下我想要实现的目标:

我的 Sprite 纹理在游戏中发生变化,因此在发生变化后我需要 CollisionPolygon2D 自动进行相应更改 &我正在寻找耗电最少的解决方案

编辑:

当我指的是精灵时,我指的是不规则透明图片,例如 可以满足我的需要,但它无法通过 代码,那么还有其他方法可以实现这一点吗?

我什至尝试了在旧论坛上找到的这个脚本:

extends CollisionPolygon2D
tool

export (bool) var from_sprite= false setget set_from_sprite

func set_from_sprite(new_val):
    var bitmap = BitMap.new()
    
    var children=self.get_children();
    
    for child in children:
        if(child.get_class()=="Sprite"):
            if(child.texture==null):
                continue
            bitmap.create_from_image_alpha(child.texture.get_data())
            var rect = Rect2(child.position.x, child.position.y, child.texture.get_width(), child.texture.get_height())

            var polygons = bitmap.opaque_to_polygons(rect,0.5);
            print(polygons)
            self.polygon=polygons[0]
            self.position -= Vector2((child.texture.get_width() / 2), (child.texture.get_height() / 2)) * child.scale.x
            self.scale = child.scale

            break;
    property_list_changed_notify();

但它不如Create CollisionPolygon2Dsibling那么精确

I'm trying to get the polygon data (so I can add it to my custom node) from a CollisionPolygon2D sibling created from a Sprite via Code:

enter image description here

but I'm running into multiple problems:

  1. How do I Create CollisionPolygon2D Sibling via code?

  2. When I select Region Enabled as true and then create, it gives a weird offset like this:

enter image description here

  1. Having to create a CollisionPolygon2D sibling first, getting its polygon and then deleting it is power consuming, is there a way I can directly get the polygon?

To Avoid an XY problem allow me to explain what I'm trying to achieve:

My Sprite texture changes in-game, so after it changes I need the CollisionPolygon2D to automatically change accordingly & I'm looking for the least power consuming solution

Edit:

when I meant sprite I meant a irregular transparent image, for example this does what I need but it doesn't work via code, so is there some other way to achieve this?

I even tried this script I found on an old forum:

extends CollisionPolygon2D
tool

export (bool) var from_sprite= false setget set_from_sprite

func set_from_sprite(new_val):
    var bitmap = BitMap.new()
    
    var children=self.get_children();
    
    for child in children:
        if(child.get_class()=="Sprite"):
            if(child.texture==null):
                continue
            bitmap.create_from_image_alpha(child.texture.get_data())
            var rect = Rect2(child.position.x, child.position.y, child.texture.get_width(), child.texture.get_height())

            var polygons = bitmap.opaque_to_polygons(rect,0.5);
            print(polygons)
            self.polygon=polygons[0]
            self.position -= Vector2((child.texture.get_width() / 2), (child.texture.get_height() / 2)) * child.scale.x
            self.scale = child.scale

            break;
    property_list_changed_notify();

but it isn't as precise as Create CollisionPolygon2D sibling

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒几许 2025-01-27 14:55:08

我相信Sprite始终是矩形,您可以使用get_Rect获得,从矩形获得多边形的最佳方法是自己制作。

这样的事情:

static func rect_corners(rect:Rect2) -> PoolVector2Array:
    # Return the positions of the corners of a Rect2.
    # Assuming the size is positive, the points should be:
    # 0: bottom-right, 1: bottom-left, 2: top-left, 3: top-right.

    var start := rect.position
    var end := rect.end
    return PoolVector2Array(
        [
            end,
            Vector2(start.x, end.y),
            start,
            Vector2(end.x, start.y),
        ]
    )

我不知道您实际想做什么形状。但是,看看一个 geetryrer> geetryry 类。它可能很有用,特别是如果您可以通过进行简单多边形的布尔操作来创建多边形(请参阅clip_polygons_2dexplude_polygons_2dMERGE_POLYGONS_2D)。 另请参见convex_hull_2d方法。

请注意,您可以将transform2d应用于polygon(pool> poolvector2Array)。更准确地说xformxform_inv可以在pool> pool vector2array上使用。


顺便说一句,bitmap具有 opaque_to_polygons 方法可能也有用,具体取决于情况。它应该根据给定的bitmap在给定rect2上的bitmapepsilon是分辨率)上的bitmap的alpha提供一个多边形。 a href =“ https://en.wikipedia.org/wiki/marching_squares” rel =“ nofollow noreferrer”>行进squares ,因此,较小的epsilon也会更加精确,但也将是更精确的在更多点上)……这可能对复杂形状有用,或者可能是过度杀伤,或者根本不方便。

I believe the Sprite would always be a rectangle, which you can get with get_rect, and the best way to get a polygon from a rectangle is to make it yourself.

Something like this:

static func rect_corners(rect:Rect2) -> PoolVector2Array:
    # Return the positions of the corners of a Rect2.
    # Assuming the size is positive, the points should be:
    # 0: bottom-right, 1: bottom-left, 2: top-left, 3: top-right.

    var start := rect.position
    var end := rect.end
    return PoolVector2Array(
        [
            end,
            Vector2(start.x, end.y),
            start,
            Vector2(end.x, start.y),
        ]
    )

I don't know what shape you actually want to do. But have a look a the Geometry class. It might be useful, in particular if you can create your polygon by doing boolean operations of simpler polygons (see clip_polygons_2d, exclude_polygons_2d, intersect_polygons_2d, and merge_polygons_2d). See also the convex_hull_2d method.

Be aware that you can apply Transform2D to a polygon (PoolVector2Array). More precisely xform and xform_inv can take and work on PoolVector2Array.


By the way, Bitmap has an opaque_to_polygons method that might also be useful, depending on the situation. It should give you a polygon based on the alpha of the pixels of the Bitmap on the given Rect2 (epsilon is the resolution, it uses marching squares, so a smaller epsilon will be more precise but also result in more points)… Which might be useful for complex shapes, or might be overkill, or might not be convenient at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文