• Bevy的一些窗口设置


    记录了Bevy中窗口背景色、分辨率、标题、是否保留窗口按钮、是否锁定窗口尺寸、帧率的设置。

    0. 运行环境

    运行环境如下:

    • Rust版本:1.72.0
    • Bevy版本:0.11.3

    所用Cargo.toml如下:

    [package]
    name = "bevy-test"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    bevy = "0.11.3"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    以下代码基于的基本代码如下:

    use bevy::prelude::*;
    use bevy::window::PrimaryWindow;
    
    fn main() {
        App::new()
            .add_plugins(DefaultPlugins)
            .add_systems(Startup, spawn_camera)
            .add_systems(Startup, spawn_player)
            .run();
    }
    
    #[derive(Component)]
    pub struct Player {}
    
    /* 在屏幕中心创建2D摄像机 */
    pub fn spawn_camera(mut commands: Commands, window_query: Query<&Window, With<PrimaryWindow>>) {
        let window = window_query.get_single().unwrap();
    
        commands.spawn(Camera2dBundle {
            transform: Transform::from_xyz(window.width() / 2.0, window.height() / 2.0, 0.0),
            ..default()
        });
    }
    
    /* 在屏幕中心创建玩家(方块) */
    pub fn spawn_player(
        mut commands: Commands,
        window_query: Query<&Window, With<PrimaryWindow>>
    ) {
        let window = window_query.get_single().unwrap();
    
        commands.spawn((
            SpriteBundle {
                sprite: Sprite {
                    color: Color::rgb(0.0, 1.0, 1.0),
                    custom_size: Some(Vec2::new(50.0, 50.0)),
                    ..default()
                },
                transform: Transform::from_xyz(window.width() / 2.0, window.height() / 2.0, 0.0),
                ..default()
            },
            Player {},
        ));
    }
    
    /* 玩家移动 */
    pub fn player_movement(
        keyboard_input: Res<Input<KeyCode>>,
        mut player_query: Query<&mut Transform, With<Player>>,
        time: Res<Time>,
    ) {
        if let Ok(mut transform) = player_query.get_single_mut() {
            let mut direction = Vec3::ZERO;
    
            if keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A) {
                direction += Vec3::new(-1.0, 0.0, 0.0);
            }
            if keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D) {
                direction += Vec3::new(1.0, 0.0, 0.0);
            }
            if keyboard_input.pressed(KeyCode::Up) || keyboard_input.pressed(KeyCode::W) {
                direction += Vec3::new(0.0, 1.0, 0.0);
            }
            if keyboard_input.pressed(KeyCode::Down) || keyboard_input.pressed(KeyCode::S) {
                direction += Vec3::new(0.0, -1.0, 0.0);
            }
    
            if direction.length() > 0.0 {
                direction = direction.normalize();
            }
    
            transform.translation += direction * 500.0 * time.delta_seconds();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    1. 背景色设置

    Bevy中背景色是通过添加bevy::prelude::ClearColor资源的方式设置的。

    官网文档

    ClearColor文档链接:https://docs.rs/bevy/latest/bevy/prelude/struct.ClearColor.html

    pub struct ClearColor(pub Color);
    
    • 1

    A Resource that stores the color that is used to clear the screen between frames.
    This color appears as the “background” color for simple apps, when there are portions of the screen with nothing rendered.

    翻译:

    一种资源,用于储存在两帧之间填充屏幕的颜色。
    当屏幕的某些部分没有任何渲染时,此颜色显示为简单应用程序的“背景”颜色。

    代码示例

    fn main() {
        App::new()
            /* 设置背景色 */
            .insert_resource(ClearColor(Color::rgb(0.0, 0.8, 0.0)))
            .add_plugins(DefaultPlugins)
            .add_systems(Startup, spawn_camera)
            .add_systems(Startup, spawn_player)
            .run();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 分辨率、标题、窗口按钮、锁定窗口尺寸设置

    Bevy中分辨率、标题、窗口按钮、锁定窗口尺寸设置是通过设置默认插件(DefaultPlugins)中的WindowPlugin来实现的。
    注意:在Bevy 0.8及以前分辨率等设置是通过WindowDescriptor来实现的,从0.9版本改为通过设置WindowPlugin来实现。

    官网文档

    Window结构体文档链接:https://docs.rs/bevy/latest/bevy/window/struct.Window.html

    pub struct Window {
        pub cursor: Cursor,
        pub present_mode: PresentMode,
        pub mode: WindowMode,
        pub position: WindowPosition,
        pub resolution: WindowResolution,
        pub title: String,
        pub composite_alpha_mode: CompositeAlphaMode,
        pub resize_constraints: WindowResizeConstraints,
        pub resizable: bool,
        pub decorations: bool,
        pub transparent: bool,
        pub focused: bool,
        pub window_level: WindowLevel,
        pub canvas: Option<String>,
        pub fit_canvas_to_parent: bool,
        pub prevent_default_event_handling: bool,
        pub internal: InternalWindowState,
        pub ime_enabled: bool,
        pub ime_position: Vec2,
        pub window_theme: Option<WindowTheme>,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    The defining Component for window entities, storing information about how it should appear and behave.
    Each window corresponds to an entity, and is uniquely identified by the value of their Entity. When the Window component is added to an entity, a new window will be opened. When it is removed or the entity is despawned, the window will close.
    This component is synchronized with winit through bevy_winit: it will reflect the current state of the window and can be modified to change this state.

    代码示例

    fn main() {
        App::new()
            .insert_resource(ClearColor(Color::rgb(0.0, 0.8, 0.0)))
            /* 窗口设置 */
            .add_plugins(DefaultPlugins.set(WindowPlugin {
                primary_window: Some(Window {
                    title: "A Cool Title".into(),
                    resolution: (800., 600.).into(),
                    resizable: true,
                    decorations: true,
                    ..default()
                }),
                ..default()
            }))
            .add_systems(Startup, spawn_camera)
            .add_systems(Startup, spawn_player)
            .run();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. 帧率设置

    目前官网似乎没有提供设置帧率的方法,但有一个名为bevy_framepace的crate可以实现设置帧率的功能。
    链接:https://github.com/aevyrie/bevy_framepace

    和Bevy的版本对应关系:

    bevybevy_framepace
    0.110.13
    0.100.12
    0.90.7, 0.8, 0.9, 0.10, 0.11
    0.80.5, 0.6

    使用方法

    1. Cargo.toml中加入依赖:
    [package]
    name = "bevy-test"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    bevy = "0.11.3"
    bevy_framepace = "0.13.3"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 加入插件
    app.add_plugin(bevy_framepace::FramepacePlugin);
    
    • 1
    1. 设置帧率
    pub fn set_frame_rate(mut settings: ResMut<bevy_framepace::FramepaceSettings>,){
        use bevy_framepace::Limiter;
        settings.limiter = Limiter::from_framerate(30.0);
    }
    
    • 1
    • 2
    • 3
    • 4

    完整代码示例

    use bevy::prelude::*;
    use bevy::window::PrimaryWindow;
    
    fn main() {
        App::new()
            .insert_resource(ClearColor(Color::rgb(0.0, 0.8, 0.0)))
            /* 窗口设置 */
            .add_plugins(DefaultPlugins.set(WindowPlugin {
                primary_window: Some(Window {
                    title: "A Cool Title".into(),
                    resolution: (800., 600.).into(),
                    resizable: true,
                    decorations: true,
                    ..default()
                }),
                ..default()
            }))
            .add_plugins(bevy_framepace::FramepacePlugin)
            .add_systems(Startup, spawn_camera)
            .add_systems(Startup, spawn_player)
            .add_systems(Startup, set_frame_rate)
            .add_systems(Update, player_movement)
            .run();
    }
    
    #[derive(Component)]
    pub struct Player {}
    
    /* 在屏幕中心创建2D摄像机 */
    pub fn spawn_camera(mut commands: Commands, window_query: Query<&Window, With<PrimaryWindow>>) {
        let window = window_query.get_single().unwrap();
    
        commands.spawn(Camera2dBundle {
            transform: Transform::from_xyz(window.width() / 2.0, window.height() / 2.0, 0.0),
            ..default()
        });
    }
    
    /* 在屏幕中心创建玩家(方块) */
    pub fn spawn_player(
        mut commands: Commands,
        window_query: Query<&Window, With<PrimaryWindow>>
    ) {
        let window = window_query.get_single().unwrap();
    
        commands.spawn((
            SpriteBundle {
                sprite: Sprite {
                    color: Color::rgb(0.0, 1.0, 1.0),
                    custom_size: Some(Vec2::new(50.0, 50.0)),
                    ..default()
                },
                transform: Transform::from_xyz(window.width() / 2.0, window.height() / 2.0, 0.0),
                ..default()
            },
            Player {},
        ));
    }
    
    /* 玩家移动 */
    pub fn player_movement(
        keyboard_input: Res<Input<KeyCode>>,
        mut player_query: Query<&mut Transform, With<Player>>,
        time: Res<Time>,
    ) {
        if let Ok(mut transform) = player_query.get_single_mut() {
            let mut direction = Vec3::ZERO;
    
            if keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A) {
                direction += Vec3::new(-1.0, 0.0, 0.0);
            }
            if keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D) {
                direction += Vec3::new(1.0, 0.0, 0.0);
            }
            if keyboard_input.pressed(KeyCode::Up) || keyboard_input.pressed(KeyCode::W) {
                direction += Vec3::new(0.0, 1.0, 0.0);
            }
            if keyboard_input.pressed(KeyCode::Down) || keyboard_input.pressed(KeyCode::S) {
                direction += Vec3::new(0.0, -1.0, 0.0);
            }
    
            if direction.length() > 0.0 {
                direction = direction.normalize();
            }
    
            transform.translation += direction * 500.0 * time.delta_seconds();
        }
    }
    
    /* 设置帧率 */
    pub fn set_frame_rate(mut settings: ResMut<bevy_framepace::FramepaceSettings>,){
        use bevy_framepace::Limiter;
        settings.limiter = Limiter::from_framerate(30.0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    参考链接

    1. 【中字】Bevy 0.8入门教程-基本3D场景_哔哩哔哩_bilibili
    2. 0.8 to 0.9
    3. Window in bevy::window - Rust
  • 相关阅读:
    Java 中的反射和枚举
    dvwa 代码注入impossible代码审计
    学习STM32第十八天
    【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——上
    SignalR WebSocket通讯机制
    Apollo配置中心-手把手教你搭建Apollo配置中心运行环境
    问题杂谈(三十八)处理Cesium双击定位后无法平移视角,只能旋转的问题
    内网渗透笔记
    前端补充19
    网络安全(黑客)自学
  • 原文地址:https://blog.csdn.net/willian113/article/details/133641141