Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![windows_subsystem = "windows"]
- use bevy::prelude::*;
- #[derive(Resource)]
- struct Screen {
- size: Vec2,
- }
- #[derive(Component, Default)]
- struct Velocity {
- vector: Vec2,
- }
- #[derive(Component, Default)]
- struct Grabber {
- previous_cursor_position: Vec2,
- }
- fn main() {
- App::new()
- .add_plugins(DefaultPlugins.set(WindowPlugin {
- // TODO: Add always on top
- window: WindowDescriptor {
- title: "Gorgeous Window".to_owned(),
- width: 128.0,
- height: 128.0,
- position: WindowPosition::Centered,
- decorations: false,
- transparent: true,
- ..default()
- },
- ..default()
- }))
- .add_startup_system(startup)
- .add_system(update)
- //.add_system(update_camera.after(update))
- .run();
- }
- fn startup(
- mut commands: Commands,
- mut windows: ResMut<Windows>,
- asset_server: Res<AssetServer>,
- assets: Res<Assets<Image>>,
- ) {
- // Get texture's handle
- let texture_handle = asset_server.load("cube.png");
- // Get window
- let window = windows.primary_mut();
- if let Some(image) = assets.get(&texture_handle) {
- window.set_resolution(image.size().x, image.size().y);
- }
- let window_position = window.position().unwrap().as_vec2();
- let window_center = Vec2 {
- x: window_position.x + window.width() * 0.5,
- y: window_position.y + window.height() * 0.5,
- };
- // Calculate screen size
- commands.insert_resource(Screen {
- size: window_center * 2.0,
- });
- // Create an entity and set its position to window's position
- commands
- .spawn((
- SpriteBundle {
- transform: Transform::from_xyz(window_center.x, window_center.y, 0.0),
- texture: texture_handle,
- ..default()
- },
- Velocity::default(),
- Grabber::default(),
- ))
- .with_children(|parent| {
- parent.spawn(
- // Change camera's clear color to transparent
- Camera2dBundle {
- camera_2d: Camera2d {
- clear_color: bevy::core_pipeline::clear_color::ClearColorConfig::None,
- },
- transform: Transform::from_xyz(0.0, 0.0, 1.0),
- ..default()
- },
- );
- });
- }
- /* fn update_camera(mut query: Query<&mut Camera2d>) {
- for mut camera in query.iter_mut() {
- match camera.clear_color {
- ClearColorConfig::Default => {
- camera.clear_color = ClearColorConfig::None;
- break;
- }
- ClearColorConfig::None => {
- camera.clear_color = ClearColorConfig::Default;
- break;
- }
- _ => {}
- }
- }
- } */
- fn update(
- mut query: Query<(&mut Transform, &mut Velocity, &mut Grabber)>,
- // mut query_camera: Query<&mut Transform, With<Camera2d>>,
- mut windows: ResMut<Windows>,
- screen: Res<Screen>,
- mouse_buttons: Res<Input<MouseButton>>,
- time: Res<Time>,
- ) {
- let delta = time.delta_seconds();
- let drag_force = 500.0;
- let throw_force = 10.0;
- let friction_force = 2000.0;
- let push_force = 2000.0;
- let lerp_force = 10.0;
- // Window
- let window = windows.primary_mut();
- let window_position = window.position().unwrap().as_vec2();
- let window_rect = Rect::new(
- window_position.x,
- window_position.y,
- window_position.x + window.width(),
- window_position.y + window.height(),
- );
- for (mut transform, mut velocity, mut grabber) in query.iter_mut() {
- // Cursor position
- let mut cursor_position: Vec2;
- if window.cursor_position().is_some() {
- cursor_position = window.cursor_position().unwrap();
- cursor_position.y = window_rect.height() - cursor_position.y;
- } else {
- cursor_position = grabber.previous_cursor_position;
- }
- // Window position delta
- let cursor_delta = cursor_position - grabber.previous_cursor_position;
- grabber.previous_cursor_position = cursor_position;
- // Grab start
- if mouse_buttons.just_pressed(MouseButton::Left) {
- velocity.vector = Vec2::ZERO;
- }
- // Grab process, moving window
- if mouse_buttons.pressed(MouseButton::Left) {
- transform.translation += Vec3 {
- x: cursor_delta.x,
- y: cursor_delta.y,
- z: 0.0,
- } * drag_force
- * delta
- }
- // Grab end
- if mouse_buttons.just_released(MouseButton::Left) {
- // Throw
- let heading = cursor_delta.normalize();
- velocity.vector += heading * cursor_delta.length() * throw_force;
- }
- // Push window towards screen if it's out of bounds
- if window_rect.max.x > screen.size.x
- || window_rect.min.x < 0.0
- || window_rect.max.y > screen.size.y
- || window_rect.min.y < 0.0
- {
- let to_screen_center = screen.size * 0.5 - window_rect.center();
- velocity.vector += to_screen_center.normalize() * push_force * delta;
- // Move velocity towards zero
- } else
- /* if velocity.vector != Vec2::ZERO */
- {
- velocity.vector = move_towards(velocity.vector, Vec2::ZERO, friction_force * delta);
- // velocity.vector.lerp(Vec2::ZERO, friction_force * delta);
- /* let strength = friction_force * delta;
- if velocity.vector.x > delta {
- velocity.vector.x -= strength
- };
- if velocity.vector.x < -delta {
- velocity.vector.x += strength
- };
- if velocity.vector.y > delta {
- velocity.vector.y -= strength
- };
- if velocity.vector.y < -delta {
- velocity.vector.y += strength
- }; */
- }
- // Add velocity to position
- // TODO: Retrieve previous velocity if it's NaN
- if velocity.vector.is_nan() == false {
- transform.translation += Vec3 {
- x: velocity.vector.x,
- y: velocity.vector.y,
- z: 0.0,
- } * delta;
- }
- // Update window position
- let lerp = window_rect.center().lerp(
- Vec2 {
- x: transform.translation.x,
- y: transform.translation.y,
- },
- lerp_force * delta,
- );
- window.set_position(
- MonitorSelection::Current,
- IVec2 {
- x: (lerp.x - window_rect.half_size().x) as i32,
- y: (lerp.y - window_rect.half_size().y) as i32,
- },
- );
- /* for mut camera in query_camera.iter_mut() {
- camera.translation = Vec3 {
- x: window_rect.center().x,
- y: window_rect.center().y,
- z: 1.0,
- }
- } */
- // Debug info
- // println!("\x1B[2J\x1B[1;1H"); // Clears console
- // println!("Screen size: {}", screen.size);
- // println!("Window position: {}", window_rect.center());
- // println!("Cursor position: {}", cursor_position);
- // println!("Translation: {}", transform.translation);
- // println!("Velocity: {}", velocity.vector);
- }
- }
- fn move_towards(current: Vec2, target: Vec2, delta: f32) -> Vec2 {
- let vector = target - current;
- let magnitude = vector.length();
- if magnitude <= delta || magnitude == 0.0 {
- return target;
- }
- current + vector / magnitude * delta
- }
Advertisement
Add Comment
Please, Sign In to add comment