【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 input
            let 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 update
            if 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 input
            let 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 update
                options.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 base
        commands.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()
        });
        // cube
        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, 0.5, 0.0),
            ..default()
        });
        // light
        commands.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();
        // camera
        commands.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 对象的库限制
    参考这个解决

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/321174.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jetpack Flow 、Room 初学者学习记录

学习使用响应式Flow操作数据&#xff0c;记录自己学习的过程。 ContactViewModel 是一个 ViewModel&#xff0c;它依赖于一个Room操作接口 ContactDao &#xff0c;访问对象来获取联系人数据。它使用了 StateFlow 来处理状态的变化和数据的更新。ViewModels 通常用于管理应用的…

emc防护原理

emc原理 emc设计的根本是对于干扰电流的阻塞和疏导。通过阻抗变化来实现对于特定频率的电流的防护。 emc设计 在485等信号线emc实验中&#xff0c;一般使用8us/20us的脉冲波形进行浪涌信号线实验即可。在特殊场景&#xff08;军品&#xff09;会使用到更高等级的浪涌实验&am…

在illustrator中按大小尺寸选择物体 <脚本 018>

在Illustrator中我们可以依据对象的属性 如&#xff1a;填充颜色、描边颜色或描边宽度来选择相同属性的对象&#xff0c;但是Illustrator中没有根据不同大小尺寸来选择对象的功能&#xff0c;下面介绍的就是根据大小尺寸选择对象的脚本。 1、下面是当前画板中的所有对象&#…

Linux远程登陆协议ssh

目录 一、SSH服务 1. ssh基础 2. 原理 3. 服务端配置 3.1 常用配置项 3.2 具体操作 3.2.1 修改默认端口号 3.2.2 禁止root用户登录 3.2.3 白名单列表 3.2.4 黑名单列表 3.2.5 使用秘钥对及免交互验证登录 3.2.6 免交互式登录 一、SSH服务 1. ssh基础 SSH&…

【嘿,“怪”回来了】半年未见,好久不见。新年伊始,共赴新约。

您的阅读概要&#xff1a; 故事的开头总是极尽温柔&#xff0c;故事会一直温柔……半年未见&#xff0c;好久不见新年伊始&#xff0c;共赴新约忙碌的敲代码也不要忘了浪漫呀 故事的开头总是极尽温柔&#xff0c;故事会一直温柔…… ✨【自我介绍】&#xff1a;你好&#xff0c…

【数据库】间隙锁Gap Lock

什么是间隙锁 间隙锁&#xff08;Gap Lock&#xff09;&#xff1a;间隙锁是&#xff08;RR级别下&#xff09;一个在索引记录之间的间隙上的锁&#xff0c;可以是两个索引记录之间&#xff0c;也可能是第一个索引记录之前或最后一个索引之后的空间。间隙锁&#xff08;Gap Lo…

【数据结构与算法】之数组系列-20240115

这里写目录标题 一、599. 两个列表的最小索引总和二、724. 寻找数组的中心下标三、面试题 16.11. 跳水板四、35. 搜索插入位置 一、599. 两个列表的最小索引总和 简单 假设 Andy 和 Doris 想在晚餐时选择一家餐厅&#xff0c;并且他们都有一个表示最喜爱餐厅的列表&#xff0c…

vue项目之.env文件.env.dev、test、pro

.env文件是vue运行项目时的环境配置文件。 .env: 全局默认配置文件&#xff0c;所有环境(开发、测试、生产等&#xff09;均会加载并合并该文件 .env.development(开发环境默认命名) 开发环境的配置&#xff0c;文件名默认为.env.development,如果需要改名也是可以的&#xf…

记录误删除docker中极狐gitlab容器恢复过程

如题一次误操作导致删除了docker中极狐gitlab容器恢复过程 情况说明 创建容器时&#xff0c;我是用的是极狐官网推荐安装的步骤&#xff0c;具体按照官网步骤走就行 sudo docker run --detach \--hostname gitlab.example.com \--publish 443:443 --publish 80:80 --publish …

steam搬砖项目赚钱吗?低门槛副业月入5k真的假的?

steam搬砖项目一开始默默无闻&#xff0c;现在越来越受欢迎&#xff0c;因为大家都看到了该项目的长期稳定性。 steam搬砖项目主要是搬csgo游戏装备和道具&#xff0c;从steam购买&#xff0c;在网易Buff上出售&#xff0c;赚取差价。只需少量投资&#xff0c;即可获得长期稳定…

港大谷歌提出GO-NeRF:在NeRF中生成协调且高质量的3D对象

尽管在3D生成方面取得了进展&#xff0c;但在作为NeRF表示的现有3D场景中直接创建3D对象仍然是未经探索的。这个过程不仅需要高质量的3D对象生成&#xff0c;还需要将生成的3D内容无缝地合成到现有的NeRF中。为此&#xff0c;作者提出了一种新方法&#xff0c;GO-NeRF&#xff…

C++深入学习之STL:1、容器部分

标准模板库STL的组成 主要由六大基本组件组成&#xff1a;容器、迭代器、算法、适配器、函数对象(仿函数)以及空间配置器。 容器&#xff1a;就是用来存数据的&#xff0c;也称为数据结构。 本文要详述的是容器主要如下&#xff1a; 序列式容器&#xff1a;vector、list 关联…

AC修炼计划(AtCoder Beginner Contest 335)E-F

传送门&#xff1a; AtCoder Beginner Contest 335 (Sponsored by Mynavi) - AtCoder A&#xff0c;B&#xff0c;C&#xff0c;D还算比较基础&#xff0c;没有什么思路&#xff0c;纯暴力就可以过。 这里来总结一下E和F E - Non-Decreasing Colorful Path 最开始以为是树形…

顶级Web应用程序测试工具列表

今天主要列举Web应用程序的工具。 今天的列表仅仅提供索引功能&#xff0c;具体要使用的同学&#xff0c;可以自行搜索哦。 通过web应用程序测试&#xff0c;在web应用程序公开发布之前&#xff0c;会发现网站功能、安全性、可访问性、可用性、兼容性和性能等问题。 Web应用程…

细说JavaScript语句详解

一、顺序结构 二、表达式语句 三、声明语句 四、条件语句 1、if语句 2、if…else语句 3、else if语句 4、switch语句 五、循环语句 1、while循环 2、do… while循环 3、for循环 4、for…in循环 六、跳出语句 1、label语句 2、break语句 3、continue语句

【MySQL】基础篇

文章目录 一、SQL规则与规范二、基本的SELECT语句SELECT...FROM...;列的别名 AS ""去除重复行 DISTINCT空值参与运算 结果一定也为NULL着重号 常量描述表结构 DESCRIBE过滤数据 WHERE 三、运算符算术运算符比较运算符非符号类型运算符逻辑运算符运算符优先级 四、排序…

Git 是什么?

Git 是什么&#xff1f; Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;…

ubuntu 2022.04 安装vcs2018和verdi2018

主要参考网站朋友们的作业。 安装时参考&#xff1a; ubuntu18.04安装vcs、verdi2018_ubuntu安装vcs-CSDN博客https://blog.csdn.net/qq_24287711/article/details/130017583 编译时参考&#xff1a; 【ASIC】VCS报Error-[VCS_COM_UNE] Cannot find VCS compiler解决方法_e…

陶瓷碗口缺口检测-图像分割

图像分割 由于对碗口进行缺口检测&#xff0c;因此只需要碗口的边界信息。得到陶瓷碗区域填充后的图像&#xff0c;对图像进行边缘检测。这是属于图像分割中的内容&#xff0c;在图像的边缘中&#xff0c;可以利用导数算子对数字图像求差分&#xff0c;将边缘提取出来。 本案…

电流检测方法

电路检测电路常用于&#xff1a;高压短路保护、电机控制、DC/DC换流器、系统功耗管理、二次电池的电流管理、蓄电池管理等电流检测等场景。 对于大部分应用&#xff0c;都是通过感测电阻两端的压降测量电流。 一般使用电流通过时的压降为数十mV&#xff5e;数百mV的电阻值&…