Fix bunches of bugs and simplify map plugin.
This commit is contained in:
parent
0accbb4789
commit
03d963bed4
131
src/map.rs
131
src/map.rs
|
@ -82,8 +82,7 @@ impl ITileType for Tile {
|
|||
pub struct PortalBundle {
|
||||
pub portal: Portal,
|
||||
pub mappable: Mappable,
|
||||
pub transform: Transform,
|
||||
pub global_transform: GlobalTransform,
|
||||
pub transform: TransformBundle,
|
||||
}
|
||||
|
||||
#[derive(Bundle, Clone, Default)]
|
||||
|
@ -91,8 +90,75 @@ pub struct MapBundle<D: 'static + Clone + Default + Send + Sync> {
|
|||
pub map: Map<D>,
|
||||
pub spawn_colliders: SpawnColliders,
|
||||
pub spawn_portals: SpawnPortals,
|
||||
pub transform: Transform,
|
||||
pub global_transform: GlobalTransform,
|
||||
pub transform: TransformBundle,
|
||||
}
|
||||
|
||||
#[derive(Bundle, Clone, Debug)]
|
||||
pub struct TileBundle {
|
||||
pub transform: TransformBundle,
|
||||
pub collider: Collider,
|
||||
pub rigid_body: RigidBody,
|
||||
pub active_collision_types: ActiveCollisionTypes,
|
||||
pub map_obstruction: MapObstruction,
|
||||
}
|
||||
|
||||
impl Default for TileBundle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
transform: default(),
|
||||
collider: Collider::cuboid(0.5, 0.5),
|
||||
rigid_body: RigidBody::Fixed,
|
||||
active_collision_types: ActiveCollisionTypes::default()
|
||||
| ActiveCollisionTypes::KINEMATIC_STATIC
|
||||
| ActiveCollisionTypes::DYNAMIC_STATIC,
|
||||
map_obstruction: MapObstruction,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TileBundle {
|
||||
pub fn new(x: i32, y: i32) -> Self {
|
||||
Self {
|
||||
transform: Transform::from_xyz(x as f32 + 0.5, y as f32 + 0.5, 0.).into(),
|
||||
..default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Bundle, Clone, Debug)]
|
||||
pub struct ZoneBundle {
|
||||
pub collider: Collider,
|
||||
pub transform: TransformBundle,
|
||||
pub area: Area,
|
||||
pub zone: Zone,
|
||||
pub sensor: Sensor,
|
||||
pub active_events: ActiveEvents,
|
||||
}
|
||||
|
||||
impl ZoneBundle {
|
||||
fn new(collider: Collider, position: (f32, f32)) -> Self {
|
||||
let point = Isometry2::new(Vector2::new(position.0, position.1), 0.);
|
||||
let aabb = collider.raw.compute_aabb(&point);
|
||||
Self {
|
||||
collider,
|
||||
area: Area(aabb),
|
||||
transform: Transform::from_translation(Vec3::new(position.0, position.1, 0.)).into(),
|
||||
zone: default(),
|
||||
sensor: default(),
|
||||
active_events: ActiveEvents::COLLISION_EVENTS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&MRect> for ZoneBundle {
|
||||
fn from(rect: &MRect) -> Self {
|
||||
let collider = Collider::cuboid(
|
||||
rect.width() as f32 / 2. + 0.5,
|
||||
rect.height() as f32 / 2. + 0.5,
|
||||
);
|
||||
let position = (rect.center().x(), rect.center().y());
|
||||
Self::new(collider, position)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GridBuilder {
|
||||
|
@ -125,14 +191,13 @@ impl<D: Clone + Default> MapFilter<D> for GridBuilder {
|
|||
if let Ok(maze) =
|
||||
generator.generate(self.width_in_rooms as i32, self.height_in_rooms as i32)
|
||||
{
|
||||
let total_height = (self.room_height + 1) * self.height_in_rooms + 1;
|
||||
let total_height = self.room_height * self.height_in_rooms + self.height_in_rooms + 1;
|
||||
let half_width = self.room_width / 2;
|
||||
let half_height = self.room_height / 2;
|
||||
for y in 0..self.height_in_rooms {
|
||||
for x in 0..self.width_in_rooms {
|
||||
let x_offset = x * (self.room_width + 1);
|
||||
let y_offset =
|
||||
total_height - (y * (self.room_height + 1)) - self.room_height - 2;
|
||||
let y_offset = total_height - (y + 1) * (self.room_height + 1) - 1;
|
||||
let room = MRect::new_i32(
|
||||
x_offset as i32 + 1,
|
||||
y_offset as i32 + 1,
|
||||
|
@ -190,21 +255,7 @@ fn spawn_colliders<D: 'static + Clone + Default + Send + Sync>(
|
|||
for x in 0..map.width {
|
||||
if let Some(tile) = map.at(x, y) {
|
||||
if tile.blocks_motion() {
|
||||
let id = commands
|
||||
.spawn((
|
||||
RigidBody::Fixed,
|
||||
TransformBundle::from_transform(Transform::from_xyz(
|
||||
x as f32 + 0.5,
|
||||
y as f32 + 0.5,
|
||||
0.,
|
||||
)),
|
||||
Collider::cuboid(0.5, 0.5),
|
||||
ActiveCollisionTypes::default()
|
||||
| ActiveCollisionTypes::KINEMATIC_STATIC
|
||||
| ActiveCollisionTypes::DYNAMIC_STATIC,
|
||||
MapObstruction,
|
||||
))
|
||||
.id();
|
||||
let id = commands.spawn(TileBundle::new(x as i32, y as i32)).id();
|
||||
if tile.blocks_visibility() {
|
||||
commands.entity(id).insert(Visible::opaque());
|
||||
}
|
||||
|
@ -214,26 +265,8 @@ fn spawn_colliders<D: 'static + Clone + Default + Send + Sync>(
|
|||
}
|
||||
}
|
||||
for room in &map.rooms {
|
||||
let shape = Collider::cuboid(
|
||||
(room.width() / 2) as f32 + 0.5,
|
||||
(room.height() / 2) as f32 + 0.5,
|
||||
);
|
||||
let position =
|
||||
Isometry2::new(Vector2::new(room.center().x(), room.center().y()), 0.);
|
||||
let aabb = shape.raw.compute_aabb(&position);
|
||||
commands.entity(map_entity).with_children(|parent| {
|
||||
parent.spawn((
|
||||
TransformBundle::from_transform(Transform::from_xyz(
|
||||
position.translation.x,
|
||||
position.translation.y,
|
||||
0.,
|
||||
)),
|
||||
shape,
|
||||
Sensor,
|
||||
ActiveEvents::COLLISION_EVENTS,
|
||||
Area(aabb),
|
||||
Zone,
|
||||
));
|
||||
parent.spawn(ZoneBundle::from(room));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -248,21 +281,19 @@ fn spawn_portals<D: 'static + Clone + Default + Send + Sync>(
|
|||
if **spawn_portals {
|
||||
commands.entity(map_entity).remove::<SpawnPortals>();
|
||||
let mut portals: Vec<(f32, f32)> = vec![];
|
||||
for x in 1..map.width {
|
||||
for y in 1..map.height {
|
||||
let mut spawn_portal = false;
|
||||
if map.get_available_exits(x, y).len() > 2 {
|
||||
for x in 0..map.width {
|
||||
for y in 0..map.height {
|
||||
let idx = (x, y).to_index(map.width);
|
||||
if map.tiles[idx].is_walkable()
|
||||
&& (x > 1 && map.tiles[idx - 1].is_walkable())
|
||||
let mut spawn_portal = false;
|
||||
if map.get_available_exits(x, y).len() > 2 && map.tiles[idx].is_walkable() {
|
||||
if (x > 1 && map.tiles[idx - 1].is_walkable())
|
||||
&& (x < map.width - 2 && map.tiles[idx + 1].is_walkable())
|
||||
&& (y > 1 && map.tiles[idx - map.width].is_blocked())
|
||||
&& (y < map.height - 2 && map.tiles[idx + map.width].is_blocked())
|
||||
{
|
||||
spawn_portal = true;
|
||||
}
|
||||
if map.tiles[idx].is_walkable()
|
||||
&& (x > 1 && map.tiles[idx - 1].is_blocked())
|
||||
if (x > 1 && map.tiles[idx - 1].is_blocked())
|
||||
&& (x < map.width - 2 && map.tiles[idx + 1].is_blocked())
|
||||
&& (y > 1 && map.tiles[idx - map.width].is_walkable())
|
||||
&& (y < map.height - 2 && map.tiles[idx + map.width].is_walkable())
|
||||
|
@ -282,7 +313,7 @@ fn spawn_portals<D: 'static + Clone + Default + Send + Sync>(
|
|||
for (x, y) in portals {
|
||||
commands.entity(map_entity).with_children(|parent| {
|
||||
parent.spawn(PortalBundle {
|
||||
transform: Transform::from_translation(Vec3::new(x, y, 0.)),
|
||||
transform: Transform::from_translation(Vec3::new(x, y, 0.)).into(),
|
||||
..default()
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user