camera zooming
This commit is contained in:
@@ -1,13 +1,39 @@
|
|||||||
use bevy::input::keyboard::KeyCode;
|
use bevy::input::keyboard::KeyCode;
|
||||||
|
use bevy::input::mouse::{MouseScrollUnit, MouseWheel};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy::render::camera::{OrthographicProjection, Projection};
|
||||||
|
|
||||||
use crate::constants::TILE_SIZE;
|
use crate::constants::TILE_SIZE;
|
||||||
|
use crate::{game, tilemap};
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct PanningCamera {
|
pub struct PanningCamera {
|
||||||
pub pan_speed: f32,
|
pub pan_speed: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Default)]
|
||||||
|
pub struct CameraMoved(pub bool);
|
||||||
|
|
||||||
|
pub fn camera_z_movement(
|
||||||
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
mut z_index: ResMut<game::ZIndex>,
|
||||||
|
mut camera_moved: ResMut<CameraMoved>,
|
||||||
|
) {
|
||||||
|
camera_moved.0 = false;
|
||||||
|
if keyboard_input.just_pressed(KeyCode::ShiftLeft) {
|
||||||
|
z_index.0 -= 1.0;
|
||||||
|
z_index.0 = z_index.0.clamp(-tilemap::Z_BELOW + 1.0, tilemap::Z_ABOVE);
|
||||||
|
camera_moved.0 = true;
|
||||||
|
println!("z_index = {}", z_index.0);
|
||||||
|
}
|
||||||
|
if keyboard_input.just_pressed(KeyCode::ShiftRight) {
|
||||||
|
z_index.0 += 1.0;
|
||||||
|
z_index.0 = z_index.0.clamp(-tilemap::Z_BELOW + 1.0, tilemap::Z_ABOVE);
|
||||||
|
camera_moved.0 = true;
|
||||||
|
println!("z_index = {}", z_index.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn camera_movement(
|
pub fn camera_movement(
|
||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
mut query: Query<(&PanningCamera, &mut Transform), With<Camera>>,
|
mut query: Query<(&PanningCamera, &mut Transform), With<Camera>>,
|
||||||
@@ -41,7 +67,36 @@ pub fn camera_movement(
|
|||||||
pub fn spawn_panning_camera(mut commands: Commands) {
|
pub fn spawn_panning_camera(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Camera2d,
|
Camera2d,
|
||||||
|
Projection::Orthographic(OrthographicProjection {
|
||||||
|
scale: 1.0,
|
||||||
|
..OrthographicProjection::default_2d()
|
||||||
|
}),
|
||||||
Transform::from_xyz(0., 0., 10. * TILE_SIZE),
|
Transform::from_xyz(0., 0., 10. * TILE_SIZE),
|
||||||
PanningCamera { pan_speed: 15.0 },
|
PanningCamera { pan_speed: 15.0 },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn scroll_events(mut evr_scroll: EventReader<MouseWheel>, mut query: Query<&mut Projection>) {
|
||||||
|
const ZOOM_SENSITIVITY: f32 = 0.05;
|
||||||
|
const MIN_SCALE: f32 = 0.4;
|
||||||
|
const MAX_SCALE: f32 = 1.5;
|
||||||
|
|
||||||
|
for ev in evr_scroll.read() {
|
||||||
|
for mut projection_component in query.iter_mut() {
|
||||||
|
let current_scale = match &*projection_component {
|
||||||
|
Projection::Orthographic(ortho_proj) => ortho_proj.scale,
|
||||||
|
Projection::Perspective(_) => 1.0,
|
||||||
|
Projection::Custom(_custom_projection) => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_scale = match ev.unit {
|
||||||
|
MouseScrollUnit::Line => current_scale + ev.y * ZOOM_SENSITIVITY,
|
||||||
|
MouseScrollUnit::Pixel => todo!(),
|
||||||
|
};
|
||||||
|
*projection_component = Projection::Orthographic(OrthographicProjection {
|
||||||
|
scale: new_scale.max(MIN_SCALE).min(MAX_SCALE),
|
||||||
|
..OrthographicProjection::default_2d()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+7
-6
@@ -17,7 +17,7 @@ impl Citizen {
|
|||||||
pub fn new(asset_server: &Res<AssetServer>, position: Vec3) -> Self {
|
pub fn new(asset_server: &Res<AssetServer>, position: Vec3) -> Self {
|
||||||
Citizen {
|
Citizen {
|
||||||
ambulatory: Ambulatory {
|
ambulatory: Ambulatory {
|
||||||
walk_speed: 2.,
|
walk_speed: 0.,
|
||||||
run_speed: 6.,
|
run_speed: 6.,
|
||||||
target: None,
|
target: None,
|
||||||
current_path: None,
|
current_path: None,
|
||||||
@@ -197,7 +197,8 @@ pub fn citizen_movement(
|
|||||||
if transform.translation.z / TILE_SIZE <= z_index.0 + 1.0 {
|
if transform.translation.z / TILE_SIZE <= z_index.0 + 1.0 {
|
||||||
*visibility = Visibility::Visible;
|
*visibility = Visibility::Visible;
|
||||||
let saturation =
|
let saturation =
|
||||||
((z_index.0 - transform.translation.z / TILE_SIZE) / 8.0)
|
((z_index.0 - (transform.translation.z / TILE_SIZE) + 1.)
|
||||||
|
/ 8.0)
|
||||||
.clamp(0.0, 1.0);
|
.clamp(0.0, 1.0);
|
||||||
|
|
||||||
sprite.color =
|
sprite.color =
|
||||||
@@ -324,7 +325,7 @@ fn calculate_path(tilemap: &TileMap, start: IVec3, goal: IVec3) -> Vec<Vec3> {
|
|||||||
) {
|
) {
|
||||||
(1, 0, 0) | (0, 1, 0) | (0, 0, 1) => 10, // Orthogonal movement (1 axis)
|
(1, 0, 0) | (0, 1, 0) | (0, 0, 1) => 10, // Orthogonal movement (1 axis)
|
||||||
(1, 1, 0) | (1, 0, 1) | (0, 1, 1) => 14, // Diagonal movement (2 axes)
|
(1, 1, 0) | (1, 0, 1) | (0, 1, 1) => 14, // Diagonal movement (2 axes)
|
||||||
(1, 1, 1) => 17, // Full 3D diagonal movement (3 axes)
|
(1, 1, 1) => 20, // Full 3D diagonal movement (3 axes)
|
||||||
_ => continue, // Invalid movement
|
_ => continue, // Invalid movement
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -405,9 +406,9 @@ pub fn spawn_citizens(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||||||
|
|
||||||
// Spawn a handful of citizens
|
// Spawn a handful of citizens
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
let x: f32 = rng.random_range(-8.0..8.0);
|
let x: f32 = rng.random_range(-5.0..5.0);
|
||||||
let y: f32 = rng.random_range(-8.0..8.0);
|
let y: f32 = rng.random_range(-5.0..5.0);
|
||||||
let mut position = Vec3::new(x.round(), y.round(), 30.0) * TILE_SIZE;
|
let mut position = Vec3::new(x.round(), y.round(), 35.0) * TILE_SIZE;
|
||||||
position.z += 0.1;
|
position.z += 0.1;
|
||||||
|
|
||||||
commands.spawn(Citizen::new(&asset_server, position));
|
commands.spawn(Citizen::new(&asset_server, position));
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
pub const PIXEL_RATIO: f32 = 2.0;
|
pub const PIXEL_RATIO: f32 = 1.0;
|
||||||
pub const TILE_PIXELS: u32 = 16;
|
pub const TILE_PIXELS: u32 = 16;
|
||||||
pub const TILE_SIZE: f32 = TILE_PIXELS as f32 * PIXEL_RATIO;
|
pub const TILE_SIZE: f32 = TILE_PIXELS as f32 * PIXEL_RATIO;
|
||||||
pub const ITILE_SIZE: i32 = TILE_SIZE as i32;
|
pub const ITILE_SIZE: i32 = TILE_SIZE as i32;
|
||||||
|
|||||||
+6
-8
@@ -42,19 +42,17 @@ fn main() {
|
|||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
FixedUpdate,
|
FixedUpdate,
|
||||||
(
|
(tiles::build_quilted_terrain_sprites, camera::scroll_events),
|
||||||
camera::camera_movement,
|
|
||||||
cursor::move_cursor,
|
|
||||||
tiles::build_quilted_terrain_sprites,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.init_resource::<tile::CameraMoved>()
|
.init_resource::<camera::CameraMoved>()
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
tile::camera_z_movement,
|
camera::camera_z_movement,
|
||||||
|
camera::camera_movement,
|
||||||
|
cursor::move_cursor,
|
||||||
tile::update_tile_visibility
|
tile::update_tile_visibility
|
||||||
.run_if(|camera_moved: Res<tile::CameraMoved>| camera_moved.0),
|
.run_if(|camera_moved: Res<camera::CameraMoved>| camera_moved.0),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
|
|||||||
-23
@@ -47,29 +47,6 @@ impl Default for FixtureTile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
|
||||||
pub struct CameraMoved(pub bool);
|
|
||||||
|
|
||||||
pub fn camera_z_movement(
|
|
||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
||||||
mut z_index: ResMut<game::ZIndex>,
|
|
||||||
mut camera_moved: ResMut<CameraMoved>,
|
|
||||||
) {
|
|
||||||
camera_moved.0 = false;
|
|
||||||
if keyboard_input.just_pressed(KeyCode::ShiftLeft) {
|
|
||||||
z_index.0 -= 1.0;
|
|
||||||
z_index.0 = z_index.0.clamp(-tilemap::Z_BELOW + 1.0, tilemap::Z_ABOVE);
|
|
||||||
camera_moved.0 = true;
|
|
||||||
println!("z_index = {}", z_index.0);
|
|
||||||
}
|
|
||||||
if keyboard_input.just_pressed(KeyCode::ShiftRight) {
|
|
||||||
z_index.0 += 1.0;
|
|
||||||
z_index.0 = z_index.0.clamp(-tilemap::Z_BELOW + 1.0, tilemap::Z_ABOVE);
|
|
||||||
camera_moved.0 = true;
|
|
||||||
println!("z_index = {}", z_index.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Resource, Default, Clone)]
|
#[derive(Resource, Default, Clone)]
|
||||||
pub struct TileMap {
|
pub struct TileMap {
|
||||||
pub floor_tiles: HashMap<IVec3, (u32, bool, bool, u8, [u32; 8])>, // id, opaque, walkable, astar_weight, visible_range
|
pub floor_tiles: HashMap<IVec3, (u32, bool, bool, u8, [u32; 8])>, // id, opaque, walkable, astar_weight, visible_range
|
||||||
|
|||||||
+8
-7
@@ -11,8 +11,8 @@ use noise::{NoiseFn, Perlin};
|
|||||||
|
|
||||||
pub const CHUNK_SIZE: i32 = 8;
|
pub const CHUNK_SIZE: i32 = 8;
|
||||||
|
|
||||||
pub const Z_BELOW: f32 = 3.0;
|
pub const Z_BELOW: f32 = 20.0;
|
||||||
pub const Z_ABOVE: f32 = 5.0;
|
pub const Z_ABOVE: f32 = 10.0;
|
||||||
pub const Z_TOTAL: f32 = Z_ABOVE + Z_BELOW; // MAX 255 DO NOT EXCEED
|
pub const Z_TOTAL: f32 = Z_ABOVE + Z_BELOW; // MAX 255 DO NOT EXCEED
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
@@ -164,6 +164,7 @@ fn generate_chunks_from_algo(
|
|||||||
) {
|
) {
|
||||||
let is_empty = events.is_empty();
|
let is_empty = events.is_empty();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
let count = events.len();
|
||||||
|
|
||||||
let cave_noise = Perlin::new(0);
|
let cave_noise = Perlin::new(0);
|
||||||
for event in events.read() {
|
for event in events.read() {
|
||||||
@@ -204,9 +205,9 @@ fn generate_chunks_from_algo(
|
|||||||
let noise_value = cave_noise.get([
|
let noise_value = cave_noise.get([
|
||||||
world_x as f64 * 0.05,
|
world_x as f64 * 0.05,
|
||||||
world_y as f64 * 0.05,
|
world_y as f64 * 0.05,
|
||||||
z as f64 * (0.15 * -z as f64),
|
z as f64 * 0.05,
|
||||||
]);
|
]);
|
||||||
if noise_value < -0.65 {
|
if noise_value < -0.85 {
|
||||||
FloorTilePrefab::air(position).spawn(&mut commands);
|
FloorTilePrefab::air(position).spawn(&mut commands);
|
||||||
tilemap
|
tilemap
|
||||||
.floor_tiles
|
.floor_tiles
|
||||||
@@ -278,13 +279,13 @@ fn generate_chunks_from_algo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !is_empty {
|
if !is_empty {
|
||||||
println!("Chunks loaded in {:.2?}", start.elapsed());
|
println!("{} chunks loaded in {:.2?}", count, start.elapsed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_initial_chunks(mut event_writer: EventWriter<LoadChunkEvent>) {
|
fn setup_initial_chunks(mut event_writer: EventWriter<LoadChunkEvent>) {
|
||||||
for x in -10..=10 {
|
for x in -16..=16 {
|
||||||
for y in -10..=10 {
|
for y in -9..=9 {
|
||||||
event_writer.write(LoadChunkEvent {
|
event_writer.write(LoadChunkEvent {
|
||||||
chunk_position: IVec2::new(x, y),
|
chunk_position: IVec2::new(x, y),
|
||||||
});
|
});
|
||||||
|
|||||||
+6
-6
@@ -328,14 +328,14 @@ fn blit_texture_with_alpha(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This system handles updating quilted sprites when the world changes
|
// This system handles updating quilted sprites when the world changes
|
||||||
pub fn update_quilts_on_world_change(
|
// pub fn update_quilts_on_world_change(
|
||||||
mut commands: Commands,
|
// mut commands: Commands,
|
||||||
mut quilt_cache: ResMut<QuiltCache>,
|
// mut quilt_cache: ResMut<QuiltCache>,
|
||||||
mut cwss: ResMut<CurrentWorldSpriteState>,
|
// mut cwss: ResMut<CurrentWorldSpriteState>,
|
||||||
// Add any resources or queries that indicate world changes
|
// Add any resources or queries that indicate world changes
|
||||||
// For example, if you have a WorldChangeEvent:
|
// For example, if you have a WorldChangeEvent:
|
||||||
// mut world_changes: EventReader<WorldChangeEvent>,
|
// mut world_changes: EventReader<WorldChangeEvent>,
|
||||||
) {
|
// ) {
|
||||||
// Example: Check for world changes
|
// Example: Check for world changes
|
||||||
// if !world_changes.is_empty() {
|
// if !world_changes.is_empty() {
|
||||||
// for event in world_changes.iter() {
|
// for event in world_changes.iter() {
|
||||||
@@ -347,7 +347,7 @@ pub fn update_quilts_on_world_change(
|
|||||||
// Alternatively, if you have specific systems that modify the world,
|
// Alternatively, if you have specific systems that modify the world,
|
||||||
// you could have them set cwss.state = WorldSpriteState::WaitingForRender
|
// you could have them set cwss.state = WorldSpriteState::WaitingForRender
|
||||||
// and add affected z-indices to quilt_cache.dirty_indices
|
// and add affected z-indices to quilt_cache.dirty_indices
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[derive(Bundle)]
|
#[derive(Bundle)]
|
||||||
pub struct FloorTilePrefab {
|
pub struct FloorTilePrefab {
|
||||||
|
|||||||
Reference in New Issue
Block a user