用 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