8个版本

使用旧的Rust 2015

0.3.1 2018年4月28日
0.3.0 2017年11月19日
0.2.1 2017年3月21日
0.2.0 2017年1月6日
0.1.0 2016年3月31日

#680 in 游戏开发

每月47次下载

Apache-2.0

110KB
2K SLoC

collider-rs

Collider是一个用于游戏开发的连续2D碰撞检测的Rust库。

这是同一名称的Java库的后续版本。随着我的关注点从Java转向Rust,我将库进行了移植。

这个库的Rust包可以在这里找到。

文档

Collider的文档可以在这里找到。

描述

大多数游戏引擎都遵循定期更新所有形状的位置,并在时间冻结的快照中检查碰撞的方法。另一方面,连续碰撞检测意味着碰撞时间被非常精确地确定,用户不受固定时间步长方法的限制。Collider目前支持两种形状:圆形和矩形。用户指定这些形状的位置和速度,他们可以在任何时候更新这些形状,Collider将解决碰撞和分离的精确时间。

连续碰撞检测相对于传统方法具有一定的优势。在游戏引擎中,精灵的位置可能会更新以重叠墙壁,而在传统的碰撞检测系统中,则需要进行后校正以确保精灵不会出现在墙壁内部。在连续碰撞检测中,由于已知精灵接触墙壁的精确时间和位置,因此不需要这样做。传统碰撞检测可能会出现“隧道”问题,其中快速的小物体撞上狭窄的墙壁,碰撞检测未能检测到,或者两个快速的小物体直接穿过对方,碰撞检测也未能检测到。这也不是连续碰撞检测的问题。也有争议认为,在某些情况下,连续碰撞检测可能更有效,因为击中框可能不需要频繁更新,但仍能保持平滑的外观。

示例

use collider::{Collider, HbEvent, HbId, HbProfile};
use collider::geom::{Shape, v2};

#[derive(Copy, Clone, Debug)]
struct DemoHbProfile { id: HbId } // add any additional identfying data to this struct

impl HbProfile for DemoHbProfile {
    fn id(&self) -> HbId { self.id }
    fn can_interact(&self, _other: &DemoHbProfile) -> bool { true }
    fn cell_width() -> f64 { 4.0 }
    fn padding() -> f64 { 0.01 }
}

let mut collider: Collider<DemoHbProfile> = Collider::new();

let hitbox = Shape::square(2.0).place(v2(-10.0, 0.0)).moving(v2(1.0, 0.0));
let overlaps = collider.add_hitbox(DemoHbProfile { id: 0 }, hitbox);
assert!(overlaps.is_empty());

let hitbox = Shape::square(2.0).place(v2(10.0, 0.0)).moving(v2(-1.0, 0.0));
let overlaps = collider.add_hitbox(DemoHbProfile { id: 1 }, hitbox);
assert!(overlaps.is_empty());

while collider.time() < 20.0 {
    let time = collider.next_time().min(20.0);
    collider.set_time(time);
    if let Some((event, profile_1, profile_2)) = collider.next() {
        println!("{:?} between {:?} and {:?} at time {}.",
                 event, profile_1, profile_2, collider.time());
        if event == HbEvent::Collide {
            println!("Speed of collided hitboxes is halved.");
            for profile in [profile_1, profile_2].iter() {
                let mut hb_vel = collider.get_hitbox(profile.id()).vel;
                hb_vel.value *= 0.5;
                collider.set_hitbox_vel(profile.id(), hb_vel);
            }
        }
    }
}

// the above loop prints the following events:
//   Collide between DemoHbProfile { id: 0 } and DemoHbProfile { id: 1 } at time 9.
//   Speed of collided hitboxes is halved.
//   Separate between DemoHbProfile { id: 0 } and DemoHbProfile { id: 1 } at time 13.01.

主页

Collider的主页在我的个人网站上:http://www.matthewmichelotti.com/projects/collider/

许可

Collider遵循Apache 2.0 许可证

期待

(注:本节针对已经熟悉此库的人。)

在更远的未来,或者如果需求很高,可能会添加一些新功能。

  • 将直角三角形添加到可能形状的集合中。(注:我并不打算添加通用多边形)

依赖项