如何检查两个 KinematicBody2D 在 Godot 中是否重叠?

发布于 2025-01-17 03:32:01 字数 616 浏览 1 评论 0原文

我刚刚开始编码,正在尝试在 Godot 3.0 中制作一个简单的鸭子射击游戏。我有一个十字准线(Kinematicbody2D)和飞过屏幕的鸭子(也是 KinematicBody2D)。有没有办法检测鸭子和十字准线是否重叠?就像 if 语句一样?
如果有人好奇,这是我到目前为止得到的代码(这是鸭子脚本,注释是我需要在该行中添加的内容)。

 func _physics_process(delta: float) -> void:
    position.x += 4
    if (position.x > 1600):
        Score -= 1
        position.x = rand_range(-250, -1000)
    
    if Input.is_action_just_pressed("shoot"):
        #check if overlapping with crosshair
            Score += 1
            #bird explodes in feathers
            position.x = rand_range(-250, -1000)
        else:
            Score -= 0.25

I've just gotten into coding, and I'm trying to make a simple duck shooter game in Godot 3.0. I have a crosshair(Kinematicbody2D) and ducks flying across the screen(also KinematicBody2D). Is there a way that I can detect if the duck and crosshair are overlapping? Like an if statement?
In case anyone's curious, this is the code I've got so far (This is the duck script and the comments are what I need to add in on that line).

 func _physics_process(delta: float) -> void:
    position.x += 4
    if (position.x > 1600):
        Score -= 1
        position.x = rand_range(-250, -1000)
    
    if Input.is_action_just_pressed("shoot"):
        #check if overlapping with crosshair
            Score += 1
            #bird explodes in feathers
            position.x = rand_range(-250, -1000)
        else:
            Score -= 0.25

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

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

发布评论

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

评论(1

禾厶谷欠 2025-01-24 03:32:01

我认为将十字线做成物理体是没有意义的。 它会碰撞/推动/弹开障碍物吗?更不用说KinematicBody2D了。 您需要move_and_slide吗?或者您可以不用写位置吗?所以在我回答问题之前,这里有一些替代方案正如发布的那样。


Input Pickable

如果你想知道指针是否与物理体交互,你可以启用input_pickable,你会得到一个“input_event” 发生时发出信号。


模拟输入可选取

否则,您可以在 _input 事件中获取指点设备的位置并查询那里有哪些物理对象。像这样:

if (
        event is InputEventScreenDrag
        or event is InputEventScreenTouch
        or event is InputEventMouse
    ):
        var viewport := get_viewport()
        var position:Vector2 = viewport.get_canvas_transform().affine_inverse().xform(event.position)
        var objects := get_world_2d().direct_space_state.intersect_point(position)
        for object in objects:
            print(object.collider)

看看你想要的人是否在那里。


Area2D

另一种选择是将十字线制作成 Area2D,然后您可以向 Area2D 询问其 overlapping_bodies,看看那里有没有你想要的那个。或者调用 overlaps_body 将物理主体作为参数传递,如果它与 Area2D 重叠,则返回 truefalse 或分别不是。


KinematicBody2D 碰撞

为了回答标题上的问题,如果您有两个运动体,如果您使用 move_and_* 方法移动它们(这就是它的意图)。您可以列出它们碰撞的内容,如下所示:

for i in get_slide_count():
    var collision = get_slide_collision(i)
    print("Collided with: ", collision.collider.name)

否则,您可以这样做:

var parameters := Physics2DShapeQueryParameters.new()
parameters.transform = global_transform
parameters.set_shape($CollisionShape2D.shape)
var results = get_world_2d().direct_space_state.intersect_shape(parameters)
for result in results:
    print(result.collider)

I don't think it makes sense to make the crosshair into a physics body. Does it collide/push/bounce off obstacles? Much less a KinematicBody2D. Do you need move_and_slide or can you get away with writing the position? So here are some alternatives to go about it, before I answer the question as posted.


Input Pickable

If you want to find out if the pointer interacts with a physics body, you can enable input_pickable, and you will get an "input_event" signal whenever it happens.


Mimic input Pickable

Otherwise you can get the position of the pointing device in an _input event and query what physics objects are there. Something like this:

if (
        event is InputEventScreenDrag
        or event is InputEventScreenTouch
        or event is InputEventMouse
    ):
        var viewport := get_viewport()
        var position:Vector2 = viewport.get_canvas_transform().affine_inverse().xform(event.position)
        var objects := get_world_2d().direct_space_state.intersect_point(position)
        for object in objects:
            print(object.collider)

And see if the one you want is there.


Area2D

Another option is to make the crosshair into an Area2D, then you can ask the Area2D for its overlapping_bodies, and see if the one you want is there. Or call overlaps_body passing your physics body as parameter and it returns true or false if it is overlapping the Area2D or not, respectively.


KinematicBody2D collisions

And to answer the question on the title, if you have two kinematic bodies, if you moved them with move_and_* methods (which is how it is intended). You can a lists of what they collided with like this:

for i in get_slide_count():
    var collision = get_slide_collision(i)
    print("Collided with: ", collision.collider.name)

Otherwise, you can do this:

var parameters := Physics2DShapeQueryParameters.new()
parameters.transform = global_transform
parameters.set_shape($CollisionShape2D.shape)
var results = get_world_2d().direct_space_state.intersect_shape(parameters)
for result in results:
    print(result.collider)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文