Closed MTRNord closed 3 years ago
Hi there!
You were very close with Query<&LdtkMap>
, you actually have to use Query<&Handle<LdtkMap>>
. I'll have to add this to the docs apparently. 😃 Thanks for asking. :+1:
pub fn setup_collisions(
map_query: Query<&Handle<LdtkMap>>,
map_assets: Res<Assets<LdtkMap>>,
) {
// Loop through all of the maps
for map_handle in map_query.iter() {
// We have to `if let` here because asset server may not have finished loading
// the map yet.
if let Some(map) = map_assets.get(map_handle) {
// Do something with map data
}
}
}
At that point you have full access to the whole map data structure which you can do whatever you want with.
awesome! yeah having that in the example would have helped :)
You can leave the issue open and I'll close it when I get a good example in. :smile: :+1:
@zicklag if you have the time and want to: An example to get the coordinates of the entities using this would also be nice. I did get the texture loaded as wanted but I am kinda stuck wrapping my head around how to find the x,y coordinates for the entity :) I am probably just missing something again. (aka do i need Layer defs or layer instances, or both and how to bring them into the bevy coordinate format)
There may be minor typos in the below example, but heres a modification of the actual code I've used in my game for spawning the player:
if let Some(map) = maps.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 == "MyEntities") // Filter on the one we want
.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 == "PlayerStart") // 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(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],
// 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] * -1,
// Spawn the player with the z value we determined earlier
player_z
),
..Default::default()
});
}
}
It's a little wordier than I would like: the LDtk map format could probably use some helpers to make this kind of stuff a little easier, but at least for now all the data is there. If me or my team get the chance sometime we might try to add some helpers.
Hm I guess it should work but for some reason it seems like it ends up not where it is in the editor.
Editor:
Game:
(And yes due to laziness and learning purposes I am using one of the starter levels the editor brought)
Ah, do you have the center_map
option set to true
in when you spawn the map? That will cause the coordinates to be off. The setting is really more of a convenience for when you just want to display the map.
I guess that's a little confusing maybe. :thinking: maybe I shouldn't have the option to avoid confusion? But then maybe people would be annoyed that they couldn't spawn the map without it. I'm open to suggestions on that point. :slightly_smiling_face:
(And yes due to laziness and learning purposes I am using one of the starter levels the editor brought)
That ain't lazyness that's efficiency! 😉
Ah yeah :) though I think the coordinate_at_mouse
example thingy by the engine has a conversion for calculating the coordinates based on the window size. That should move it in the right place right?
Hmm I haven't seen that before. I don't know. If you want it centered or something during gameplay you would most-likely just move the camera to follow the player or something like that.
Intresting enough without the center_map
set to true it is different wrong.
I guess it might be due to using a 4k monitor :)
Hmm, that's interesting. Is the map scale set to 1? I think the monitor scale shouldn't make a difference.
Ahhh thats it. It was set to 4. Am I right to assume multiplying each coordinate with the scale factor will fix the issue? (It works with scale 1 but scale 1 doesnt cover the screen the way I want it too)
Yes, you could multiply everything by 4 and I think it would work, but there's a much more awesome way to do it that will work no matter what your screen size. You just have to spawn the camera with different settings that tell it to fix the height of the camera and then automatically reveal the rest ofthe scene along the width of the camera, and to also scale the whole scene up if the height of the screen is bigger than the height of the screen:
commands
.spawn(OrthographicCameraBundle {
orthographic_projection: OrthographicProjection {
far: 1024.0, // This gives us 1024 layers,
scale: 200, // How many pixels high in the game
scaling_mode: ScalingMode::FixedVertical,
..Default::default()
},
..OrthographicCameraBundle::new_2d()
})
Oh yeah thats much cooler :D Thanks for all the help!
Ah but that doesnt work in 0-4 apparently due to missing scale and scaling_mode fields :D I guess I am now movin to the latest version now
Oh, yeah, I forgot about that. 0.5 should be comming out soon-ish I think so looking forward to that. :)
Oh yeah thats much cooler :D Thanks for all the help!
Glad I could help 😃
Just had to figure out dep hell :D
Side note: This breaks with 0.5 after bevy commit 079b3ade89195ef1aa4bcf1f8c0740a6572b84b6
(thats the las working one or me)
Ah, gotcha. Good job finding the working one! After 0.5 is released I'll make a new bevy_ldtk
release that works.
Yeah thats fine :D No rush :3 Learned today more in this issue than in the whole university semester ;P
Fixed in 173ecbd14157423e45327c451000c8dc6bb0eddf.
Hi :) How do I access the map from a system? I am new to bevy so I might have missed something. My first try was to use
map: Query<LdtkMap>
but that didnt work.Basicly I want to get from the map the entities to draw them as needed. And the required information is stored in the map.