bevy-playground/src/map.rs

104 lines
3.1 KiB
Rust
Raw Normal View History

use crate::{inspector::HideFromInspector, prelude::*};
use bevy::tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task};
// use bevy::{
// ecs::world::CommandQueue,
// tasks::{AsyncComputeTaskPool, Task},
// };
2024-08-02 16:43:30 -05:00
use bevy_ecs_tilemap::prelude::*;
2024-08-02 13:40:43 -05:00
use rand::prelude::*;
use rand_pcg::Pcg64;
use rand_seeder::Seeder;
#[derive(Component, Debug)]
pub struct Tilemap;
#[derive(Component, Debug)]
pub struct TileLoader(Task<()>);
#[derive(Event)]
pub struct TileLoadEvent(TileBundle);
pub fn init(
mut commands: Commands,
assets: Res<AssetServer>,
mut loads: EventWriter<TileLoadEvent>,
) {
2024-08-02 17:04:16 -05:00
// TODO: I'm pretty determined to not have this sieze up the game despite the large number of entities being added. Should work with a "loading" screen and doing this in the background?
2024-08-02 13:40:43 -05:00
let mut rng: Pcg64 = Seeder::from("default_seed").make_rng();
2024-08-02 16:43:30 -05:00
let size = TilemapSize::new(1024, 1024);
let tile_size = TilemapTileSize::new(16., 16.);
let grid_size = TilemapGridSize::new(16., 16.);
let map_type = TilemapType::Square;
let texture = TilemapTexture::Single(assets.load("img/Tileset Grass.png"));
let storage = TileStorage::empty(size);
let tilemap = commands
.spawn((
Tilemap,
Name::new("Tilemap"),
TilemapBundle {
grid_size,
map_type,
size,
storage,
texture,
tile_size,
transform: get_tilemap_center_transform(&size, &grid_size, &map_type, f32::MIN),
..Default::default()
},
))
.id();
let pool = AsyncComputeTaskPool::get();
let task = pool.spawn(async move {
for x in 0..size.x {
for y in 0..size.y {
let position = TilePos::new(x, y);
let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 {
rng.gen_range(0..(16 * 8))
} else {
0
2024-08-02 17:04:16 -05:00
});
loads.send(TileLoadEvent(TileBundle {
position,
tilemap_id: TilemapId(tilemap),
texture_index,
..default()
}));
}
2024-08-02 17:04:16 -05:00
}
return ();
});
commands.entity(tilemap).insert(TileLoader(task));
}
2024-08-02 17:04:16 -05:00
pub fn tile_loaders(
mut commands: Commands,
mut storage: Query<&mut TileStorage>,
mut tasks: Query<&mut TileLoader>,
mut loads: EventReader<TileLoadEvent>,
) {
// TODO: to avoid locking up the universe we only want to handle a certain number per iteration (Update)
let mut storage = storage.single_mut();
for ev in loads.read() {
let ref_position = &ev.0.position;
let tile = commands.spawn((HideFromInspector, ev.0)).id();
storage.set(ref_position, tile);
}
for mut task in &mut tasks {
if block_on(future::poll_once(&mut task.0)).is_some() {
// TODO: transition to game?
2024-08-02 16:43:30 -05:00
}
}
}
2024-08-02 16:43:30 -05:00
2024-08-02 13:40:43 -05:00
pub fn exit(mut commands: Commands, q: Query<Entity, With<Tilemap>>) {
for id in q.iter() {
commands.entity(id).despawn_recursive();
}
}