6个版本

0.2.4 2020年10月15日
0.2.3 2020年10月15日
0.1.0 2020年10月10日

#16 in #aa-bb

每月下载量26

MIT许可证

125KB
3K SLoC

physme

physme是一个简单的2D和3D游戏物理引擎,它不根据牛顿力学产生正确的结果,而是旨在提供令人满意的结果。该引擎的一个主要目标是提供一个非常简单且直观的API,以便任何人都能够快速入门游戏中的物理。这个目标的一部分是让2D和3D物理具有相同的API和相同的世界效果,但在不同的空间中。

该引擎仅支持静态和半动力学物体。静态物体不会移动,并且仅影响半动力学物体。半动力学物体可以移动,但方式在物理上不准确,但在屏幕上看起来不错。半动力学物体之所以被称为这样,是因为它们结合了来自其他物理引擎所知的运动学和动力学物体的特性。它们会受到力的作用,但同时也拥有自己设定的物理属性。

还包括三种类型的关节。

  • FixedJoint是最简单的关节。它只是用一个偏移和角度锁定目标物体,不考虑其他几何形状(忽略碰撞)。
  • MechanicalJoint类似于FixedJoint,但它考虑了其他几何形状(允许目标物体在碰撞中被位移)。MechanicalJoint还似乎提供了一些轻微的“缓冲”或弹簧效果。这是由于关节计算方式的问题。如果您需要真实的弹簧关节,请看下一点。
  • SpringJoint会随着时间的推移将目标物体“跳”到目标位置。这个时间可以通过rigidness值来控制。0.0的刚性意味着高弹力,目标物体进入位置所需的时间是某个高未指定的数字。1.0的刚性意味着低弹力,目标物体进入位置所需的时间是某个低数字,但比0.0或甚至f32::EPSILON(可能是100ms)要大。

这个引擎可能足以满足您下一个游戏快闪活动或您的个人项目。您可能不会用它来制作AAA游戏。

顺便说一下,它只与Bevy兼容。

快速入门

使用 physme 创建您的第一个游戏与添加一个物理插件一样简单。

use physme::prelude2d::*;

let mut builder = App::build();
builder
    .add_plugin(Physics2dPlugin);

可选地设置一些参数

    .add_resource(GlobalGravity(Vec2::new(0.0, -500.0)))
    .add_resource(GlobalFriction(0.90))
    .add_resource(GlobalStep(15.0));

然后在您的 setup 函数中,将一个 RigidBody 组件添加到您的实体中

fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    let icon = asset_server.load("assets/icon.png").unwrap();
    commands
        .spawn(SpriteComponents {
            material: materials.add(icon.into()),
            ..Default::default()
        })
        .with(
            RigidBody::new(Mass::Real(1.0))
                .with_status(Status::Semikinematic)
                .with_position(Vec2::new(0.0, 0.0))
                .with_terminal(Vec2::new(500.0, 1000.0)),
        );
}

以及一些具有任意数量的 Shape 组件的子实体。

        .with_children(|parent| {
            parent.spawn((Shape::from(Size::new(28.0, 28.0)),));
        });

就是这样!这将在游戏的每一帧执行所有物理更新。

如果您想向您的身体添加三种关节类型之一,您首先需要在创建实体时获取 Entity ID

let mut anchor = None;
let mut target = None;
    // (...)
    .spawn(...)
    .for_current_entity(|e| anchor = Some(e))
    // (...)
    .spawn(...)
    .for_current_entity(|e| target = Some(e))

然后创建一个带有关节组件的独立实体。

    // (...)
    .spawn((SpringJoint::new(anchor.unwrap(), target.unwrap())
        .with_offset(Vec2::new(50.0, 50.0)),))

关节将在提供的三个 joint_system 之一中进行计算。您还可以使用提供的 JointBehaviour 特性在 physme::dim2physme::dim3 中创建自定义关节,并将 joint_system::<B> 添加到其中,其中 B 是您的自定义行为。关节可以操纵位置、旋转、线性和角速度,并应用线性或角冲量。

依赖项

~252MB
~825K SLoC