Work in progress

The content of this page was not yet updated for Godot `4.2` and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

# 跳跃与踩扁怪物¶

## 控制物理交互¶

### 层和遮罩的分配¶

Main 场景中选中 `Ground` 节点。在检查器中展开 Collision（碰撞）部分。你可以看到，该节点的层和遮罩在这里以按钮网格的形式排列。

## 跳跃¶

```#...
# Vertical impulse applied to the character upon jumping in meters per second.
@export var jump_impulse = 20
```

`_physics_process()` 内，请在调用 `move_and_slide()` 那块代码之前添加以下代码。

```func _physics_process(delta):
#...

# Jumping.
if is_on_floor() and Input.is_action_just_pressed("jump"):
target_velocity.y = jump_impulse

#...
```

`is_on_floor()` 方法是来自 `CharacterBody3D` 类的工具。如果物体在这一帧中与地板发生碰撞返回 `true`。这就是为什么我们要对 Player 施加重力的原因：这样我们就会与地板相撞，而不是像怪物一样漂浮在地板上。

## 踩扁怪物¶

### 编写踩扁机制¶

```# Vertical impulse applied to the character upon bouncing over a mob in
# meters per second.
@export var bounce_impulse = 16
```

```func _physics_process(delta):
#...

# Iterate through all collisions that occurred this frame
for index in range(get_slide_collision_count()):
# We get one of the collisions with the player
var collision = get_slide_collision(index)

# If the collision is with ground
if collision.get_collider() == null:
continue

# If the collider is with a mob
if collision.get_collider().is_in_group("mob"):
var mob = collision.get_collider()
# we check that we are hitting it from above.
if Vector3.UP.dot(collision.get_normal()) > 0.1:
# If so, we squash it and bounce.
mob.squash()
target_velocity.y = bounce_impulse
# Prevent further duplicate calls.
break
```

`get_slide_collision()` 返回的是 KinematicCollision3D 对象，包含碰撞在哪里发生、如何发生等信息。例如，我们对它的 `get_collider` 属性调用 `is_in_group()` 来检查我们是否是和“mob”发生了碰撞：`collision.collider.is_in_group("mob")`