用 Rust 開發遊戲 - 2 畫圖和攝像機

上一篇文章 << 用 Rust 開發遊戲 - 1 Bevy 和 ECS>>,我們創建了一個 2D 遊戲平臺的窗口,這篇文章我們添加一個正方形代表玩家,一個攝像機系統顯示圖形。

畫一個正方形

我們的遊戲將由精靈組成。我們所有的世界都是用等寬等高的正方形建造的。

這意味着我們要做的第一件事就是在屏幕上畫一個正方形。

讓我們創建一個名爲 spawn_player 的新系統:

// Player component
struct Player;
// spawn player system
fn spawn_player(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
    commands
        .spawn_bundle(SpriteBundle {
            material: materials.add(Color::rgb(0.7, 0.7, 0.7).into()),
            sprite: Sprite::new(Vec2::new(10.0, 10.0)),
            ..Default::default()
        })
        .insert(Player);
}

並在我們的 Bevy 應用程序中註冊這個系統:

App::build()
        .insert_resource(WindowDescriptor {
            title: "Platformer!".to_string(),
            width: 640.0,
            height: 400.0,
            vsync: true,
            ..Default::default()
        })
        .insert_resource(ClearColor(Color::rgb(0.04, 0.04, 0.04)))
        .add_startup_stage("player_setup", SystemStage::single(spawn_player.system())) // line to add
        .add_plugins(DefaultPlugins)
        .run();

現在我們來運行 cargo run,然而,窗口打開,我們什麼也沒有看到。

我們在 Bevy 場景中繪製了一個正方形,但由於沒有添加攝像機,所以它還不可見……

添加一個攝像機

爲了添加一個攝像機,我們將創建一個新的系統:

fn setup(mut commands: Commands) {
    commands.spawn_bundle(OrthographicCameraBundle::new_2d());
}

並在我們的應用程序中註冊它:

// ...
+ .add_startup_system(setup.system())
.add_startup_stage("player_setup", SystemStage::single(spawn_player.system()))
// ...

這個新系統爲屏幕增加了一個正交攝像機。在製作電腦遊戲時,你需要了解兩種主要的攝像機類型:正投影和透視。

在 3D 遊戲中,當我們需要模擬一個真實的世界視圖時,透視鏡頭是最常用的。這種類型的攝像機更能代表我們在現實生活中看待事物的方式。

當我們不需要高這個維度時,就會使用正交攝像機。當物體離我們的視角 (攝像機) 更遠時,正交攝像機不會改變物體的大小。在我們的例子中,我們正在創造一款 2D 平臺遊戲,所以我們只需要使用正交攝像機。

讓我們運行 cargo run:

攝像機調整

如果窗口被調整,可見區域會變大。在通常的平臺遊戲中,可見區域的寬度很少發生變化。攝像機將跟隨玩家,但屏幕的可見寬度應該保持不變。

看看 orthographiccamerample::new_2d() 的源碼,我們可以看到它添加了一個名爲 OrthographicProjection 的資源,該資源具有一個名爲 scaling_mode 的參數。該參數是一個 enum,可以取 4 個不同的值。我們感興趣的是 FixedHorizontal 枚舉變體。

讓我們在 src 下新創建一個 camera.rs 文件:

// src/camera.rs
use bevy::{prelude::OrthographicCameraBundle, render::camera::{OrthographicProjection, DepthCalculation, ScalingMode}, math::Vec3};
pub fn new_camera_2d() -> OrthographicCameraBundle {
  let far = 1000.0;
  let mut camera = OrthographicCameraBundle::new_2d();
  camera.orthographic_projection = OrthographicProjection {
    far,
    depth_calculation: DepthCalculation::ZDifference,
    scaling_mode: ScalingMode::FixedHorizontal,
    ..Default::default()
  };
  camera.transform.scale = Vec3::new(10., 10., 1.);
  return camera;
}

這一行 camera.transform.scale = Vec3::new(10., 10., 1); 就是放大我們的攝像機,否則,可視區域在 y 軸和 x 軸上從 - 1 到 + 1 的單位區域。

// src/main.rs
mod camera;
pub use camera::*;
// ...
+ commands.spawn_bundle(new_camera_2d()); 
- commands.spawn_bundle(OrthographicCameraBundle::new_2d());

這是可行的,但我們的玩家太龐大了。讓我們縮小一下:

// src/main.rs spawn_player method
.spawn_bundle(SpriteBundle {
    material: materials.add(Color::rgb(0.7, 0.7, 0.7).into()),
    sprite: Sprite::new(Vec2::new(1.0, 1.0)),
    ..Default::default()
})

現在運行 cargo run:

本文翻譯自:

https://dev.to/sbelzile/making-games-in-rust-part-2-drawing-stuff-and-cameras-1jon

coding 到燈火闌珊 專注於技術分享,包括 Rust、Golang、分佈式架構、雲原生等。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/DnIQBT6CgbzwsudvNOtxkg