Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: update to bevy 0.8 and bevy_ecs_tilemap rewrite #106

Merged
merged 41 commits into from
Aug 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
cec126a
depend on bevy_ecs_tilemap's rewrite branch
Trouv Jul 29, 2022
b5c6f0f
update non-system code to rewrite
Trouv Jul 29, 2022
d15418c
refactor: update non-level-spawning systems to rewrite
Trouv Jul 29, 2022
322c843
refactor: update some level spawn methods, including background color…
Trouv Jul 30, 2022
dbda54b
refactor: update 'settings'-related tilemap code for level spawning t…
Trouv Jul 30, 2022
ea7eea2
refactor: update tile makers to rewrite
Trouv Jul 30, 2022
7514305
refactor: update set_all_tiles_with_func to rewrite
Trouv Jul 30, 2022
d13be19
fix: a couple small fixes in tile_makers.rs
Trouv Jul 30, 2022
3725d86
refactor: start updating level spawn code
Trouv Aug 4, 2022
eef932e
refactor: update spawning for IntGrid layers to rewrite
Trouv Aug 4, 2022
2316913
refactor: update spawning of Tile and AutoTile layers to rewrite
Trouv Aug 4, 2022
9562bb4
refactor: finish update to level spawning logic for rewrite
Trouv Aug 4, 2022
5684669
fix: update implementation of From<TilePos> for GridCoords to rewrite
Trouv Aug 4, 2022
53036ec
chore: remove unused imports
Trouv Aug 4, 2022
bc7ab2a
refactor: add TilePos2dMap to step in for HashMap<TilePos, ..> in til…
Trouv Aug 5, 2022
22b5b0e
test: update tile_maker tests to rewrite
Trouv Aug 5, 2022
5684665
fix: various fixes for rewrite..
Trouv Aug 5, 2022
42b8d58
refactor: move GridCoords and TilePos insertion to tile maker combinator
Trouv Aug 7, 2022
cacc401
Update Bevy and bevy_ecs_tilemap deps, temporarily knock out heron de…
nfagerlund Aug 7, 2022
f80248e
Add new offset arg to TextureAtlas::from_grid_with_padding
nfagerlund Aug 7, 2022
bc097f8
Update a bunch of renamed types that used to have "2d" in their names
nfagerlund Aug 7, 2022
c089faf
Remove uses of Tilemap2dTextureSize
nfagerlund Aug 7, 2022
6bb90e0
Updates for hierarchy commandification
nfagerlund Aug 7, 2022
c1ced35
Add `bevy_sprite` feature dependency
nfagerlund Aug 7, 2022
f70a784
Updates for inherited visibility
nfagerlund Aug 8, 2022
1bfe05f
Fix `basic` example
nfagerlund Aug 8, 2022
3764212
Merge pull request #104 from nfagerlund/nf/aug22-tilemap-rewrite-help
Trouv Aug 8, 2022
638ced5
docs: update examples to bevy 0.8, other than platformer
Trouv Aug 9, 2022
2469230
chore: run cargo fmt
Trouv Aug 9, 2022
9396e9a
refactor: address compiler warnings
Trouv Aug 9, 2022
80cef2f
chore: fix clippy issues
Trouv Aug 9, 2022
526ec93
refactor: give all tile entities spatial bundles, along with the laye…
Trouv Aug 10, 2022
2060140
fix: generate new layer_entity within layered_grid_tiles loop
Trouv Aug 10, 2022
e0858a0
docs: update platformer example to rewrite/0.8
Trouv Aug 10, 2022
21adaa7
docs: adjust comments in spawn_wall_collision system
Trouv Aug 10, 2022
8bd7abf
docs: update getting started example to bevy 0.8
Trouv Aug 10, 2022
32f4b2c
docs: update a few more pieces of docs for rewrite changes
Trouv Aug 10, 2022
9bb0bd8
refactor: remove set_ldtk_texture_filters_to_nearest
Trouv Aug 11, 2022
c42f890
refactor: rename insert_spatial_bundle_for_layer_tiles
Trouv Aug 11, 2022
e10e0bf
fix: make TilemapGridSize nonzero for IntGrid layers w/o AutoTile rules
Trouv Aug 11, 2022
056a4e3
fix: resolve de/spawning redundancies between new LDtk entites and ne…
Trouv Aug 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
908 changes: 485 additions & 423 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ exclude = ["assets/*", "repo/*", "scripts/*"]

[dependencies]
bevy_ecs_ldtk_macros = { version = "0.3", optional = true, path = "macros" }
bevy_ecs_tilemap = "0.6"
bevy = { version = "0.7", default-features = false }
bevy_ecs_tilemap = { version = "0.7.0" }
bevy = { version = "0.8", default-features = false, features = ["bevy_sprite"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
regex = "1.5"
regex = "1"
hex = "0.4"
anyhow = "1.0"
thiserror = "1.0"

[dev-dependencies]
bevy = "0.7"
heron = { version = "3.0", features = ["2d"] }
bevy = "0.8"
heron = { version = "4.0.0-alpha.4", features = ["2d"] }
rand = "0.8"

[features]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() {
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());

commands.spawn_bundle(LdtkWorldBundle {
ldtk_handle: asset_server.load("my_project.ldtk"),
Expand Down
5 changes: 3 additions & 2 deletions examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use bevy::prelude::*;
use bevy::{prelude::*, render::texture::ImageSettings};
use bevy_ecs_ldtk::prelude::*;

fn main() {
App::new()
.insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites
.add_plugins(DefaultPlugins)
.add_plugin(LdtkPlugin)
.add_startup_system(setup)
Expand All @@ -12,7 +13,7 @@ fn main() {
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());

commands.spawn_bundle(LdtkWorldBundle {
ldtk_handle: asset_server.load("my_project.ldtk"),
Expand Down
2 changes: 1 addition & 1 deletion examples/field_instances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() {
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());

asset_server.watch_for_changes().unwrap();

Expand Down
2 changes: 1 addition & 1 deletion examples/level_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const LEVEL_IIDS: [&str; 8] = [
];

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());

let iids: HashSet<String> = LEVEL_IIDS.into_iter().map(|s| s.to_string()).collect();

Expand Down
3 changes: 2 additions & 1 deletion examples/platformer/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This example shows off a more in-depth implementation of a game with `bevy_ecs_ldtk`.
// Please run with `--release`.

use bevy::prelude::*;
use bevy::{prelude::*, render::texture::ImageSettings};
use bevy_ecs_ldtk::prelude::*;

use heron::prelude::*;
Expand All @@ -11,6 +11,7 @@ mod systems;

fn main() {
App::new()
.insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites
.add_plugins(DefaultPlugins)
.add_plugin(LdtkPlugin)
.add_plugin(PhysicsPlugin::default())
Expand Down
115 changes: 67 additions & 48 deletions examples/platformer/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet};
use heron::prelude::*;

pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let camera = OrthographicCameraBundle::new_2d();
let camera = Camera2dBundle::default();
commands.spawn_bundle(camera);

asset_server.watch_for_changes().unwrap();
Expand Down Expand Up @@ -105,16 +105,31 @@ pub fn spawn_wall_collision(
right: i32,
}

// consider where the walls are
/// A simple rectangle type representing a wall of any size
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Hash)]
struct Rect {
left: i32,
right: i32,
top: i32,
bottom: i32,
}

// Consider where the walls are
// storing them as GridCoords in a HashSet for quick, easy lookup
//
// The key of this map will be the entity of the level the wall belongs to.
// This has two consequences in the resulting collision entities:
// 1. it forces the walls to be split along level boundaries
// 2. it lets us easily add the collision entities as children of the appropriate level entity
let mut level_to_wall_locations: HashMap<Entity, HashSet<GridCoords>> = HashMap::new();

wall_query.for_each(|(&grid_coords, &Parent(parent))| {
// the intgrid tiles' direct parents will be bevy_ecs_tilemap chunks, not the level
// To get the level, you need their grandparents, which is where parent_query comes in
if let Ok(&Parent(level_entity)) = parent_query.get(parent) {
wall_query.for_each(|(&grid_coords, parent)| {
// An intgrid tile's direct parent will be a layer entity, not the level entity
// To get the level entity, you need the tile's grandparent.
// This is where parent_query comes in.
if let Ok(grandparent) = parent_query.get(parent.get()) {
level_to_wall_locations
.entry(level_entity)
.entry(grandparent.get())
.or_insert(HashSet::new())
.insert(grid_coords);
}
Expand Down Expand Up @@ -165,15 +180,15 @@ pub fn spawn_wall_collision(
}

// combine "plates" into rectangles across multiple rows
let mut wall_rects: Vec<Rect<i32>> = Vec::new();
let mut previous_rects: HashMap<Plate, Rect<i32>> = HashMap::new();
let mut wall_rects: Vec<Rect> = Vec::new();
let mut previous_rects: HashMap<Plate, Rect> = HashMap::new();

// an extra empty row so the algorithm "terminates" the rects that touch the top
// edge
plate_stack.push(Vec::new());

for (y, row) in plate_stack.iter().enumerate() {
let mut current_rects: HashMap<Plate, Rect<i32>> = HashMap::new();
let mut current_rects: HashMap<Plate, Rect> = HashMap::new();
for plate in row {
if let Some(previous_rect) = previous_rects.remove(plate) {
current_rects.insert(
Expand Down Expand Up @@ -201,38 +216,41 @@ pub fn spawn_wall_collision(
previous_rects = current_rects;
}

// spawn colliders for every rectangle
for wall_rect in wall_rects {
commands
.spawn()
.insert(CollisionShape::Cuboid {
half_extends: Vec3::new(
(wall_rect.right as f32 - wall_rect.left as f32 + 1.)
* grid_size as f32
commands.entity(level_entity).with_children(|level| {
// Spawn colliders for every rectangle..
// Making the collider a child of the level serves two purposes:
// 1. Adjusts the transforms to be relative to the level for free
// 2. the colliders will be despawned automatically when levels unload
for wall_rect in wall_rects {
level
.spawn()
.insert(CollisionShape::Cuboid {
half_extends: Vec3::new(
(wall_rect.right as f32 - wall_rect.left as f32 + 1.)
* grid_size as f32
/ 2.,
(wall_rect.top as f32 - wall_rect.bottom as f32 + 1.)
* grid_size as f32
/ 2.,
0.,
),
border_radius: None,
})
.insert(RigidBody::Static)
.insert(PhysicMaterial {
friction: 0.1,
..Default::default()
})
.insert(Transform::from_xyz(
(wall_rect.left + wall_rect.right + 1) as f32 * grid_size as f32
/ 2.,
(wall_rect.top as f32 - wall_rect.bottom as f32 + 1.)
* grid_size as f32
(wall_rect.bottom + wall_rect.top + 1) as f32 * grid_size as f32
/ 2.,
0.,
),
border_radius: None,
})
.insert(RigidBody::Static)
.insert(PhysicMaterial {
friction: 0.1,
..Default::default()
})
.insert(Transform::from_xyz(
(wall_rect.left + wall_rect.right + 1) as f32 * grid_size as f32 / 2.,
(wall_rect.bottom + wall_rect.top + 1) as f32 * grid_size as f32 / 2.,
0.,
))
.insert(GlobalTransform::default())
// Making the collider a child of the level serves two purposes:
// 1. Adjusts the transforms to be relative to the level for free
// 2. the colliders will be despawned automatically when levels unload
.insert(Parent(level_entity));
}
))
.insert(GlobalTransform::default());
}
});
}
});
}
Expand Down Expand Up @@ -407,18 +425,19 @@ pub fn update_level_selection(
) {
for (level_handle, level_transform) in level_query.iter() {
if let Some(ldtk_level) = ldtk_levels.get(level_handle) {
let level_bounds = Rect {
bottom: level_transform.translation.y,
top: level_transform.translation.y + ldtk_level.level.px_hei as f32,
left: level_transform.translation.x,
right: level_transform.translation.x + ldtk_level.level.px_wid as f32,
let level_bounds = bevy::sprite::Rect {
min: Vec2::new(level_transform.translation.x, level_transform.translation.y),
max: Vec2::new(
level_transform.translation.x + ldtk_level.level.px_wid as f32,
level_transform.translation.y + ldtk_level.level.px_hei as f32,
),
};

for player_transform in player_query.iter() {
if player_transform.translation.x < level_bounds.right
&& player_transform.translation.x > level_bounds.left
&& player_transform.translation.y < level_bounds.top
&& player_transform.translation.y > level_bounds.bottom
if player_transform.translation.x < level_bounds.max.x
&& player_transform.translation.x > level_bounds.min.x
&& player_transform.translation.y < level_bounds.max.y
&& player_transform.translation.y > level_bounds.min.y
&& !level_selection.is_match(&0, &ldtk_level.level)
{
*level_selection = LevelSelection::Iid(ldtk_level.level.iid.clone());
Expand Down
5 changes: 3 additions & 2 deletions examples/traitless.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Roughly equivalent to the "basic" example, except it doesn't use the LdtkEntity convenience
// trait. As a result, you can run this example with --no-default-features

use bevy::prelude::*;
use bevy::{prelude::*, render::texture::ImageSettings};
use bevy_ecs_ldtk::prelude::*;

fn main() {
App::new()
.insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites
.add_plugins(DefaultPlugins)
.add_plugin(LdtkPlugin)
.add_startup_system(setup)
Expand All @@ -15,7 +16,7 @@ fn main() {
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(Camera2dBundle::default());

commands.spawn_bundle(LdtkWorldBundle {
ldtk_handle: asset_server.load("my_project.ldtk"),
Expand Down
1 change: 1 addition & 0 deletions macros/src/ldtk_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ fn expand_sprite_sheet_bundle_attribute(
asset_server.load(#asset_path).into(),
bevy::prelude::Vec2::new(#tile_width, #tile_height),
#columns, #rows, bevy::prelude::Vec2::splat(#padding),
Vec2::ZERO,
)
),
sprite: bevy::prelude::TextureAtlasSprite {
Expand Down
2 changes: 1 addition & 1 deletion src/app/ldtk_int_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub trait LdtkIntCell {
/// Note: whether or not the entity is registered to the app, the plugin will insert [Transform],
/// [GlobalTransform], and [Parent] components to the entity **after** this bundle is inserted.
/// So, any custom implementations of these components within this trait will be overwritten.
/// Furthermore, a [bevy_ecs_tilemap::TileBundle] will be inserted **before** this bundle, so
/// Furthermore, a [bevy_ecs_tilemap::tiles::TileBundle] will be inserted **before** this bundle, so
/// be careful not to overwrite the components provided by that bundle.
fn bundle_int_cell(int_grid_cell: IntGridCell, layer_instance: &LayerInstance) -> Self;
}
Expand Down
40 changes: 18 additions & 22 deletions src/components.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! [Component]s and [Bundle]s used by the plugin.

pub use crate::ldtk::{EntityInstance, LayerInstance, Type};
pub use crate::ldtk::EntityInstance;
use crate::ldtk::{LayerInstance, Type};
use bevy::prelude::*;

use std::{
Expand All @@ -16,10 +17,7 @@ use crate::{
utils::ldtk_grid_coords_to_grid_coords,
};

use bevy_ecs_tilemap::{TileBundle, TileBundleTrait, TileParent, TilePos};

#[allow(unused_imports)]
use bevy_ecs_tilemap::Map;
use bevy_ecs_tilemap::tiles::{TileBundle, TilePos};

/// [Component] added to any `IntGrid` tile by default.
///
Expand Down Expand Up @@ -118,15 +116,15 @@ impl From<GridCoords> for IVec2 {
impl From<TilePos> for GridCoords {
fn from(tile_pos: TilePos) -> Self {
GridCoords {
x: tile_pos.0 as i32,
y: tile_pos.1 as i32,
x: tile_pos.x as i32,
y: tile_pos.y as i32,
}
}
}

impl From<GridCoords> for TilePos {
fn from(grid_coords: GridCoords) -> Self {
TilePos(grid_coords.x as u32, grid_coords.y as u32)
TilePos::new(grid_coords.x as u32, grid_coords.y as u32)
}
}

Expand Down Expand Up @@ -315,23 +313,13 @@ impl From<&LayerInstance> for LayerMetadata {
}
}

#[derive(Clone, Default, Bundle)]
#[derive(Copy, Clone, Debug, Default, Bundle)]
pub(crate) struct TileGridBundle {
#[bundle]
pub tile_bundle: TileBundle,
pub grid_coords: GridCoords,
}

impl TileBundleTrait for TileGridBundle {
fn get_tile_pos_mut(&mut self) -> &mut TilePos {
self.tile_bundle.get_tile_pos_mut()
}

fn get_tile_parent(&mut self) -> &mut TileParent {
self.tile_bundle.get_tile_parent()
}
}

#[derive(Clone, Default, Bundle)]
pub(crate) struct IntGridCellBundle {
pub int_grid_cell: IntGridCell,
Expand All @@ -347,13 +335,21 @@ pub(crate) struct EntityInstanceBundle {
/// After the ldtk file is done loading, the levels you've chosen with [LevelSelection] or
/// [LevelSet] will begin to spawn.
/// Each level is its own entity, with the [LdtkWorldBundle] as its parent.
/// Each level has `Handle<LdtkLevel>`, [Map], [Transform], and [GlobalTransform] components.
/// Finally, all tiles and entities in the level are spawned as children to the level unless marked
/// by a [Worldly] component.
/// Each level has a `Handle<LdtkLevel>` component.
///
/// All non-Entity layers (IntGrid, Tile, and AutoTile) will also spawn as their own entities.
/// Each layer's parent will be the level entity.
/// Each layer will have a [LayerMetadata] component, and are [bevy_ecs_tilemap::TilemapBundle]s.
/// Each tile in these layers will have the layer entity as its parent.
///
/// For Entity layers, all LDtk entities in the level are spawned as children to the level entity,
/// unless marked by a [Worldly] component.
#[derive(Clone, Default, Bundle)]
pub struct LdtkWorldBundle {
pub ldtk_handle: Handle<crate::assets::LdtkAsset>,
pub level_set: LevelSet,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub visibility: Visibility,
pub computed_visibility: ComputedVisibility,
}