13个版本 (4个重大更新)
0.5.0 | 2021年4月19日 |
---|---|
0.4.2 | 2021年3月10日 |
0.3.1 | 2021年2月28日 |
0.3.0 | 2021年1月31日 |
0.0.1 | 2021年1月3日 |
#11 in #map-editor
每月 36 次下载
140KB
563 行
bevy_ldtk
( 瓦片集来自 Adam Saltsman 的 "Cavernas" )
用于加载LDtk瓦片地图的Bevy插件。
维护说明: 由于我们在内部转向使用Bevy Retro及其LDtk地图加载器,因此我们将仅对此库进行小范围修复。尽管如此,我们仍然欢迎社区提交功能或修复的pull requests!
许可证
Bevy LDtk遵循Katharos许可证,该许可证对您使用它的方式施加某些限制。请在使用Bevy LDtk进行项目之前阅读并理解这些条款。
使用方法
use bevy::prelude::*;
use bevy_ldtk::*;
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_plugin(LdtkPlugin)
.add_startup_system(setup.system())
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// Enable hot reload
asset_server.watch_for_changes().unwrap();
commands
// Spawn the map
.spawn()
.insert_bundle(LdtkMapBundle {
map: asset_server.load("map1.ldtk"),
config: LdtkMapConfig {
set_clear_color: true,
scale: 1.0,
level: std::env::args()
.nth(2)
.map(|x| x.parse().unwrap())
.unwrap_or(0),
center_map: false,
},
..Default::default()
});
// And the camera
commands
.spawn()
.insert_bundle(OrthographicCameraBundle::new_2d());
}
层
当地图层被实例化时,最底层的层在LdtkMapBundle
's Transform
组件的变换坐标处实例化。底层之后的每个层在Z轴上向上放置一个单位。为了使玩家等的精灵出现在渲染的地图上方,它们的Z轴平移必须高于地图变换+您希望它出现在其上的层编号。
LDtk版本
LDtk版本 | 插件版本 |
---|---|
0.8.1 | 0.4, 0.5 |
0.7.0 | 0.2, 0.3 |
Bevy版本
Bevy版本 | 插件版本 |
---|---|
0.4 | 0.2, 0.3, 0.4 |
0.5 | 0.5 |
master | 未官方支持,但可能工作 |
功能
- 一个高效的渲染器,每个地图层只使用4个顶点,并在GPU上排列瓦片
- 支持通过Bevy资产服务器集成进行热重载
- 代码注释详尽,以帮助其他希望了解如何制作自己的瓦片地图渲染器的人。
注意事项
此插件处于相对早期阶段,但对于许多基本地图来说仍然相当有用
- 许多功能尚未支持,包括
- 带间隔的瓦片集
- 单独文件中的关卡
- 偶尔在瓦片之间会出现一些轻微的渲染伪影。( #1 )目前还不确定是什么原因造成的。非常感谢任何有渲染经验的帮助!
提取地图信息
您可以从LDtk JSON地图数据中提取游戏所需的任何信息。以下是一个示例,展示如何实例化玩家。
fn spawn_player(
mut commands: Commands,
printed_maps: Local<Vec<Entity>>,
query: Query<(Entity, &Handle<LdtkMap>)>,
map_assets: Res<Assets<LdtkMap>>,
asset_server: Res<AssetServer>,
mut color_materials: ResMut<Assets<ColorMaterial>>,
) {
for (ent, handle) in query.iter() {
// Skip any maps we have already printed the spawn location for
if printed_maps.contains(&ent) {
continue;
}
// If the map asset has finished loading
if let Some(map) = map_assets.get(handle) {
// This is the default level, but if you spawned a different level, put that ID here
let level_idx = 0;
// Get the level from the project
let level = &map.project.levels[level_idx];
// Find the entities layer
let entities_layer = level
.layer_instances
.as_ref() // get a reference to the layer instances
.unwrap() // Unwrap the option ( this could be None, if there are no layers )
.iter() // Iterate over the layers
.filter(|&x| x.__identifier == "Entities") // Filter on the name of the layer
.next() // Get it
.unwrap(); // Unwrap it ( would be None if it could not find a layer "MyEntities" )
// Get the specific entity you want
let player_start = entities_layer
.entity_instances
.iter() // Iterate over our entities in the layer
.filter(|x| x.__identifier == "Player_Spawn") // Find the one we want
.next() // Get it
.unwrap(); // Unwrap it
// Get the number of layers in the map and add one to it: this is how high we need to
// spawn the player so that he is on top of all the maps
let player_z = level.layer_instances.as_ref().unwrap().len() as f32 + 1.0;
// Spawn the entity!
commands.spawn().insert_bundle(SpriteBundle {
// Set your sprite stuff
transform: Transform::from_xyz(
// The player x position is the entity's x position from the map data
player_start.px[0] as f32,
// The player y position is the entity's y position from the map data, but
// multiplied by negative one because in the LDtk map +y means down and not up.
player_start.px[1] as f32 * -1.0,
// Spawn the player with the z value we determined earlier
player_z,
),
material: color_materials.add(ColorMaterial {
texture: Some(asset_server.load("character.png")),
..Default::default()
}),
..Default::default()
});
}
}
}
依赖关系
~29–73MB
~596K SLoC