3 个 版 本
0.1.2 | 2024 年 7 月 25 日 |
---|---|
0.1.1 | 2024 年 7 月 25 日 |
0.1.0 | 2024 年 7 月 25 日 |
#719 in 游 戏 开 发
在 2 库 中使用
135KB
3K SLoC
网站
建设中 🚧
该项目仍在建设中,处于预发布阶段。可能会进行重大更改,可能会破坏某些功能。我们为此带来的不便表示歉意。
易用性
这个项目的想法是使其使用起来非常直观,以至于可以通过这个游 戏 引擎学习 Rust。当你可以制作出可交互的东 西,而不是仅仅操作数据时,学习通常会更好,我们希望在 Rust 中提供这种机会。
操作系统 支持
大多数主要操作系 统 应该 支持,然而只有 Windows 已经经过测试。
当前功能
有关计划中或已完成的功能的完整列表,请访问 这里
渲染器
物理 引擎
使用 Rapier 进行物理,并可作为资源访问碰撞信息。
一个简单的 平 台 游 戏 示例
use ABC_Game_Engine::physics::rapier2d::geometry::Ray;
use ABC_Game_Engine::physics::rapier2d::math::Real;
use ABC_Game_Engine::physics::rapier2d::na as nalgebra;
use ABC_Game_Engine::physics::rapier2d::na::vector;
use ABC_Game_Engine::prelude::*;
use ABC_lumenpyx::prelude::*;
struct Player;
struct Ground;
struct PlayerController {
speed: f32,
jump_force: f32,
}
impl System for PlayerController {
fn run(&mut self, entities_and_components: &mut EntitiesAndComponents) {
let player_entity;
let (player_x, player_y) = {
let player_entities = entities_and_components
.get_entities_with_component::<Player>()
.cloned()
.collect::<Vec<Entity>>();
player_entity = player_entities[0];
let (transform,) =
entities_and_components.get_components::<(Transform,)>(player_entity);
(transform.x, transform.y)
};
let delta_time: f32;
let mut normalized_dir = [0.0 as f32; 2];
{
delta_time = entities_and_components
.get_resource::<DeltaTime>()
.expect("Failed to get DeltaTime resource")
.get_delta_time() as f32;
let physics_info = entities_and_components
.get_resource::<RapierPhysicsInfo>()
.expect("Failed to get PhysicsInfo resource");
let input = entities_and_components.get_resource::<Input>().unwrap();
if input.get_key_state(KeyCode::A) == KeyState::Held {
normalized_dir[0] -= 1.0;
}
if input.get_key_state(KeyCode::D) == KeyState::Held {
normalized_dir[0] += 1.0;
}
let is_ground_check = |collider_handle: ColliderHandle, _: &Collider| {
let entity = physics_info
.get_associated_entity_with_collider_handle(collider_handle.into())
.expect("Failed to get associated entity with collider handle");
entities_and_components
.try_get_components::<(Ground,)>(entity)
.0
.is_some()
};
let is_ground_filter = QueryFilter {
predicate: Some(&is_ground_check),
..Default::default()
};
let intersection = physics_info.cast_ray(
&Ray::new(
vector![player_x as f32, player_y as f32 - 5.01].into(),
vector![0.0, -1.0],
),
Real::MAX,
true,
is_ground_filter,
);
if input.get_key_state(KeyCode::Space) == KeyState::Pressed && intersection.is_some() {
let intersection = intersection.unwrap();
if intersection.1 < 0.01 {
normalized_dir[1] = 1.0;
}
}
}
if let (Some(_), Some(_), Some(rigid_body)) = entities_and_components
.try_get_components_mut::<(Player, Transform, RigidBody)>(player_entity)
{
rigid_body.apply_impulse(
vector![
normalized_dir[0] * self.speed * delta_time,
normalized_dir[1] * self.jump_force,
],
true,
);
}
}
}
fn main() {
let mut scene = Scene::new();
let mut lumenpyx_eventloop =
LumenpyxEventLoop::new(&mut scene.world, [160, 160], "Platformer Example");
lumenpyx_eventloop.set_render_settings(
&mut scene.world,
RenderSettings::default()
.with_reflections(false)
.with_shadows(false),
);
{
let entities_and_components = &mut scene.world.entities_and_components;
let camera = Camera::new();
entities_and_components.add_entity_with((camera, Transform::default()));
let ball = Circle::new([1.0, 1.0, 1.0, 1.0], 5.0);
let circle_collider = ColliderBuilder::ball(5.0).build();
let circle_rb = RigidBodyBuilder::dynamic().additional_mass(1.0).build();
entities_and_components.add_entity_with((
ball,
Transform {
x: -20.0,
y: -20.0,
z: 0.0,
rotation: 0.0,
scale: 1.0,
origin_x: 0.0,
origin_y: 0.0,
},
circle_rb,
circle_collider,
Player {},
));
let ground_collider = ColliderBuilder::cuboid(160.0, 5.0).build();
let ground_rb = RigidBodyBuilder::fixed().build();
let ground_rect = Rectangle::new([0.0, 1.0, 1.0, 1.0], 160.0, 10.0);
entities_and_components.add_entity_with((
ground_rect,
Transform {
x: 0.0,
y: -80.0,
z: 0.0,
rotation: 0.0,
scale: 1.0,
origin_x: 0.0,
origin_y: 0.0,
},
ground_collider,
ground_rb,
Ground {},
));
}
scene.world.add_system(PlayerController {
speed: 1000.0,
jump_force: 3000.0,
});
physics::add_default_physics_systems(&mut scene.world);
let physics_info = scene
.world
.entities_and_components
.get_resource_mut::<RapierPhysicsInfo>();
physics_info
.expect("Failed to get PhysicsInfo resource")
.set_gravity([0.0, -9.81 * 4.0].into());
lumenpyx_eventloop.run(&mut scene.world, |world| {
world.run();
render(&mut world.entities_and_components);
});
}
依 赖 项
~14–47MB
~761K SLoC