【rust/bevy】从game template开始

2024-01-14 13:36
文章标签 rust template game bevy

本文主要是介绍【rust/bevy】从game template开始,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 说在前面
  • 步骤
  • 进入3D
  • 控制方块
  • 问题

说在前面

  • 操作系统:win11
  • rust版本:rustc 1.77.0-nightly
  • bevy版本:0.12

步骤

  • rust安装
    这里
    windows下建议使用msvc版本
  • bevy安装
    这里
  • clone代码
    git clone https://github.com/NiklasEi/bevy_game_template.git
    
  • 运行
    cargo run
    
  • 结果
    在这里插入图片描述

进入3D

  • template中的例子是2d的,我们稍微修改下
  • 首先增加一个CameraController,代码在bevy的例程中也可以找到
    //! A freecam-style camera controller plugin.
    //! To use in your own application:
    //! - Copy the code for the [`CameraControllerPlugin`] and add the plugin to your App.
    //! - Attach the [`CameraController`] component to an entity with a [`Camera3dBundle`].use bevy::window::CursorGrabMode;
    use bevy::{input::mouse::MouseMotion, prelude::*};use std::f32::consts::*;
    use std::fmt;/// Based on Valorant's default sensitivity, not entirely sure why it is exactly 1.0 / 180.0,
    /// but I'm guessing it is a misunderstanding between degrees/radians and then sticking with
    /// it because it felt nice.
    pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0;#[derive(Component)]
    pub struct CameraController {pub enabled: bool,pub initialized: bool,pub sensitivity: f32,pub key_forward: KeyCode,pub key_back: KeyCode,pub key_left: KeyCode,pub key_right: KeyCode,pub key_up: KeyCode,pub key_down: KeyCode,pub key_run: KeyCode,pub mouse_key_enable_mouse: MouseButton,pub keyboard_key_enable_mouse: KeyCode,pub walk_speed: f32,pub run_speed: f32,pub friction: f32,pub pitch: f32,pub yaw: f32,pub velocity: Vec3,
    }impl Default for CameraController {fn default() -> Self {Self {enabled: true,initialized: false,sensitivity: 1.0,key_forward: KeyCode::W,key_back: KeyCode::S,key_left: KeyCode::A,key_right: KeyCode::D,key_up: KeyCode::E,key_down: KeyCode::Q,key_run: KeyCode::ShiftLeft,mouse_key_enable_mouse: MouseButton::Left,keyboard_key_enable_mouse: KeyCode::M,walk_speed: 5.0,run_speed: 15.0,friction: 0.5,pitch: 0.0,yaw: 0.0,velocity: Vec3::ZERO,}}
    }impl fmt::Display for CameraController {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {write!(f,"
    Freecam Controls:MOUSE\t- Move camera orientation{:?}/{:?}\t- Enable mouse movement{:?}{:?}\t- forward/backward{:?}{:?}\t- strafe left/right{:?}\t- 'run'{:?}\t- up{:?}\t- down",self.mouse_key_enable_mouse,self.keyboard_key_enable_mouse,self.key_forward,self.key_back,self.key_left,self.key_right,self.key_run,self.key_up,self.key_down)}
    }pub struct CameraControllerPlugin;impl Plugin for CameraControllerPlugin {fn build(&self, app: &mut App) {app.add_systems(Update, camera_controller);}
    }fn camera_controller(time: Res<Time>,mut windows: Query<&mut Window>,mut mouse_events: EventReader<MouseMotion>,mouse_button_input: Res<Input<MouseButton>>,key_input: Res<Input<KeyCode>>,mut move_toggled: Local<bool>,mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
    ) {let dt = time.delta_seconds();if let Ok((mut transform, mut options)) = query.get_single_mut() {if !options.initialized {let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);options.yaw = yaw;options.pitch = pitch;options.initialized = true;}if !options.enabled {return;}// Handle key inputlet mut axis_input = Vec3::ZERO;if key_input.pressed(options.key_forward) {axis_input.z += 1.0;}if key_input.pressed(options.key_back) {axis_input.z -= 1.0;}if key_input.pressed(options.key_right) {axis_input.x += 1.0;}if key_input.pressed(options.key_left) {axis_input.x -= 1.0;}if key_input.pressed(options.key_up) {axis_input.y += 1.0;}if key_input.pressed(options.key_down) {axis_input.y -= 1.0;}if key_input.just_pressed(options.keyboard_key_enable_mouse) {*move_toggled = !*move_toggled;}// Apply movement updateif axis_input != Vec3::ZERO {let max_speed = if key_input.pressed(options.key_run) {options.run_speed} else {options.walk_speed};options.velocity = axis_input.normalize() * max_speed;} else {let friction = options.friction.clamp(0.0, 1.0);options.velocity *= 1.0 - friction;if options.velocity.length_squared() < 1e-6 {options.velocity = Vec3::ZERO;}}let forward = transform.forward();let right = transform.right();transform.translation += options.velocity.x * dt * right+ options.velocity.y * dt * Vec3::Y+ options.velocity.z * dt * forward;// Handle mouse inputlet mut mouse_delta = Vec2::ZERO;if mouse_button_input.pressed(options.mouse_key_enable_mouse) || *move_toggled {for mut window in &mut windows {if !window.focused {continue;}window.cursor.grab_mode = CursorGrabMode::Locked;window.cursor.visible = false;}for mouse_event in mouse_events.read() {mouse_delta += mouse_event.delta;}}if mouse_button_input.just_released(options.mouse_key_enable_mouse) {for mut window in &mut windows {window.cursor.grab_mode = CursorGrabMode::None;window.cursor.visible = true;}}if mouse_delta != Vec2::ZERO {// Apply look updateoptions.pitch = (options.pitch - mouse_delta.y * RADIANS_PER_DOT * options.sensitivity).clamp(-PI / 2., PI / 2.);options.yaw -= mouse_delta.x * RADIANS_PER_DOT * options.sensitivity;transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, options.yaw, options.pitch);}}
    }
    
  • 再添加一个SceneSetup,用于初始化场景和相机
    use bevy::prelude::*;
    use bevy::app::{Plugin, App, Startup};use crate::camera::CameraController;pub struct SceneSetupPlugin;impl Plugin for SceneSetupPlugin {fn build(&self, app: &mut App) {app.add_systems(Startup, setup);}
    }/// set up a simple 3D scene
    fn setup(mut commands: Commands,mut meshes: ResMut<Assets<Mesh>>,mut materials: ResMut<Assets<StandardMaterial>>,
    ) {// circular basecommands.spawn(PbrBundle {mesh: meshes.add(shape::Circle::new(4.0).into()),material: materials.add(Color::WHITE.into()),transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),..default()});// cubecommands.spawn(PbrBundle {mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),material: materials.add(Color::rgb_u8(124, 144, 255).into()),transform: Transform::from_xyz(0.0, 0.5, 0.0),..default()});// lightcommands.spawn(PointLightBundle {point_light: PointLight {intensity: 1500.0,shadows_enabled: true,..default()},transform: Transform::from_xyz(4.0, 8.0, 4.0),..default()});let camera_controller = CameraController::default();// cameracommands.spawn((Camera3dBundle {transform: Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),..default()},camera_controller));
    }
    
  • 将GamePlugin中的代码修改下进行测试
    impl Plugin for GamePlugin {fn build(&self, app: &mut App) {app.add_state::<GameState>().add_plugins((// LoadingPlugin,// MenuPlugin,SceneSetupPlugin,// ActionsPlugin,// InternalAudioPlugin,// PlayerPlugin,CameraControllerPlugin));#[cfg(debug_assertions)]{app.add_plugins((FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin::default()));}}
    }
    
  • 结果
    在这里插入图片描述

控制方块

  • 上面的测试中我们将游戏流程注释掉了,现在我们尝试加回来,并将方块作为我们的Player
  • 首先将player设置为方块(不要忘记将上面场景中的方块去掉)
    fn spawn_player(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>,mut materials: ResMut<Assets<StandardMaterial>>) {commands.spawn(PbrBundle {mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),material: materials.add(Color::rgb_u8(124, 144, 255).into()),transform: Transform::from_xyz(0.0, 1., 0.0),..default()}).insert(Player);
    }
    
  • 然后将actions中的相机改为3d
    pub fn set_movement_actions(mut actions: ResMut<Actions>,keyboard_input: Res<Input<KeyCode>>,touch_input: Res<Touches>,player: Query<&Transform, With<Player>>,camera: Query<(&Camera, &GlobalTransform), With<Camera3d>>,
    ) {// ...
    }
    
  • 然后我们先去掉menu中的相机
    fn setup_menu(mut commands: Commands, textures: Res<TextureAssets>) {info!("menu");// commands.spawn(Camera2dBundle::default());// ...
    
  • 结果(将move_player中的速度调低点)
    在这里插入图片描述
  • 不过这里我们的ui和场景显示到一块了,后面再看看怎么处理

问题

  • note: LINK : fatal error LNK1189: 超过 65535 对象的库限制
    参考这个解决

这篇关于【rust/bevy】从game template开始的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605329

相关文章

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

Rust 数据类型详解

《Rust数据类型详解》本文介绍了Rust编程语言中的标量类型和复合类型,标量类型包括整数、浮点数、布尔和字符,而复合类型则包括元组和数组,标量类型用于表示单个值,具有不同的表示和范围,本文介绍的非... 目录一、标量类型(Scalar Types)1. 整数类型(Integer Types)1.1 整数字

Rust中的Option枚举快速入门教程

《Rust中的Option枚举快速入门教程》Rust中的Option枚举用于表示可能不存在的值,提供了多种方法来处理这些值,避免了空指针异常,文章介绍了Option的定义、常见方法、使用场景以及注意事... 目录引言Option介绍Option的常见方法Option使用场景场景一:函数返回可能不存在的值场景

fzu 2275 Game KMP

Problem 2275 Game Time Limit: 1000 mSec    Memory Limit : 262144 KB  Problem Description Alice and Bob is playing a game. Each of them has a number. Alice’s number is A, and Bob’s number i

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

第二十四章 rust中的运算符重载

注意 本系列文章已升级、转移至我的自建站点中,本章原文为:rust中的运算符重载 目录 注意一、前言二、基本使用三、常用运算符四、通用约束 一、前言 C/C++中有运算符重载这一概念,它的目的是让即使含不相干的内容也能通过我们自定义的方法进行运算符操作运算。 比如字符串本身是不能相加的,但由于C++中的String重载了运算符+,所以我们就可以将两个字符串进行相加、但实际