首页 > 其他分享 >bevy 0.11 camera2d zoom and pan with touchpad on macos

bevy 0.11 camera2d zoom and pan with touchpad on macos

时间:2023-08-05 20:11:25浏览次数:46  
标签:bevy mut macos min camera2d height width camera let

use bevy::prelude::*;
use bevy::{input::mouse::MouseWheel, render::camera::ScalingMode};
use bevy::input::touchpad::TouchpadMagnify;
use bevy::window::PrimaryWindow;

const GRID_SIZE: usize = 200;

pub struct SimpleCameraPlugin;

impl Plugin for SimpleCameraPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Startup, spawn_camera)
            .add_systems(Update, (camera_pan, camera_zoom));
    }
}

#[cfg(not(target_os = "macos"))]
#[derive(Component)]
pub struct CameraSettings {
    pub pan_speed: f32,
    pub zoom_speed: f32,
}

fn spawn_camera(mut commands: Commands) {
    let mut camera = Camera2dBundle::default();
    camera.transform.translation.x = GRID_SIZE as f32 / 2.0;
    camera.transform.translation.y = GRID_SIZE as f32 / 2.0;

    camera.projection.scaling_mode = ScalingMode::AutoMin {
        min_width: 64.0,
        min_height: 36.0,
    };

    commands.spawn((
        camera,

        #[cfg(not(target_os = "macos"))]
        CameraSettings {
            pan_speed: 6.0,
            zoom_speed: 10.0,
        },
    ));
}

#[cfg(target_os = "macos")]
fn camera_zoom(
    mut camera: Query<&mut OrthographicProjection, With<Camera2d>>,
    mut touchpad: EventReader<TouchpadMagnify>,
) {
    let mut projection = camera.single_mut();
    if let ScalingMode::AutoMin {
        min_width,
        min_height,
    } = projection.scaling_mode
    {
        if let Some(ev) = touchpad.iter().last() {
            let width_delta = -ev.0 * min_width;
            let height_delta = width_delta * 9. / 16.;
            let new_width = num::clamp(min_width + width_delta, 16.0, 128.0);
            let new_height = num::clamp(min_height + height_delta, 9.0, 72.0);
            // TODO units
            projection.scaling_mode = ScalingMode::AutoMin {
                min_width: new_width,
                min_height: new_height,
            };
        }
    }
}

#[cfg(target_os = "macos")]
fn camera_pan(
    window: Query<&Window, With<PrimaryWindow>>,
    mut camera: Query<(&mut Transform, &OrthographicProjection), With<Camera2d>>,
    mut mouse: EventReader<MouseWheel>,
) {
    if mouse.is_empty() { return; }

    let window = window.single();
    let (win_width, win_height) = (window.physical_width() as f32, window.physical_height() as f32);

    let (mut transform, projection) = camera.single_mut();

    if let ScalingMode::AutoMin { min_width, min_height } = projection.scaling_mode {
        if let Some(ev) = mouse.iter().last() {
            transform.translation.x -= ev.x / win_width * min_width;
            transform.translation.y += ev.y / win_height * min_height;
        }
        transform.translation.x = num::clamp(transform.translation.x, min_width/2. - 2., GRID_SIZE as f32 - min_width/2. + 1.);
        transform.translation.y = num::clamp(transform.translation.y, min_height/2. - 2., GRID_SIZE as f32 - min_height/2. + 1.);
    }
}

#[cfg(not(target_os = "macos"))]
fn camera_zoom(
    mut camera: Query<(&mut OrthographicProjection, &CameraSettings), With<Camera2d>>,
    mut mouse: EventReader<MouseWheel>,
) {
    let (mut projection, settings) = camera.single_mut();
    if let ScalingMode::AutoMin {
        min_width,
        min_height,
    } = projection.scaling_mode
    {
        for ev in mouse.iter() {
            let width_delta = ev.y * settings.zoom_speed;
            let height_delta = width_delta * min_height / min_width;
            let new_width = num::clamp(min_width + width_delta, 16.0, 128.0);
            let new_height = num::clamp(min_height + height_delta, 9.0, 72.0);
            // TODO units
            projection.scaling_mode = ScalingMode::AutoMin {
                min_width: new_width,
                min_height: new_height,
            };
        }
    }
}

#[cfg(not(target_os = "macos"))]
fn camera_pan(
    mut camera: Query<(&mut Transform, &CameraSettings), With<Camera2d>>,
    keyboard: Res<Input<KeyCode>>,
    time: Res<Time>,
) {
    let (mut transform, settings) = camera.single_mut();

    if keyboard.pressed(KeyCode::A) {
        transform.translation.x -= time.delta_seconds() * settings.pan_speed;
    }
    if keyboard.pressed(KeyCode::D) {
        transform.translation.x += time.delta_seconds() * settings.pan_speed;
    }
    if keyboard.pressed(KeyCode::W) {
        transform.translation.y += time.delta_seconds() * settings.pan_speed;
    }
    if keyboard.pressed(KeyCode::S) {
        transform.translation.y -= time.delta_seconds() * settings.pan_speed;
    }
}

标签:bevy,mut,macos,min,camera2d,height,width,camera,let
From: https://www.cnblogs.com/hangj/p/17608531.html

相关文章

  • JetBrains RubyMine 2023.2 (macOS, Linux, Windows) 发布 - 最智能的 Ruby 与 Rails
    JetBrainsRubyMine2023.2(macOS,Linux,Windows)发布-最智能的Ruby与RailsIDE请访问原文链接:https://sysin.org/blog/jb-rubymine-2023/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgJetBrainsRubyMine-最智能的Ruby与RailsIDE为什么选择RubyMi......
  • JetBrains Rider 2023.2 (macOS, Linux, Windows) - 快速且强大的跨平台 .NET IDE
    JetBrainsRider2023.2(macOS,Linux,Windows)-快速且强大的跨平台.NETIDE请访问原文链接:https://sysin.org/blog/jb-rider-2023/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgJetBrainsRider-快速且强大的跨平台.NETIDERider是什么?JetBrainsRider......
  • VMware ESXi 7.0 U3n macOS Unlocker & OEM BIOS (标准版和厂商定制版) 2023年8月更新
    VMwareESXi7.0U3nmacOSUnlocker&OEMBIOS(标准版和厂商定制版)2023年8月更新ESXi7.0标准版和Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)定制版镜像请访问原文链接:https://sysin.org/blog/vmware-esxi-7-u3-oem/,查看最新版。原创作品,转......
  • 米哈游游戏《原神》如何在苹果电脑 MacOS 系统上运行?
    作者最近购买了一台新的Mac电脑,我平时喜欢玩原神想着能不能在Mac上玩原神呀,最初以为Mac能够像在Windows上一样直接从官方网站上下载mac版直接安装原神,但却发现原神根本就没有Mac版本。后来作者了解到可以通过playCover在Mac上安装IOS版本的原神,小试了一下,歪瑞的nice~......
  • bevy cursor to world
    代码//!bevyversion:0.11//!Spawnaballontheplanewhenyouclickonit.usebevy::prelude::*;usebevy::input::common_conditions::input_just_pressed;usebevy::window::{PrimaryWindow,close_on_esc};constPLANE_SIZE:f32=5.0;fnmain(){Ap......
  • macOS 虚拟桌面黑屏(转)
    转自:macOS重置虚拟桌面、macOS虚拟桌面黑屏有几次出现如图的情况,以为是iTerm的问题,但是在关闭软件,重启之后,依旧无效。后面经过网友告知,才知道是虚拟桌面的问题。为了清理这个问题,有以下两种方法法一:在终端输入以下命令,会删除虚拟桌面文件,以及重启电脑sudorm~/Library/Pr......
  • 解决在macOS系统上使用rust-gdb调式rust代码时无法进入断点的问题
        问题title缩写,主要原因是gdb无法在cargo生成可执行文件和符号信息关联起来,类型信息如下图:  解决方案:在Cargo.toml文件中添加一项配置,所以能找到符号信息. 配置信息说明:1. profile.dev或者profile.release是用cargobuild进行编译时使用到的配置......
  • MacOS苹果系统投屏工具—AirServer
    AirServer是一个Mac专用投屏工具,功能强大,并且可以通过网络和其他平台同步视频内容。可以使用多个设备进行投屏,快速查看同一局域网内的视频。支持的设备:苹果系统。支持Windows、Mac、Android、iOS、windows平台。→→↓↓载AirServer 1、支持Windows、Mac(部分苹果用......
  • 黑苹果如何在macOS Sonoma中驱动博通网卡
    准备资源资源包中包含:AirportBrcmFixup.kext/IOSkywalkFamily.kext/IO80211FamilyLegacy.kext/OpenCore-Patcher 使用方法:1.将csr-active-config设置为03080000全选代码复制2.在boot-args中添加amfi=0x803.在Delete中添加csr-active-config4.将SecureBootModel设置为D......
  • macOS Sonoma 14 beta 4 (23A5301g) ISO、IPSW、PKG 下载
    macOSSonoma14beta4(23A5301g)ISO、IPSW、PKG下载本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows和Linux中创建可引导介质。请访问原文链接:https://sysin.org/blog/macOS-......