File size: 3,561 Bytes
48ca417 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
use bevy::{
asset::{ AssetServer, Assets, Handle },
ecs::{ component::Component, system::Query },
math::{ IVec2, Vec2 },
render::texture::Image,
sprite::TextureAtlasLayout,
transform::components::Transform,
};
use bevy_ecs_ldtk::{
ldtk::{ LayerInstance, TilesetDefinition },
utils::ldtk_pixel_coords_to_translation_pivoted,
EntityInstance,
prelude::LdtkEntity,
prelude::LdtkFields,
};
use bevy_rapier2d::dynamics::Velocity;
#[derive(Clone, PartialEq, Debug, Default, Component)]
pub struct PredefinedPath {
pub points: Vec<Vec2>,
pub index: usize,
pub forward: bool,
}
impl LdtkEntity for PredefinedPath {
fn bundle_entity(
entity_instance: &EntityInstance,
layer_instance: &LayerInstance,
_: Option<&Handle<Image>>,
_: Option<&TilesetDefinition>,
_: &AssetServer,
_: &mut Assets<TextureAtlasLayout>
) -> PredefinedPath {
let mut points = Vec::new();
points.push(
ldtk_pixel_coords_to_translation_pivoted(
entity_instance.px,
layer_instance.c_hei * layer_instance.grid_size,
IVec2::new(entity_instance.width, entity_instance.height),
entity_instance.pivot
)
);
let ldtk_path_points = entity_instance
.iter_points_field("path")
.expect("path field should be correctly typed");
for ldtk_point in ldtk_path_points {
// The +1 is necessary here due to the pivot of the entities in the sample
// file.
// The paths set up in the file look flat and grounded,
// but technically they're not if you consider the pivot,
// which is at the bottom-center for the skulls.
let pixel_coords =
(ldtk_point.as_vec2() + Vec2::new(0.5, 1.0)) *
Vec2::splat(layer_instance.grid_size as f32);
points.push(
ldtk_pixel_coords_to_translation_pivoted(
pixel_coords.as_ivec2(),
layer_instance.c_hei * layer_instance.grid_size,
IVec2::new(entity_instance.width, entity_instance.height),
entity_instance.pivot
)
);
}
PredefinedPath {
points,
index: 1,
forward: true,
}
}
}
pub fn move_on_path(mut query: Query<(&mut Transform, &mut Velocity, &mut PredefinedPath)>) {
for (mut transform, mut velocity, mut path) in &mut query {
if path.points.len() <= 1 {
continue;
}
let mut new_velocity =
(path.points[path.index] - transform.translation.truncate()).normalize() * 20.0;
if new_velocity.dot(velocity.linvel) < 0.0 {
if path.index == 0 {
path.forward = true;
} else if path.index == path.points.len() - 1 {
path.forward = false;
}
transform.translation.x = path.points[path.index].x;
transform.translation.y = path.points[path.index].y;
if path.forward {
path.index += 1;
} else {
path.index -= 1;
}
new_velocity =
(path.points[path.index] - transform.translation.truncate()).normalize() * 20.0;
}
velocity.linvel = new_velocity;
}
}
|