我如何检测Kinematicbody2d与Godot中的刚性2D之间的碰撞?

发布于 2025-01-27 20:02:42 字数 1021 浏览 6 评论 0原文

我试图在戈多特制作一个简单的游戏,墙壁掉下来,玩家必须躲避它。墙是一个刚性的2​​D,带有精灵,并附有CollisionShape2D。播放器是一个Kinematicbody2D,带有精灵和collisionShape2d。主要场景是一个Node2D,玩家和墙是一个孩子。我设法让玩家检测到碰撞,但是当我发出信号(连接到墙脚本)时,墙一无所有。我已经尝试在玩家脚本中使用body_entered信号,但是什么也没有发生。有人知道如何解决这个问题吗?

我的玩家脚本:

extends KinematicBody2D

var speed = 1300
var velocity = Vector2()
signal game_over

func get_input():
velocity = Vector2()
if Input.is_action_pressed('d'):
    velocity.x += 1
if Input.is_action_pressed('a'):
    velocity.x -= 1
velocity = velocity.normalized() * speed

func _physics_process(delta):
get_input()

move_and_slide(velocity, Vector2(0, 0), false, 4, 0.785, false)

for index in get_slide_count():
    var collision = get_slide_collision(index)
    if collision.collider.is_in_group("Level"):
        death()

func death():
    emit_signal("game_over")
    hide()

墙脚本:

extends RigidBody2D

func _on_Player_game_over():
    print("player collided") #example to see if collision is detected

I am trying to make a simple game in Godot where a wall falls down and the player has to dodge it. The wall is a RigidBody2D with a sprite and CollisionShape2D attached. The player is a KinematicBody2D with a sprite and CollisionShape2D attached. The main scene is a Node2D with the player and wall as children of it. I have managed to get the player to detect collisions but when I emit a signal (which is connected to the wall script), the wall does nothing. I have already tried using the body_entered signal in the player script, but nothing happens. Does anybody know how to fix this?

My player script:

extends KinematicBody2D

var speed = 1300
var velocity = Vector2()
signal game_over

func get_input():
velocity = Vector2()
if Input.is_action_pressed('d'):
    velocity.x += 1
if Input.is_action_pressed('a'):
    velocity.x -= 1
velocity = velocity.normalized() * speed

func _physics_process(delta):
get_input()

move_and_slide(velocity, Vector2(0, 0), false, 4, 0.785, false)

for index in get_slide_count():
    var collision = get_slide_collision(index)
    if collision.collider.is_in_group("Level"):
        death()

func death():
    emit_signal("game_over")
    hide()

The wall script:

extends RigidBody2D

func _on_Player_game_over():
    print("player collided") #example to see if collision is detected

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

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

发布评论

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

评论(1

秋风の叶未落 2025-02-03 20:02:42

我无法说出为什么您的代码不起作用。但是,我会以不同的方式做:与其发出信号,不如在collider上调用方法

    if collision.collider.is_in_group("Level"):
        collision.collider._on_Player_game_over()
        death()

可能值得给该方法一个更好的名称。

,顺便说一句。您还可以检查对撞机是否具有该方法。例如:

    if collision.collider.has_method("_on_Player_game_over"):
        collision.collider._on_Player_game_over()
        death()

其余答案正在解释如何用arigdbody2d上处理碰撞,“ body_entered” signal。

  • 首先确保arigidbody2d具有contact_monitor设置为true

  • 还将其Contacts_reported设置为大于0的值。可以与同一身体有多个接触,您需要考虑与其他尸体的可能接触。 围绕8的值可能还可以。

  • 具有“ body_entered” argid> arigidbody2d connected 信号< em>本身。


  • arigidbody2d的方法中,处理“ body_entered”信号您将获得body> body参数:

      func _on_wall_body_enter(Body):
        打印(“碰撞”)
     

    顺便说一句,我想鼓励利用碰撞层和口罩。因此,您可以缩小arigidbody2d甚至检查。

    的碰撞。

  • 因此 例如,您可以:

    • 使用名称:

        func _on_wall_body_enter(Body):
          如果body.name ==“ player”:
              打印(“与玩家碰撞”)
       
    • 使用组:

        func _on_wall_body_enter(Body):
          如果body.is_in_group(“ player”):
              打印(“与玩家碰撞”)
       
    • 使用类名称(这需要向玩家添加class_name):

        func _on_wall_body_enter(Body):
          如果身体是玩家:
              打印(“与玩家碰撞”)
       
    • 检查方法:

        func _on_wall_body_enter(Body):
          如果body.has_method(“死亡”):
              打印(“与玩家碰撞”)
       
  • ,当然,您可以在通知上调用方法。例如:

      func _on_wall_body_enter(Body):
        如果身体是玩家:
            body.depheath()
     

      func _on_wall_body_enter(Body):
        如果body.has_method(“死亡”):
            body.depheath()
     

I can't tell why your code is not working. However, I would do it differently: Instead of emitting a signal, call a method on the collider:

    if collision.collider.is_in_group("Level"):
        collision.collider._on_Player_game_over()
        death()

It is probably worth giving the method a better name.

By the way, you can also check if the collider has the method. For example:

    if collision.collider.has_method("_on_Player_game_over"):
        collision.collider._on_Player_game_over()
        death()

The rest of this answer is explaining how to handle the collision on the RigidBody2D with the "body_entered" signal.

  • First make sure the RigidBody2D has contact_monitor set to true.

  • Also set its contacts_reported to a value greater than 0. There can be multiple contacts with the same body, and you need to consider possible contacts with other bodies. A value around 8 is probably OK.

  • Have the "body_entered" signal of the RigidBody2D connected to itself.

  • in the method in the RigidBody2D that handles the "body_entered" signal you would get a body parameter:

    func _on_Wall_body_enter(body):
        print("Collision")
    

    By the way, I would like to encourage to take advantage of collision layer and masks. So you can narrow what collisions the RigidBody2D even checks for.

  • Then you can filter what body it is. You can, for example:

    • Use the name:

      func _on_Wall_body_enter(body):
          if body.name == "Player":
              print("Collision with player")
      
    • Use a group:

      func _on_Wall_body_enter(body):
          if body.is_in_group("Player"):
              print("Collision with player")
      
    • Use a class name (this requires to add a class_name to the player):

      func _on_Wall_body_enter(body):
          if body is Player:
              print("Collision with player")
      
    • Check for a method:

      func _on_Wall_body_enter(body):
          if body.has_method("death"):
              print("Collision with player")
      
  • And, of course, you can call a method on it notify. For example:

    func _on_Wall_body_enter(body):
        if body is Player:
            body.death()
    

    Or

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