游戏开发中的物理之运动角色(2D)

游戏开发中的物理之运动角色(2D)

介绍

是的,这个名字听起来很奇怪。“运动角色”。那是什么?该名称的原因是,当物理引擎问世时,它们被称为“动态”引擎(因为它们主要处理碰撞响应)。为了使用动态引擎创建角色控制器,已经进行了许多尝试,但是这并不像看起来那样容易。Godot是您可以找到的最佳动态角色控制器实现之一(如在2d / platformer演示中所见),但是使用它需要相当水平的技能和对物理引擎的理解(或者非常耐心尝试错误)。

诸如Havok之类的某些物理引擎似乎认为动态角色控制器是最佳选择,而其他物理引擎(PhysX)则更愿意推广运动学引擎。

那么区别是什么呢?:

甲动态字符控制器采用刚性体具有无限惯性张量。这是一个不能旋转的刚体。物理引擎总是让物体移动和碰撞,然后一起解决它们的碰撞。如平台游戏演示所示,这使动态角色控制器能够与其他物理对象无缝交互。但是,这些交互并非总是可预测的。碰撞可能需要一帧以上的时间才能解决,因此一些碰撞似乎只位移了一小部分。这些问题可以解决,但需要一定的技能。
一个运动人物控制器被假定为总是在非碰撞状态开始,并且会一直移动到非冲突状态。如果它开始处于碰撞状态,它将尝试像刚体一样释放自身,但这是例外,而不是规则。这使得它们的控制和运动更加可预测且易于编程。但是,不利的是,除非手动编写代码,否则它们无法直接与其他物理对象进行交互。
这个简短的教程将集中于运动字符控制器。基本上,这是老式的处理冲突的方式(不一定在幕后变得更简单,而是被很好地隐藏起来并作为一个很好的简单API呈现)。

物理过程

为了管理运动体或角色的逻辑,始终建议使用物理过程,因为它在物理步骤之前被调用,并且其执行与物理服务器同步,也总是被称为每秒相同的次数。与使用常规过程相比,这使物理和运动计算的工作方式更具可预测性,如果帧率太高或太低,则常规过程可能会出现尖峰或失去精度。

using Godot;
using System;

public class PhysicsScript : KinematicBody2D
{
    
    
    public override void _PhysicsProcess(float delta)
    {
    
    
    }
}

场景设定

有一些测试,这里的场景(从tilemap的教程) kbscene.zip。我们将为角色创建一个新场景。使用机器人精灵创建一个这样的场景:

../../_images/kbscene.png

您会注意到,我们的CollisionShape2D节点旁边有一个警告图标。这是因为我们尚未为其定义形状。在CollisionShape2D的shape属性中创建一个新的CircleShape2D。单击转到其选项,并将半径设置为30:

../../_images/kbradius.png

注意:如之前在物理教程中所述,物理引擎无法处理大多数形状的比例(仅碰撞多边形,平面和线段有效),因此请始终更改形状的参数(例如半径),而不是缩放它。运动/刚体/静态物体本身也是如此,因为它们的比例会影响形状比例。

现在,为角色创建一个脚本,上面用作示例的脚本应作为基础。

最后,在tilemap中实例化该角色场景,并将其作为主要场景,以便在按下play时运行。

../../_images/kbinstance.png

运动学特征

回到角色场景,打开脚本,魔术开始了!运动体默认情况下不执行任何操作,但它具有一个有用的功能,称为 KinematicBody2D.move_and_collide()。此函数将Vector2用作参数,然后尝试将该运动应用于运动体。如果发生碰撞,它会在碰撞发生时立即停止。

因此,让我们向下移动精灵,直到它掉到地上:

using Godot;
using System;

public class PhysicsScript : KinematicBody2D
{
    
    
    public override void _PhysicsProcess(float delta)
    {
    
    
        // Move down 1 pixel per physics frame
        MoveAndCollide(new Vector2(0, 1));
    }
}

结果是角色将移动,但在撞击地板时会立即停止。太酷了吧?

下一步是将重力添加到混合中,这样,它的行为就有点像常规游戏角色:

using Godot;
using System;

public class PhysicsScript : KinematicBody2D
{
    
    
    const float gravity = 200.0f;
    Vector2 velocity;

    public override void _PhysicsProcess(float delta)
    {
    
    
        velocity.y += delta * gravity;

        var motion = velocity * delta;
        MoveAndCollide(motion);
    }
}

现在,角色平稳滑落。让我们在触摸方向键时向左右两侧行走。请记住,所使用的值(至少对于速度而言)是像素/秒。

这可以通过向左和向右按下来增加简单的步行支撑:

using Godot;
using System;

public class PhysicsScript : KinematicBody2D
{
    
    
    const float gravity = 200.0f;
    const int walkSpeed = 200;

    Vector2 velocity;

    public override void _PhysicsProcess(float delta)
    {
    
    
        velocity.y += delta * gravity;

        if (Input.IsActionPressed("ui_left"))
        {
    
    
            velocity.x = -walkSpeed;
        }
        else if (Input.IsActionPressed("ui_right"))
        {
    
    
            velocity.x = walkSpeed;
        }
        else
        {
    
    
            velocity.x = 0;
        }

        // We don't need to multiply velocity by delta because "MoveAndSlide" already takes delta time into account.

        // The second parameter of "MoveAndSlide" is the normal pointing up.
        // In the case of a 2D platformer, in Godot, upward is negative y, which translates to -1 as a normal.
        MoveAndSlide(velocity, new Vector2(0, -1));
    }
}

并尝试一下。

这是平台游戏的良好起点。可以在随引擎分发的演示zip或https://github.com/godotengine/godot-demo-projects/tree/master/2d/kinematic_character中找到更完整的演示 。

猜你喜欢

转载自blog.csdn.net/qq_44273429/article/details/111723406