diff --git a/packages/rust-game/src/player_plugin/camera.rs b/packages/rust-game/src/player_plugin/camera.rs index 5f6b47b7..11441b43 100644 --- a/packages/rust-game/src/player_plugin/camera.rs +++ b/packages/rust-game/src/player_plugin/camera.rs @@ -15,51 +15,26 @@ use rust_game_plugin::{ mod view; mod zoom; +fn camera_size_from_zoom(zoom: f32, physical_size: Vec2) -> Vec2 { + let max = physical_size.x.max(physical_size.y); + + Vec2 { + x: zoom * physical_size.x / max, + y: zoom * physical_size.y / max, + } +} + #[derive(Resource)] pub struct CameraConfig { pub zoom: f32, pub animation_speed: f32, - - zoom_index: usize, -} - -impl CameraConfig { - fn target_zoom(&self) -> f32 { - match self.zoom_index { - 0 => 0.02, - 1 => 0.015, - 2 => 0.01, - 3 => 0.0075, - 4 => 0.005, - _ => 0.003, - } - } - - fn zoom_in(&mut self) -> bool { - if self.zoom_index < 4 { - self.zoom_index += 1; - true - } else { - false - } - } - - fn zoom_out(&mut self) -> bool { - if self.zoom_index > 0 { - self.zoom_index -= 1; - true - } else { - false - } - } } impl Default for CameraConfig { fn default() -> Self { Self { - zoom: 0.02, + zoom: 1920.0 * 0.02, animation_speed: 1.0, - zoom_index: 0, } } } diff --git a/packages/rust-game/src/player_plugin/camera/view.rs b/packages/rust-game/src/player_plugin/camera/view.rs index 255dbea6..3f749a4d 100644 --- a/packages/rust-game/src/player_plugin/camera/view.rs +++ b/packages/rust-game/src/player_plugin/camera/view.rs @@ -17,7 +17,10 @@ use crate::player_plugin::{ interpolation::RocketInterpolated, }; -use super::{CameraAnimation, CameraConfig, CameraStartAnimation, CustomCamera, StartAnimation}; +use super::{ + camera_size_from_zoom, CameraAnimation, CameraConfig, CameraStartAnimation, CustomCamera, + StartAnimation, +}; pub fn update() -> SystemConfigs { ( @@ -128,14 +131,16 @@ fn animate( camera_config.zoom = f32::lerp( zoom_animation.source_zoom, zoom_animation.target_zoom, - ease_out_slow(zoom_animation.progress), + ease_out_fast(zoom_animation.progress), ); if zoom_animation.progress >= 1.0 { custom_camera.animation = CameraAnimation::None; } - custom_camera.size = custom_camera.physical_size * camera_config.zoom; + custom_camera.size = + camera_size_from_zoom(camera_config.zoom, custom_camera.physical_size); + let rocket_transform = query_rocket.single(); update_camera_size(&mut camera, &mut custom_camera, &mut projection); @@ -178,9 +183,7 @@ fn track_window_size( ); custom_camera.physical_size = physical_camera_size; - - let camera_size = physical_camera_size * camera_config.zoom; - custom_camera.size = camera_size; + custom_camera.size = camera_size_from_zoom(camera_config.zoom, custom_camera.physical_size); let rocket_transform = query_rocket.single(); @@ -278,7 +281,7 @@ fn prepare_inital_view( custom_camera.level_constraint_size = inital_level.camera.size(); custom_camera.level_constraint_translation = inital_level.camera.min; custom_camera.physical_size = window_size; - custom_camera.size = window_size * camera_config.zoom; + custom_camera.size = camera_size_from_zoom(camera_config.zoom, custom_camera.physical_size); update_camera_size(&mut native_camera, &mut custom_camera, &mut projection); update_camera_transform(&mut custom_camera, &mut transform, rocket_position); diff --git a/packages/rust-game/src/player_plugin/camera/zoom.rs b/packages/rust-game/src/player_plugin/camera/zoom.rs index 60a4cd06..29c0835a 100644 --- a/packages/rust-game/src/player_plugin/camera/zoom.rs +++ b/packages/rust-game/src/player_plugin/camera/zoom.rs @@ -1,6 +1,8 @@ use bevy::{ecs::schedule::SystemConfigs, prelude::*}; use bevy_rapier2d::prelude::*; +use crate::player_plugin::camera::camera_size_from_zoom; + use super::{CameraAnimation, CameraConfig, CustomCamera, ZoomAnimation}; pub fn startup() -> SystemConfigs { @@ -121,15 +123,57 @@ fn handle_zoom_buttons( match *interaction { Interaction::Pressed => { - error!("zoom: {:?}", camera_config.zoom_index); + let camera = camera_query.single_mut(); + + let current_zoom = match &camera.animation { + CameraAnimation::Zoom(animation) => animation.target_zoom, + _ => camera_config.zoom, + }; + + if let Some(target) = match *zoom_type { + ZoomButton::ZoomIn => { + if current_zoom > 20.0 { + let mut total_zoom = current_zoom; + + let target_size = + camera_size_from_zoom(total_zoom, camera.physical_size); + + if target_size.x < camera.level_constraint_size.x + || target_size.y < camera.level_constraint_size.y + { + Some(current_zoom / 1.5) + } else { + let factor_x = + camera.physical_size.x / camera.physical_size.max_element(); + let factor_y = + camera.physical_size.y / camera.physical_size.max_element(); + + Some( + f32::max( + camera.level_constraint_size.x / factor_x, + camera.level_constraint_size.y / factor_y, + ) / 1.5, + ) + } + } else { + None + } + } + ZoomButton::ZoomOut => { + let target_size = camera_size_from_zoom(current_zoom, camera.physical_size); - if match *zoom_type { - ZoomButton::ZoomIn => camera_config.zoom_in(), - ZoomButton::ZoomOut => camera_config.zoom_out(), + if target_size.x < camera.level_constraint_size.x + || target_size.y < camera.level_constraint_size.y + { + Some(current_zoom * 1.5) + } else { + None + } + } } { camera_query.single_mut().animation = CameraAnimation::Zoom(ZoomAnimation { source_zoom: camera_config.zoom, - target_zoom: camera_config.target_zoom(), + target_zoom: target, progress: 0.0, });