generated from 2ndbeam/bevy-template
feat: Updated tilemap bundle
- Layout is now defined from bottom left corner - Added rotation to lockpick bundle - Added level TOML structures that match current level
This commit is contained in:
parent
0e18bb6df5
commit
24153e476f
7 changed files with 225 additions and 72 deletions
110
assets/levels/level.toml
Normal file
110
assets/levels/level.toml
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
[[tiles.floors]]
|
||||
x = 0
|
||||
y = 0
|
||||
w = 16
|
||||
|
||||
[[tiles.floors]]
|
||||
x = 0
|
||||
y = 4
|
||||
w = 16
|
||||
|
||||
[[tiles.floors]]
|
||||
x = 0
|
||||
y = 8
|
||||
w = 16
|
||||
|
||||
[[tiles.walls]]
|
||||
x = 0
|
||||
y = 1
|
||||
h = 3
|
||||
|
||||
[[tiles.walls]]
|
||||
x = 0
|
||||
y = 5
|
||||
h = 3
|
||||
|
||||
[[tiles.walls]]
|
||||
x = 15
|
||||
y = 1
|
||||
h = 3
|
||||
|
||||
[[tiles.walls]]
|
||||
x = 15
|
||||
y = 5
|
||||
h = 3
|
||||
|
||||
[[tiles.wall_connectors]]
|
||||
x = 4
|
||||
y = 3
|
||||
|
||||
[[tiles.wall_connectors]]
|
||||
x = 4
|
||||
y = 7
|
||||
|
||||
[[tiles.wall_connectors]]
|
||||
x = 11
|
||||
y = 3
|
||||
|
||||
[[tiles.wall_connectors]]
|
||||
x = 11
|
||||
y = 7
|
||||
|
||||
[interactive.player]
|
||||
x = 1
|
||||
y = 1
|
||||
|
||||
[[interactive.doors]]
|
||||
x = 4
|
||||
y = 1
|
||||
facing = "right"
|
||||
|
||||
[[interactive.doors]]
|
||||
x = 4
|
||||
y = 5
|
||||
facing = "right"
|
||||
lock = "right"
|
||||
|
||||
[[interactive.doors]]
|
||||
x = 11
|
||||
y = 1
|
||||
facing = "left"
|
||||
lock = "left"
|
||||
|
||||
[[interactive.doors]]
|
||||
x = 11
|
||||
y = 1
|
||||
facing = "left"
|
||||
|
||||
[[interactive.stairs]]
|
||||
x = 8
|
||||
y = 1
|
||||
floors = 2
|
||||
|
||||
[[interactive.containers]]
|
||||
x = 2
|
||||
y = 1
|
||||
|
||||
[[interactive.containers]]
|
||||
x = 14
|
||||
y = 1
|
||||
|
||||
[[interactive.containers]]
|
||||
x = 2
|
||||
y = 5
|
||||
w = 4
|
||||
h = 4
|
||||
|
||||
[interactive.containers.items]
|
||||
id = "lockpick"
|
||||
x = 2
|
||||
y = 2
|
||||
|
||||
[[interactive.containers]]
|
||||
x = 14
|
||||
y = 5
|
||||
w = 2
|
||||
h = 2
|
||||
|
||||
[interactive.containers.items]
|
||||
id = "lockpick"
|
||||
rotated = true
|
||||
48
assets/levels/level_alt.toml
Normal file
48
assets/levels/level_alt.toml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
[tiles]
|
||||
floors = [
|
||||
{ x = 0, y = 0, w = 16 },
|
||||
{ x = 0, y = 4, w = 16 },
|
||||
{ x = 0, y = 8, w = 16 },
|
||||
]
|
||||
walls = [
|
||||
{ x = 0, y = 1, h = 3 },
|
||||
{ x = 0, y = 5, h = 3 },
|
||||
{ x = 15, y = 1, h = 3 },
|
||||
{ x = 15, y = 5, h = 3 },
|
||||
]
|
||||
wall_connectors = [
|
||||
{ x = 4, y = 3 },
|
||||
{ x = 4, y = 7 },
|
||||
{ x = 11, y = 3 },
|
||||
{ x = 11, y = 7 },
|
||||
]
|
||||
|
||||
[interactive]
|
||||
player = { x = 1, y = 1 }
|
||||
doors = [
|
||||
{ x = 4, y = 1, facing = "right" },
|
||||
{ x = 4, y = 5, facing = "right", lock = "right" },
|
||||
{ x = 11, y = 1, facing = "left", lock = "left" },
|
||||
{ x = 11, y = 5, facing = "left" },
|
||||
]
|
||||
stairs = [
|
||||
{ x = 8, y = 1, floors = 2 },
|
||||
]
|
||||
containers = [
|
||||
{ x = 2, y = 1 },
|
||||
{ x = 14, y = 1 },
|
||||
{
|
||||
x = 2, y = 5,
|
||||
w = 4, h = 4,
|
||||
items = [
|
||||
{ id = "lockpick", x = 2, y = 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
x = 14, y = 5,
|
||||
w = 2, h = 2,
|
||||
items = [
|
||||
{ id = "lockpick", rotated = true },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
@ -9,10 +9,14 @@ const LOCKPICK_SPRITE: &'static str = "sprites/items/lockpick.png";
|
|||
#[require(Item)]
|
||||
pub struct Lockpick;
|
||||
|
||||
pub fn lockpick_bundle(asset_server: &Res<AssetServer>, position: UVec2) -> impl Bundle {
|
||||
pub fn lockpick_bundle(asset_server: &Res<AssetServer>, position: UVec2, rotated: bool) -> impl Bundle {
|
||||
let image = asset_server.load(LOCKPICK_SPRITE);
|
||||
let mut item = Item::new(uvec2(1, 1), position);
|
||||
if rotated {
|
||||
item.rotate();
|
||||
}
|
||||
(
|
||||
Item::new(uvec2(1, 1), position),
|
||||
item,
|
||||
ItemData {
|
||||
image,
|
||||
name: "Lockpick".into(),
|
||||
|
|
|
|||
1
src/layout/asset.rs
Normal file
1
src/layout/asset.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
pub mod asset;
|
||||
pub mod container;
|
||||
pub mod door;
|
||||
pub mod lock;
|
||||
|
|
|
|||
|
|
@ -78,80 +78,66 @@ pub fn setup_world(
|
|||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
// floor 1F
|
||||
let mut tiles = (0..16).map(|x| {
|
||||
(0, uvec2(x, 1))
|
||||
}).collect::<Vec<(u16, UVec2)>>();
|
||||
let tiles = [
|
||||
( 0, ( 0, 0, 16, 1 )), // 1F floor
|
||||
( 0, ( 0, 4, 16, 1 )), // 1F ceiling / 2F floor
|
||||
( 0, ( 0, 8, 16, 1 )), // 2F ceiling
|
||||
|
||||
// floor/ceil 1-2F
|
||||
tiles.extend((0..16).map(|x| {
|
||||
(0, uvec2(x, 5))
|
||||
}));
|
||||
( 1, ( 0, 1, 1, 3 )), // 1F left wall
|
||||
( 1, ( 0, 5, 1, 3 )), // 2F left wall
|
||||
( 1, ( 15, 1, 1, 3 )), // 1F right wall
|
||||
( 1, ( 15, 5, 1, 3 )), // 2F right wall
|
||||
|
||||
// ceil 2F
|
||||
tiles.extend((0..16).map(|x| {
|
||||
(0, uvec2(x, 9))
|
||||
}));
|
||||
( 2, ( 4, 3, 1, 1 )), // 1F left door connector
|
||||
( 2, ( 4, 7, 1, 1 )), // 2F left door connector
|
||||
( 2, ( 11, 3, 1, 1 )), // 1F right door connector
|
||||
( 2, ( 11, 7, 1, 1 )), // 2F right door connector
|
||||
].into_iter().map(|(id, (x, y, w, h))| {
|
||||
(id, URect::from_corners(uvec2(x, y), uvec2(x + w - 1, y + h - 1)))
|
||||
}).collect::<Vec<(u16, URect)>>();
|
||||
|
||||
// walls
|
||||
tiles.extend([
|
||||
(0, 4), (0, 3), (0, 2),
|
||||
(0, 8), (0, 7), (0, 6),
|
||||
(15, 4), (15, 3), (15, 2),
|
||||
(15, 8), (15, 7), (15, 6),
|
||||
].iter().map(|(x, y)| {
|
||||
(1, uvec2(*x, *y))
|
||||
}));
|
||||
commands.spawn(tilemap::tilemap_bundle(&asset_server, tiles));
|
||||
|
||||
// wall connectors
|
||||
tiles.extend([
|
||||
(4, 8), (4, 4), (11, 8), (11, 4),
|
||||
].iter().map(|(x, y)| {
|
||||
(2, uvec2(*x, *y))
|
||||
}));
|
||||
commands.spawn(player_bundle(&asset_server, vec2(meters(1.5), meters(1.))));
|
||||
|
||||
commands.spawn(tilemap::tilemap_bundle(&asset_server, uvec2(16, 10), tiles));
|
||||
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(-3.5), 0.), false));
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(-3.5), meters(4.)), false))
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(4.5), meters(1.)), false));
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(4.5), meters(5.)), false))
|
||||
.with_child(lock::padlock_bundle(&asset_server, false));
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(3.5), 0.), true))
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(11.5), meters(1.)), true))
|
||||
.with_child(lock::padlock_bundle(&asset_server, true));
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(3.5), meters(4.)), true));
|
||||
commands.spawn(door::door_bundle(&asset_server, vec2(meters(11.5), meters(5.)), true));
|
||||
|
||||
commands.spawn(stairs::stairs_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(0.), 0.),
|
||||
vec2(meters(8.), meters(1.)),
|
||||
Some(vec2(meters(2.), meters(4.))),
|
||||
None,
|
||||
));
|
||||
commands.spawn(stairs::stairs_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(0.), meters(4.)),
|
||||
vec2(meters(8.), meters(5.)),
|
||||
None,
|
||||
Some(vec2(meters(-2.), meters(-4.))),
|
||||
));
|
||||
|
||||
commands.spawn(container::container_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(-6.), 0.),
|
||||
vec2(meters(2.), meters(1.)),
|
||||
uvec2(1, 1),
|
||||
));
|
||||
commands.spawn(container::container_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(-6.), meters(4.)),
|
||||
uvec2(1, 1),
|
||||
)).with_child(lockpick_bundle(&asset_server, UVec2::ZERO));
|
||||
commands.spawn(container::container_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(6.), 0.),
|
||||
vec2(meters(14.), meters(1.)),
|
||||
uvec2(1, 1),
|
||||
));
|
||||
commands.spawn(container::container_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(6.), meters(4.)),
|
||||
uvec2(1, 1),
|
||||
)).with_child(lockpick_bundle(&asset_server, UVec2::ZERO));
|
||||
|
||||
commands.spawn(player_bundle(&asset_server, vec2(meters(-6.), meters(4.))));
|
||||
vec2(meters(2.), meters(5.)),
|
||||
uvec2(4, 4),
|
||||
)).with_child(lockpick_bundle(&asset_server, uvec2(2, 2), false));
|
||||
commands.spawn(container::container_bundle(
|
||||
&asset_server,
|
||||
vec2(meters(14.), meters(5.)),
|
||||
uvec2(2, 2),
|
||||
)).with_child(lockpick_bundle(&asset_server, UVec2::ZERO, true));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,15 @@ pub struct Tilemap;
|
|||
|
||||
pub fn tilemap_bundle(
|
||||
asset_server: &Res<AssetServer>,
|
||||
size: UVec2,
|
||||
tiles: Vec<(u16, UVec2)>,
|
||||
tiles: Vec<(u16, URect)>,
|
||||
) -> impl Bundle {
|
||||
let mut size = uvec2(0, 0);
|
||||
for tile in tiles.iter() {
|
||||
size.x = size.x.max(tile.1.max.x + 1);
|
||||
size.y = size.y.max(tile.1.max.y + 1);
|
||||
}
|
||||
let tile_data: Vec<Option<TileData>> = (0..size.element_product()).map(|xy| {
|
||||
if let Some((id, _)) = tiles.iter().find(|(_, pos)| pos.x == xy % size.x && pos.y == xy / size.x) {
|
||||
if let Some((id, _)) = tiles.iter().find(|(_, rect)| rect.contains(uvec2(xy % size.x, xy / size.x))) {
|
||||
Some(TileData::from_tileset_index(*id))
|
||||
} else { None }
|
||||
}).collect();
|
||||
|
|
@ -44,27 +48,26 @@ pub fn tilemap_bundle(
|
|||
),
|
||||
..default()
|
||||
},
|
||||
Transform::from_xyz(0., meters(0.5) * size.y as f32 - meters(3.), 0.),
|
||||
Transform::from_xyz(
|
||||
meters(0.5) * size.x as f32,
|
||||
meters(0.5) * size.y as f32 - meters(1.),
|
||||
0.,
|
||||
),
|
||||
TilemapChunkTileData(tile_data),
|
||||
Children::spawn(SpawnIter(tiles.into_iter().map(move |(_, pos)| {(
|
||||
// TODO: optimize colliders
|
||||
Collider::cuboid(meters(0.5), meters(0.5)),
|
||||
Children::spawn(SpawnIter(tiles.into_iter().map(move |(_, rect)| {
|
||||
let mut rect = rect.as_rect();
|
||||
rect.max = vec2(rect.max.x + 1., rect.max.y + 1.);
|
||||
|
||||
let (width, height) = (rect.width(), rect.height());
|
||||
let offset = rect.center();
|
||||
(
|
||||
Collider::cuboid(meters(width * 0.5), meters(height * 0.5)),
|
||||
Transform::from_xyz(
|
||||
meters(0.5 + pos.x as f32 - (size.x as f32 * 0.5)),
|
||||
meters(0.5 + pos.y as f32 - (size.y as f32 * 0.5)),
|
||||
meters(offset.x - size.x as f32 * 0.5),
|
||||
meters(offset.y - size.y as f32 * 0.5),
|
||||
0.,
|
||||
),
|
||||
)})
|
||||
)),
|
||||
//Children::spawn(SpawnIter(colliders.into_iter()
|
||||
// .map(move |(collider, pos)| {(
|
||||
// collider.clone(),
|
||||
// Transform::from_xyz(
|
||||
// pos.x - meters(0.5) * size.x as f32,
|
||||
// pos.y - meters(0.5) * size.y as f32,
|
||||
// 0.
|
||||
// ),
|
||||
// )})
|
||||
//)),
|
||||
)}
|
||||
))),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue