use std::process::exit; use crate::tile::{FixtureTile, FloorTile, NeedsOccluded, TileState}; use crate::{constants::*, game}; use bevy::{prelude::*, transform}; use bevy_platform::collections::hash_map::HashMap; #[derive(Resource)] pub struct Textures { pub handles: HashMap>, } #[derive(Resource)] pub struct TextureIDs { pub refs: HashMap, } const FLOOR_ID_OFFSET: u32 = 0; const FIXTURE_ID_OFFSET: u32 = 500000; pub const DEFAULT_TEXTURE: &str = "default.png"; const GRASS_FLOOR_PATH: &str = "grass_floor.png"; const DIRT_FLOOR_PATH: &str = "dirt_floor.png"; const ROCK_FLOOR_PATH: &str = "rock_floor.png"; const BEDROCK_FLOOR_PATH: &str = "bedrock_floor.png"; const SKY_PATH: &str = "sky.png"; const DIRT_WALL_PATH: &str = "dirt_wall.png"; const ROCK_WALL_PATH: &str = "rock_wall.png"; const BEDROCK_WALL_PATH: &str = "bedrock_wall.png"; pub fn initialize_textures(mut commands: Commands, asset_server: Res) { let mut textures: HashMap> = HashMap::new(); let mut texture_ids: HashMap = HashMap::new(); texture_ids.insert(u32::MAX, DEFAULT_TEXTURE.to_string()); texture_ids.insert(FLOOR_ID_OFFSET + 0, SKY_PATH.to_string()); textures.insert(SKY_PATH.to_string(), asset_server.load(SKY_PATH)); texture_ids.insert(FLOOR_ID_OFFSET + 1, GRASS_FLOOR_PATH.to_string()); textures.insert( GRASS_FLOOR_PATH.to_string(), asset_server.load(GRASS_FLOOR_PATH), ); texture_ids.insert(FLOOR_ID_OFFSET + 2, DIRT_FLOOR_PATH.to_string()); textures.insert( DIRT_FLOOR_PATH.to_string(), asset_server.load(DIRT_FLOOR_PATH), ); texture_ids.insert(FLOOR_ID_OFFSET + 3, ROCK_FLOOR_PATH.to_string()); textures.insert( ROCK_FLOOR_PATH.to_string(), asset_server.load(ROCK_FLOOR_PATH), ); texture_ids.insert(FLOOR_ID_OFFSET + 4, BEDROCK_FLOOR_PATH.to_string()); textures.insert( BEDROCK_FLOOR_PATH.to_string(), asset_server.load(BEDROCK_FLOOR_PATH), ); texture_ids.insert(FIXTURE_ID_OFFSET + 1, DIRT_WALL_PATH.to_string()); textures.insert( DIRT_WALL_PATH.to_string(), asset_server.load(DIRT_WALL_PATH), ); texture_ids.insert(FIXTURE_ID_OFFSET + 2, ROCK_WALL_PATH.to_string()); textures.insert( ROCK_WALL_PATH.to_string(), asset_server.load(ROCK_WALL_PATH), ); texture_ids.insert(FIXTURE_ID_OFFSET + 3, BEDROCK_WALL_PATH.to_string()); textures.insert( BEDROCK_WALL_PATH.to_string(), asset_server.load(BEDROCK_WALL_PATH), ); // Insert the textures resource into the world commands.insert_resource(Textures { handles: textures }); commands.insert_resource(TextureIDs { refs: texture_ids }); } #[derive(Debug, PartialEq)] pub enum WorldSpriteState { Inactive, WaitingForRender, InProgress, RenderReady, } #[derive(Resource)] pub struct CurrentWorldSpriteState { pub state: WorldSpriteState, } use std::time::Instant; pub fn build_world_sprites( mut query: Query<(&FloorTile, &Transform)>, mut commands: Commands, mut cwss: ResMut, textures: Res, texture_ids: Res, z_index: ResMut, ) { if cwss.state != WorldSpriteState::WaitingForRender { return; } let now = Instant::now(); if cwss.state == WorldSpriteState::WaitingForRender { cwss.state = WorldSpriteState::InProgress; let z_index = (z_index.0 as i32 + 150) as usize; println!("z_index = {}", z_index); for (floortile, transform) in query.iter_mut() { let is_visible = (floortile.visible_range[z_index / 32] & (1 << (z_index % 32) as u32)) != 0; if is_visible { let id = floortile.id; let texture_id = texture_ids.refs.get(&id).unwrap(); let texture = textures.handles.get(texture_id).unwrap(); let sprite = Sprite { image: texture.clone(), ..Default::default() }; commands.spawn((sprite, *transform)); } } cwss.state = WorldSpriteState::RenderReady; } println!("{:?}", cwss.state); let elapsed = now.elapsed(); println!("Elapsed: {:.2?}", elapsed); } #[derive(Bundle)] pub struct FloorTilePrefab { transform: Transform, tile: FloorTile, tile_state: TileState, visibility: Visibility, needs_occluded: NeedsOccluded, } impl FloorTilePrefab { pub fn grass(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FloorTile { id: 1, astar_weight: 100, ..Default::default() }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn dirt(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FloorTile { id: 2, astar_weight: 85, ..Default::default() }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn rock(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FloorTile { id: 3, astar_weight: 50, ..Default::default() }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn air(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FloorTile { id: 0, opaque: false, walkable: false, ..Default::default() }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn bedrock(position: Vec3) -> Self { FloorTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FloorTile { id: 4, astar_weight: 150, ..Default::default() }, tile_state: TileState { timer: Timer::from_seconds(1.0, TimerMode::Repeating), }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn spawn(self, commands: &mut Commands) { commands.spawn(( self.tile, self.transform, self.tile_state, self.visibility, self.needs_occluded, )); } } #[derive(Bundle)] pub struct FixtureTilePrefab { transform: Transform, tile: FixtureTile, visibility: Visibility, needs_occluded: NeedsOccluded, } impl FixtureTilePrefab { pub fn dirt_wall(position: Vec3) -> Self { FixtureTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FixtureTile { id: FIXTURE_ID_OFFSET + 1, ..Default::default() }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn rock_wall(position: Vec3) -> Self { FixtureTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FixtureTile { id: 2, ..Default::default() }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn bedrock_wall(position: Vec3) -> Self { FixtureTilePrefab { transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), tile: FixtureTile { id: 0, ..Default::default() }, visibility: Visibility::Hidden, needs_occluded: NeedsOccluded { has_been_occluded: false, }, } } pub fn spawn(self, commands: &mut Commands) { commands.spawn(( self.tile, self.transform, self.visibility, self.needs_occluded, )); } }