batch sprite 1

This commit is contained in:
StephenAdamson
2025-02-08 00:23:49 +00:00
parent 4089851734
commit 4ba6fecc27
6 changed files with 151 additions and 106 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

+5 -8
View File
@@ -34,10 +34,7 @@ impl Citizen {
use crate::constants::TILE_SIZE; use crate::constants::TILE_SIZE;
use crate::tile::TileMap; use crate::tile::TileMap;
use rand::{ use rand::{seq::IndexedRandom, Rng};
seq::{IndexedRandom, SliceRandom},
Rng,
};
use std::{ use std::{
collections::{BinaryHeap, HashMap, HashSet}, collections::{BinaryHeap, HashMap, HashSet},
process::exit, process::exit,
@@ -100,8 +97,8 @@ pub fn update_citizen_wandering_targets(
let chunk_x = chunk_pos.x * CHUNK_SIZE; let chunk_x = chunk_pos.x * CHUNK_SIZE;
let chunk_y = chunk_pos.y * CHUNK_SIZE; let chunk_y = chunk_pos.y * CHUNK_SIZE;
let target_x = chunk_x + rng.gen_range(0..CHUNK_SIZE); let target_x = chunk_x + rng.random_range(0..CHUNK_SIZE);
let target_y = chunk_y + rng.gen_range(0..CHUNK_SIZE); let target_y = chunk_y + rng.random_range(0..CHUNK_SIZE);
// Get height at position // Get height at position
let surface_height = 0; let surface_height = 0;
@@ -344,8 +341,8 @@ pub fn spawn_citizens(mut commands: Commands, asset_server: Res<AssetServer>) {
// Spawn a handful of citizens // Spawn a handful of citizens
for _ in 0..5 { for _ in 0..5 {
let x: f32 = rng.gen_range(-8.0..8.0); let x: f32 = rng.random_range(-8.0..8.0);
let y: f32 = rng.gen_range(-8.0..8.0); let y: f32 = rng.random_range(-8.0..8.0);
let mut position = Vec3::new(x.round(), y.round(), 30.0) * TILE_SIZE; let mut position = Vec3::new(x.round(), y.round(), 30.0) * TILE_SIZE;
position.z += 0.1; position.z += 0.1;
+17 -20
View File
@@ -20,14 +20,16 @@ use bevy::diagnostic::FrameTimeDiagnosticsPlugin;
fn main() { fn main() {
App::new() App::new()
.insert_resource(game::ZIndex(0.0)) .insert_resource(game::ZIndex(0.0))
.add_systems(Startup, tiles::initialize_textures) .insert_resource(tiles::CurrentWorldSpriteState {
state: tiles::WorldSpriteState::Inactive,
})
.add_systems(PreStartup, tiles::initialize_textures)
.add_plugins( .add_plugins(
DefaultPlugins DefaultPlugins
.set(WindowPlugin { .set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
title: String::from("Dorf"), title: String::from("Dorf"),
resizable: false, // mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary),
mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary),
..Default::default() ..Default::default()
}), }),
..Default::default() ..Default::default()
@@ -51,29 +53,24 @@ fn main() {
( (
// camera::camera_movement, // camera::camera_movement,
cursor::move_cursor, cursor::move_cursor,
// citizen::check_citizen_positions_for_chunks, tiles::build_world_sprites,
tile::update_tile_visibility.run_if(|cwss: Res<tiles::CurrentWorldSpriteState>| {
cwss.state == tiles::WorldSpriteState::RenderReady
}),
), ),
) )
.init_resource::<tile::CameraMoved>() .init_resource::<tile::CameraMoved>()
.add_systems( // .add_systems(
Update, // Update,
( // (
// tile::camera_z_movement, // tile::camera_z_movement,
tile::update_tile_visibility // tile::update_tile_visibility
.run_if(|camera_moved: Res<tile::CameraMoved>| camera_moved.0), // .run_if(|camera_moved: Res<tile::CameraMoved>| camera_moved.0),
// log_fps_system, // log_fps_system,
), // ),
) // )
.init_resource::<DiagnosticsRecorder>() .init_resource::<DiagnosticsRecorder>()
.add_systems( .add_systems(Update, (start_recording_system, record_diagnostics_system))
Update,
(
start_recording_system,
record_diagnostics_system,
tile::update_tile_visibility
.run_if(|camera_moved: Res<tile::CameraMoved>| camera_moved.0),
),
)
.run(); .run();
} }
+2 -2
View File
@@ -1,10 +1,9 @@
use crate::game; use crate::{game, tiles};
use bevy::ecs::system::ParamSet; use bevy::ecs::system::ParamSet;
use bevy::prelude::*; use bevy::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Component, Clone)] #[derive(Component, Clone)]
#[require(Sprite)]
pub struct FloorTile { pub struct FloorTile {
pub id: u32, pub id: u32,
pub opaque: bool, pub opaque: bool,
@@ -76,6 +75,7 @@ pub struct TileMap {
pub fixture_tiles: HashMap<IVec3, (u32, bool, [u32; 8])>, pub fixture_tiles: HashMap<IVec3, (u32, bool, [u32; 8])>,
} }
//TODO, redo
pub fn update_tile_visibility( pub fn update_tile_visibility(
z_index: ResMut<game::ZIndex>, z_index: ResMut<game::ZIndex>,
mut query_set: ParamSet<( mut query_set: ParamSet<(
+14 -14
View File
@@ -1,7 +1,8 @@
use crate::constants::{ITILE_SIZE, TILE_SIZE}; use crate::constants::{ITILE_SIZE, TILE_SIZE};
use crate::tile::{self, FixtureTile, FloorTile, NeedsOccluded, TileMap}; use crate::tile::{self, FixtureTile, FloorTile, NeedsOccluded, TileMap};
use crate::tiles::{FixtureTilePrefab, FloorTilePrefab, Textures}; use crate::tiles::{self, FixtureTilePrefab, FloorTilePrefab, Textures};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::text::cosmic_text::ttf_parser::gpos::PositioningSubtable;
use noise::{NoiseFn, Perlin}; use noise::{NoiseFn, Perlin};
use std::collections::HashMap; use std::collections::HashMap;
@@ -38,6 +39,7 @@ pub fn handle_tile_occlusion_updates(
Query<(&mut FixtureTile, &Transform, &mut NeedsOccluded)>, Query<(&mut FixtureTile, &Transform, &mut NeedsOccluded)>,
Query<(Entity, &mut NeedsOccluded)>, Query<(Entity, &mut NeedsOccluded)>,
)>, )>,
mut cwss: ResMut<tiles::CurrentWorldSpriteState>,
) { ) {
query_set query_set
.p0() .p0()
@@ -68,6 +70,7 @@ pub fn handle_tile_occlusion_updates(
commands.entity(entity).remove::<NeedsOccluded>(); commands.entity(entity).remove::<NeedsOccluded>();
} }
} }
cwss.state = tiles::WorldSpriteState::WaitingForRender;
} }
pub fn calculate_visibility(pos: IVec3, tilemap: &TileMap) -> [u32; 8] { pub fn calculate_visibility(pos: IVec3, tilemap: &TileMap) -> [u32; 8] {
@@ -211,19 +214,19 @@ fn handle_chunk_loading(
z as f64 * 0.05, z as f64 * 0.05,
]); ]);
if noise_value < -0.5 { if noise_value < -0.5 {
FloorTilePrefab::air(position, &textures).spawn(&mut commands); FloorTilePrefab::air(position).spawn(&mut commands);
tilemap tilemap
.floor_tiles .floor_tiles
.insert(pos_ivec, (0, false, true, 0, [0; 8])); // Air tile .insert(pos_ivec, (0, false, true, 0, [0; 8])); // Air tile
floor_positions.push((position, "air")); floor_positions.push((position, "air"));
} else if noise_value < 0.8 { } else if noise_value < 0.8 {
FloorTilePrefab::rock(position, &textures).spawn(&mut commands); FloorTilePrefab::rock(position).spawn(&mut commands);
tilemap tilemap
.floor_tiles .floor_tiles
.insert(pos_ivec, (2, true, false, 50, [0; 8])); // Rock tile .insert(pos_ivec, (2, true, false, 50, [0; 8])); // Rock tile
floor_positions.push((position, "rock")); floor_positions.push((position, "rock"));
} else { } else {
FloorTilePrefab::dirt(position, &textures).spawn(&mut commands); FloorTilePrefab::dirt(position).spawn(&mut commands);
tilemap tilemap
.floor_tiles .floor_tiles
.insert(pos_ivec, (1, true, true, 85, [0; 8])); // Dirt tile .insert(pos_ivec, (1, true, true, 85, [0; 8])); // Dirt tile
@@ -233,20 +236,20 @@ fn handle_chunk_loading(
if (generate_surface_noise(world_x, world_y) * TILE_SIZE).round() if (generate_surface_noise(world_x, world_y) * TILE_SIZE).round()
<= position.z + TILE_SIZE <= position.z + TILE_SIZE
{ {
FloorTilePrefab::grass(position, &textures).spawn(&mut commands); FloorTilePrefab::grass(position).spawn(&mut commands);
tilemap tilemap
.floor_tiles .floor_tiles
.insert(pos_ivec, (1, true, true, 100, [0; 8])); // Dirt tile (grass) .insert(pos_ivec, (1, true, true, 100, [0; 8])); // Dirt tile (grass)
floor_positions.push((position, "dirt")); floor_positions.push((position, "dirt"));
} else { } else {
FloorTilePrefab::dirt(position, &textures).spawn(&mut commands); FloorTilePrefab::dirt(position).spawn(&mut commands);
tilemap tilemap
.floor_tiles .floor_tiles
.insert(pos_ivec, (1, true, true, 85, [0; 8])); // Dirt tile .insert(pos_ivec, (1, true, true, 85, [0; 8])); // Dirt tile
floor_positions.push((position, "dirt")); floor_positions.push((position, "dirt"));
} }
} else { } else {
FloorTilePrefab::air(position, &textures).spawn(&mut commands); FloorTilePrefab::air(position).spawn(&mut commands);
tilemap tilemap
.floor_tiles .floor_tiles
.insert(pos_ivec, (0, false, true, 0, [0; 8])); // Air tile .insert(pos_ivec, (0, false, true, 0, [0; 8])); // Air tile
@@ -263,17 +266,17 @@ fn handle_chunk_loading(
match *floor_type { match *floor_type {
"dirt" => { "dirt" => {
FixtureTilePrefab::dirt_wall(above_pos, &textures).spawn(&mut commands); FixtureTilePrefab::dirt_wall(above_pos).spawn(&mut commands);
tilemap.fixture_tiles.insert(above_ivec, (1, true, [0; 8])); tilemap.fixture_tiles.insert(above_ivec, (1, true, [0; 8]));
// Dirt wall // Dirt wall
} }
"rock" => { "rock" => {
FixtureTilePrefab::rock_wall(above_pos, &textures).spawn(&mut commands); FixtureTilePrefab::rock_wall(above_pos).spawn(&mut commands);
tilemap.fixture_tiles.insert(above_ivec, (2, true, [0; 8])); tilemap.fixture_tiles.insert(above_ivec, (2, true, [0; 8]));
// Rock wall // Rock wall
} }
"bedrock" => { "bedrock" => {
FixtureTilePrefab::bedrock_wall(above_pos, &textures).spawn(&mut commands); FixtureTilePrefab::bedrock_wall(above_pos).spawn(&mut commands);
tilemap.fixture_tiles.insert(above_ivec, (3, true, [0; 8])); tilemap.fixture_tiles.insert(above_ivec, (3, true, [0; 8]));
// Bedrock wall // Bedrock wall
} }
@@ -310,9 +313,6 @@ impl Plugin for TilemapPlugin {
) )
.chain(), .chain(),
) )
.add_systems( .add_systems(FixedUpdate, (handle_chunk_loading).chain());
FixedUpdate,
(handle_chunk_loading, handle_tile_occlusion_updates).chain(),
);
} }
} }
+111 -60
View File
@@ -1,47 +1,133 @@
use std::process::exit;
use crate::constants::*; use crate::constants::*;
use crate::tile::{FixtureTile, FloorTile, NeedsOccluded, TileState}; use crate::tile::{FixtureTile, FloorTile, NeedsOccluded, TileState};
use bevy::prelude::*;
use bevy::utils::HashMap; use bevy::utils::HashMap;
use bevy::{prelude::*, transform};
#[derive(Resource)] #[derive(Resource)]
pub struct Textures { pub struct Textures {
pub handles: HashMap<String, Handle<Image>>, pub handles: HashMap<String, Handle<Image>>,
} }
#[derive(Resource)]
pub struct TextureIDs {
pub refs: HashMap<u32, String>,
}
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<AssetServer>) { pub fn initialize_textures(mut commands: Commands, asset_server: Res<AssetServer>) {
let mut textures = HashMap::new(); let mut textures: HashMap<String, Handle<Image>> = HashMap::new();
let mut texture_ids: HashMap<u32, String> = 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( textures.insert(
"grass_floor".to_string(), GRASS_FLOOR_PATH.to_string(),
asset_server.load("grass_floor.png"), asset_server.load(GRASS_FLOOR_PATH),
); );
texture_ids.insert(FLOOR_ID_OFFSET + 2, DIRT_FLOOR_PATH.to_string());
textures.insert( textures.insert(
"dirt_floor".to_string(), DIRT_FLOOR_PATH.to_string(),
asset_server.load("dirt_floor.png"), asset_server.load(DIRT_FLOOR_PATH),
); );
texture_ids.insert(FLOOR_ID_OFFSET + 3, ROCK_FLOOR_PATH.to_string());
textures.insert( textures.insert(
"rock_floor".to_string(), ROCK_FLOOR_PATH.to_string(),
asset_server.load("rock_floor.png"), asset_server.load(ROCK_FLOOR_PATH),
); );
texture_ids.insert(FLOOR_ID_OFFSET + 4, BEDROCK_FLOOR_PATH.to_string());
textures.insert( textures.insert(
"bedrock_floor".to_string(), BEDROCK_FLOOR_PATH.to_string(),
asset_server.load("bedrock_floor.png"), asset_server.load(BEDROCK_FLOOR_PATH),
); );
textures.insert("sky".to_string(), asset_server.load("sky.png"));
textures.insert("dirt_wall".to_string(), asset_server.load("dirt_wall.png")); texture_ids.insert(FIXTURE_ID_OFFSET + 1, DIRT_WALL_PATH.to_string());
textures.insert("rock_wall".to_string(), asset_server.load("rock_wall.png"));
textures.insert( textures.insert(
"bedrock_wall".to_string(), DIRT_WALL_PATH.to_string(),
asset_server.load("bedrock_wall.png"), 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 // Insert the textures resource into the world
commands.insert_resource(Textures { handles: textures }); 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<CurrentWorldSpriteState>,
textures: Res<Textures>,
texture_ids: Res<TextureIDs>,
) {
if cwss.state != WorldSpriteState::WaitingForRender {
return;
}
let now = Instant::now();
if cwss.state == WorldSpriteState::WaitingForRender {
cwss.state = WorldSpriteState::InProgress;
// async/thread this so we don't block the main thread
for (floortile, transform) in query.iter_mut() {
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);
// exit(0);
} }
#[derive(Bundle)] #[derive(Bundle)]
pub struct FloorTilePrefab { pub struct FloorTilePrefab {
transform: Transform, transform: Transform,
sprite: Sprite,
tile: FloorTile, tile: FloorTile,
tile_state: TileState, tile_state: TileState,
visibility: Visibility, visibility: Visibility,
@@ -49,13 +135,9 @@ pub struct FloorTilePrefab {
} }
impl FloorTilePrefab { impl FloorTilePrefab {
pub fn grass(position: Vec3, textures: &Res<Textures>) -> Self { pub fn grass(position: Vec3) -> Self {
FloorTilePrefab { FloorTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("grass_floor").unwrap().clone(),
..Default::default()
},
tile: FloorTile { tile: FloorTile {
id: 1, id: 1,
astar_weight: 100, astar_weight: 100,
@@ -71,13 +153,9 @@ impl FloorTilePrefab {
} }
} }
pub fn dirt(position: Vec3, textures: &Res<Textures>) -> Self { pub fn dirt(position: Vec3) -> Self {
FloorTilePrefab { FloorTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("dirt_floor").unwrap().clone(),
..Default::default()
},
tile: FloorTile { tile: FloorTile {
id: 2, id: 2,
astar_weight: 85, astar_weight: 85,
@@ -93,13 +171,9 @@ impl FloorTilePrefab {
} }
} }
pub fn rock(position: Vec3, textures: &Res<Textures>) -> Self { pub fn rock(position: Vec3) -> Self {
FloorTilePrefab { FloorTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("rock_floor").unwrap().clone(),
..Default::default()
},
tile: FloorTile { tile: FloorTile {
id: 3, id: 3,
astar_weight: 50, astar_weight: 50,
@@ -115,13 +189,9 @@ impl FloorTilePrefab {
} }
} }
pub fn air(position: Vec3, textures: &Res<Textures>) -> Self { pub fn air(position: Vec3) -> Self {
FloorTilePrefab { FloorTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("sky").unwrap().clone(),
..Default::default()
},
tile: FloorTile { tile: FloorTile {
id: 0, id: 0,
opaque: false, opaque: false,
@@ -138,13 +208,9 @@ impl FloorTilePrefab {
} }
} }
pub fn bedrock(position: Vec3, textures: &Res<Textures>) -> Self { pub fn bedrock(position: Vec3) -> Self {
FloorTilePrefab { FloorTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("bedrock_floor").unwrap().clone(),
..Default::default()
},
tile: FloorTile { tile: FloorTile {
id: 4, id: 4,
astar_weight: 150, astar_weight: 150,
@@ -164,7 +230,6 @@ impl FloorTilePrefab {
commands.spawn(( commands.spawn((
self.tile, self.tile,
self.transform, self.transform,
self.sprite,
self.tile_state, self.tile_state,
self.visibility, self.visibility,
self.needs_occluded, self.needs_occluded,
@@ -175,22 +240,17 @@ impl FloorTilePrefab {
#[derive(Bundle)] #[derive(Bundle)]
pub struct FixtureTilePrefab { pub struct FixtureTilePrefab {
transform: Transform, transform: Transform,
sprite: Sprite,
tile: FixtureTile, tile: FixtureTile,
visibility: Visibility, visibility: Visibility,
needs_occluded: NeedsOccluded, needs_occluded: NeedsOccluded,
} }
impl FixtureTilePrefab { impl FixtureTilePrefab {
pub fn dirt_wall(position: Vec3, textures: &Res<Textures>) -> Self { pub fn dirt_wall(position: Vec3) -> Self {
FixtureTilePrefab { FixtureTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("dirt_wall").unwrap().clone(),
..Default::default()
},
tile: FixtureTile { tile: FixtureTile {
id: 1, id: FIXTURE_ID_OFFSET + 1,
..Default::default() ..Default::default()
}, },
visibility: Visibility::Hidden, visibility: Visibility::Hidden,
@@ -200,13 +260,9 @@ impl FixtureTilePrefab {
} }
} }
pub fn rock_wall(position: Vec3, textures: &Res<Textures>) -> Self { pub fn rock_wall(position: Vec3) -> Self {
FixtureTilePrefab { FixtureTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("rock_wall").unwrap().clone(),
..Default::default()
},
tile: FixtureTile { tile: FixtureTile {
id: 2, id: 2,
..Default::default() ..Default::default()
@@ -218,13 +274,9 @@ impl FixtureTilePrefab {
} }
} }
pub fn bedrock_wall(position: Vec3, textures: &Res<Textures>) -> Self { pub fn bedrock_wall(position: Vec3) -> Self {
FixtureTilePrefab { FixtureTilePrefab {
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
sprite: Sprite {
image: textures.handles.get("bedrock_wall").unwrap().clone(),
..Default::default()
},
tile: FixtureTile { tile: FixtureTile {
id: 0, id: 0,
..Default::default() ..Default::default()
@@ -240,7 +292,6 @@ impl FixtureTilePrefab {
commands.spawn(( commands.spawn((
self.tile, self.tile,
self.transform, self.transform,
self.sprite,
self.visibility, self.visibility,
self.needs_occluded, self.needs_occluded,
)); ));