bevy虚拟屏幕系统

use bevy::prelude::*;
use bevy::window::WindowResized;

// 虚拟屏幕的配置
#[derive(Resource)]
struct CanvasConfig {
    width: f32,
    height: f32,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                resolution: (800, 600).into(),
                resizable: true,
                ..default()
            }),
            ..default()
        }))
        .insert_resource(CanvasConfig {
            width: 1280.0,
            height: 720.0,
        })
        .add_systems(Startup, setup)
        .add_systems(Update, window_resize_system)
        .add_systems(Update, player_movement_system)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    // 创建摄像机
    commands.spawn(Camera2d);

    // 创建玩家实体
    commands.spawn((
        Name::new("Player"),
        Sprite {
            image: asset_server.load("main.png"), 
            // color: Color::srgb(0.0, 0.0, 1.0),
            custom_size: Some(Vec2::new(1280.0, 720.0)),
            ..default()
        },
        Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)),
    ));

    // 新的实体
    commands.spawn((
        Name::new("textbox‘"),
        Sprite {
            image: asset_server.load("textbox.png"), 
            // color: Color::srgb(0.0, 0.0, 1.0),
            custom_size: Some(Vec2::new(1920.0, 277.0)),
            
            ..default()
        },
        Transform::from_translation(Vec3::new(0.0, -220.0, 10.0)), // z值控制层级,越大越靠前
        
        
    ));
}

fn window_resize_system(
    mut resize_events: MessageReader<WindowResized>,
    mut camera_query: Query<&mut Projection, With<Camera2d>>,
    canvas_config: Res<CanvasConfig>,
) {
    for event in resize_events.read() {
        println!("窗口大小改变: 宽度 = {}, 高度 = {}", event.width, event.height);

        for mut projection in camera_query.iter_mut() {
            if let Projection::Orthographic(ortho) = projection.as_mut() {
                let window_aspect = event.width / event.height;
                let canvas_aspect = canvas_config.width / canvas_config.height;

                // 根据宽高比计算缩放,保持虚拟屏幕内容居中且完整显示
                ortho.scale = if window_aspect > canvas_aspect {
                    // 窗口更宽,按高度适配
                    canvas_config.height / event.height
                } else {
                    // 窗口更高,按宽度适配
                    canvas_config.width / event.width
                };
            }
        }
    }
}

fn player_movement_system(
    keyboard_input: Res<ButtonInput<KeyCode>>,
    mut query: Query<&mut Transform, With<Sprite>>,
    time: Res<Time>,
) {
    if let Some(mut player_transform) = query.iter_mut().next() {
        let mut direction = Vec3::ZERO;

        if keyboard_input.pressed(KeyCode::KeyW) {
            direction.y += 1.0;
        }
        if keyboard_input.pressed(KeyCode::KeyS) {
            direction.y -= 1.0;
        }
        if keyboard_input.pressed(KeyCode::KeyA) {
            direction.x -= 1.0;
        }
        if keyboard_input.pressed(KeyCode::KeyD) {
            direction.x += 1.0;
        }

        if direction.length() > 0.0 {
            player_transform.translation += direction.normalize() * 200.0 * time.delta_secs();
        }
    }
}