fix zoom, rework chunkmap events

This commit is contained in:
2025-05-29 16:22:02 +01:00
parent 0def6af6e8
commit 7e52d6e1bd
5 changed files with 332 additions and 50 deletions
+7 -8
View File
@@ -3,7 +3,6 @@ use bevy::input::mouse::{MouseScrollUnit, MouseWheel};
use bevy::prelude::*;
use bevy::render::camera::{OrthographicProjection, Projection};
use crate::constants::TILE_SIZE;
use crate::{game, tilemap};
#[derive(Component)]
@@ -81,10 +80,10 @@ pub fn spawn_panning_camera(mut commands: Commands) {
}
pub fn scroll_events(mut evr_scroll: EventReader<MouseWheel>, mut query: Query<&mut Projection>) {
const ZOOM_SENSITIVITY: f32 = 0.035;
const LINE_SENSITIVITY: f32 = 0.035;
const PIXEL_SENSITIVITY: f32 = 0.001;
const MIN_SCALE: f32 = 0.2;
const MAX_SCALE: f32 = 2.0;
const MIN_SCALE: f32 = 0.3;
const MAX_SCALE: f32 = 1.75;
for ev in evr_scroll.read() {
for mut projection_component in query.iter_mut() {
@@ -97,14 +96,14 @@ pub fn scroll_events(mut evr_scroll: EventReader<MouseWheel>, mut query: Query<&
};
let new_scale = match ev.unit {
MouseScrollUnit::Line => current_scale + ev.y * ZOOM_SENSITIVITY,
MouseScrollUnit::Pixel => current_scale + ev.y * PIXEL_SENSITIVITY,
MouseScrollUnit::Line => current_scale + ev.y * LINE_SENSITIVITY, // win, x11
MouseScrollUnit::Pixel => current_scale + ev.y * PIXEL_SENSITIVITY, // macos, wayland
};
*projection_component = Projection::Orthographic(OrthographicProjection {
scale: new_scale.max(MIN_SCALE).min(MAX_SCALE),
..OrthographicProjection::default_2d()
});
}
}
}
}
+3 -3
View File
@@ -435,13 +435,13 @@ pub fn spawn_citizens(mut commands: Commands, asset_server: Res<AssetServer>) {
let mut rng = rand::rng();
// Spawn a handful of citizens
for _ in 0..100 {
for _ in 0..10 {
let cit = commands
.spawn(Citizen::new(
&asset_server,
Vec3::new(
rng.random_range(-25.0f32..25.0f32).round(),
rng.random_range(-25.0f32..25.0f32).round(),
rng.random_range(-8.0f32..8.0f32).round(),
rng.random_range(-8.0f32..8.0f32).round(),
35.0,
) * TILE_SIZE,
))
+48 -33
View File
@@ -25,7 +25,7 @@ pub const SEED: u32 = 420;
#[derive(Resource)]
pub struct ChunkMap {
pub loaded_chunks: HashMap<IVec2, bool>,
pub loaded_chunks: HashMap<IVec2, (bool, i32)>,
}
impl Default for ChunkMap {
@@ -193,18 +193,44 @@ pub fn generate_surface_terrain(x: i32, y: i32) -> f32 {
(noise_value * 2.5) as f32
}
fn chunkmap_despawn_timer_system(
mut chunk_map: ResMut<ChunkMap>,
mut cwss: ResMut<CurrentWorldSpriteState>,
) {
for (_, (is_loaded, timer)) in chunk_map.loaded_chunks.iter_mut() {
if !*is_loaded {
continue;
}
if *timer > 0 {
*timer -= 1;
} else {
//TODO - remove chunk from chunkmap
*is_loaded = false;
cwss.state = TerrainSpriteState::WaitingForRender;
}
}
}
fn handle_chunk_events(
mut chunk_events: EventReader<GenerateChunkEvent>,
mut chunk_map: ResMut<ChunkMap>,
mut terrain_event_writer: EventWriter<ChunkTerrainEvent>,
mut weathering_event_writer: EventWriter<ChunkWeatheringAndPrecipitationEvent>,
mut foliage_event_writer: EventWriter<ChunkFoliageEvent>,
mut fauna_event_writer: EventWriter<ChunkFaunaEvent>,
mut cwss: ResMut<CurrentWorldSpriteState>,
) {
let count = chunk_events.len();
// Fire each terrain pass. They will all fire sequentially.
for event in chunk_events.read() {
let chunk_pos = event.chunk_position;
let mut any = false;
for event in chunk_events.par_read() {
let chunk_pos = event.0.chunk_position;
if let Some((true, _)) = chunk_map.loaded_chunks.get(&chunk_pos) {
continue;
}
any = true;
let chunk_map_updates: Mutex<HashMap<IVec2, bool>> = Mutex::new(HashMap::new());
// Mark chunk as loaded in our thread-safe collection
chunk_map_updates.lock().unwrap().insert(chunk_pos, true);
terrain_event_writer.write(ChunkTerrainEvent {
chunk_position: chunk_pos,
});
@@ -217,8 +243,12 @@ fn handle_chunk_events(
fauna_event_writer.write(ChunkFaunaEvent {
chunk_position: chunk_pos,
});
// Apply all collected updates to the actual resources
for (chunk_pos, value) in chunk_map_updates.into_inner().unwrap() {
chunk_map.loaded_chunks.insert(chunk_pos, (value, 1800));
}
}
if count > 0 {
if any {
cwss.state = TerrainSpriteState::WaitingForRender;
}
}
@@ -226,36 +256,23 @@ fn handle_chunk_events(
fn generate_chunk_terrain(
commands: ParallelCommands<'_, '_>, // Use ParallelCommands for parallel spawning
mut events: EventReader<ChunkTerrainEvent>,
mut chunk_map: ResMut<ChunkMap>,
mut tilemap: ResMut<TileMap>,
mut forrestry_event_writer: EventWriter<ChunkForrestryEvent>,
mut occlusion_event_writer: EventWriter<TileOcclusionEvent>,
) {
let is_empty = events.is_empty();
let start = Instant::now();
let count = events.len();
let count: usize = events.len();
let cave_noise = Perlin::new(SEED);
// Create mutexes for our shared resources
let chunk_map_updates = Mutex::new(HashMap::new());
let tilemap_updates = Mutex::new(HashMap::new());
let forrestry_events = Mutex::new(Vec::new());
events.par_read().for_each(|event| {
let chunk_pos = event.chunk_position;
// Check if chunk is already loaded - using a local check first to avoid locking
{
let chunk_map_guard = chunk_map.loaded_chunks.get(&chunk_pos);
if let Some(true) = chunk_map_guard {
return;
}
}
// Mark chunk as loaded in our thread-safe collection
chunk_map_updates.lock().unwrap().insert(chunk_pos, true);
let start_x = chunk_pos.x * CHUNK_SIZE;
let start_y = chunk_pos.y * CHUNK_SIZE;
@@ -356,11 +373,6 @@ fn generate_chunk_terrain(
});
});
// Apply all collected updates to the actual resources
for (chunk_pos, value) in chunk_map_updates.into_inner().unwrap() {
chunk_map.loaded_chunks.insert(chunk_pos, value);
}
for (pos, data) in tilemap_updates.into_inner().unwrap() {
tilemap.floor_tiles.insert(pos, data);
occlusion_event_writer.write(TileOcclusionEvent { tile_position: pos });
@@ -623,14 +635,17 @@ impl Plugin for TilemapPlugin {
.add_systems(
FixedUpdate,
(
handle_chunk_events,
generate_chunk_terrain,
generate_chunk_weathering_and_precipitation,
generate_chunk_forrestry,
generate_chunk_foliage,
generate_chunk_fauna,
)
.chain(),
(
handle_chunk_events,
generate_chunk_terrain,
generate_chunk_weathering_and_precipitation,
generate_chunk_forrestry,
generate_chunk_foliage,
generate_chunk_fauna,
)
.chain(),
chunkmap_despawn_timer_system,
),
)
.add_systems(
Update,