【rust/bevy】从game template开始

news2025/2/27 5:29:45

目录

  • 说在前面
  • 步骤
  • 进入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 对象的库限制
    参考这个解决

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker运行RabbitMQ并使用SpringAMQP操作

文章目录 一、RabbitMQ运行二、整合SpringAMQP1. 引入依赖 三、测试1. 消费者2. 生产者3. 运行 一、RabbitMQ运行 拉取docker镜像 docker pull rabbitmq:3-management基础运行命令 docker run \-e RABBITMQ_DEFAULT_USERrabbitmq \-e RABBITMQ_DEFAULT_PASSrabbitmq \--name…

高效办公:如何通过在文件名称右边添加关键字提升工作效率

在繁忙的办公环境中&#xff0c;经常要处理大量的文件和资料。那如何管理和查找这些文件呢&#xff0c;常见的方法有在文件名称右边添加关键字。下面来看云炫文件管理器如何通过在文件名称右边添加关键字来提升工作效率。 在文件名称右边添加关键字前后效果图。 文件名批量添加…

Blazor 的基本原理探索

背景 为了提升开发效率&#xff0c;关键是对js不够熟悉&#xff0c;所以要使用C#进行全栈的开发&#xff0c;使用了mudblazor和radzen blazor&#xff0c;以及可能会用到其他的blazor组件&#xff0c;所有很有必要对blazor有个比较全面的不求甚解&#xff0c;其基本原理以及bl…

AI-数学-高中-5.求函数解析式(4种方法)

原作者视频&#xff1a;函数】3函数解析式求法&#xff08;易&#xff09;_哔哩哔哩_bilibili 1.已知函数类型-待定系数法&#xff1a;先用待定系数法把一次或二次函数一般表达式写出来&#xff1b;再用“要变一起变”左右两边同时替换&#xff0c;计算出一般表达式的常数&…

(分享) 音乐软件Spotify-声破天8.9.4

​【应用名称】&#xff1a;Spotify-声破天 ​【适用平台】&#xff1a;#Android ​【软件标签】&#xff1a;#Spotify ​【应用版本】&#xff1a;8.8.96 → 8.9.4 ​【应用大小】&#xff1a;67MB ​【软件说明】&#xff1a;软件升级更新。iOS可配合qx小火箭类的工具对…

P1179 [NOIP2010 普及组] 数字统计————C++

目录 [NOIP2010 普及组] 数字统计题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 解题思路Code1Code2运行结果 [NOIP2010 普及组] 数字统计 题目描述 请统计某个给定范围 [ L , R ] [L, R] [L,R] 的所有整数中&#xff0c;数字…

ivrobot乐高EV3 鲸鱼 能力风暴自制遥控手柄库文件和编程样例 使用指南

编程示例&#xff1a; 资源下载链接&#xff1a; https://download.csdn.net/download/abilix_tony/88739582 EV3 mindstorms能用基础版和高阶版&#xff08;条形编程界面&#xff09; EV3 classroom只能用基础版 &#xff08;scratch模块形状编程界面&#xff09; 请根据使…

基于Xilinx K7-410T的高速DAC之AD9129开发笔记(二)

引言&#xff1a;上一篇文章我们简单介绍了AD9129的基础知识&#xff0c;包括芯片的重要特性&#xff0c;外部接口相关的信号特性等。本篇我们重点介绍下项目中FPGA与AD9129互联的原理图设计&#xff0c;包括LVDS IO接口设计、时钟电路以、供电设计以及PCB设计。 LVDS数据接口设…

设计一个简单的规则引擎

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

史诗级长文--朴素贝叶斯

引言 朴素贝叶斯算法是有监督的学习算法&#xff0c;解决的是分类问题&#xff0c;如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但由于该算法以自变量之间的独立&am…

VC++中使用OpenCV读取图像、读取本地视频、读取摄像头并实时显示

VC中使用OpenCV读取图像、读取本地视频、读取摄像头并实时显示 最近闲着跟着油管博主murtazahassan&#xff0c;学习了一下LEARN OPENCV C in 4 HOURS | Including 3x Projects | Computer Vision&#xff0c;对应的Github源代码地址为&#xff1a;Learn-OpenCV-cpp-in-4-Hour…

Java重修第五天—面向对象3

通过学习本篇文章可以掌握如下知识 1、多态&#xff1b; 2、抽象类&#xff1b; 3、接口。 之前已经学过了继承&#xff0c;static等基础知识&#xff0c;这篇文章我们就开始深入了解面向对象多态、抽象类和接口的学习。 多态 多态是在继承/实现情况下的一种现象&#xf…

STM32 定时器输入捕获2——捕获高电平时长

由上图我们可以知道&#xff0c;高电平时间t2-t1。在代码中&#xff0c;可以记录此时t1的时间然后再记录t2的时间&#xff0c;t2-t1&#xff0c;就是我们所想要的答案。 但是&#xff0c;还有更简单一点点的&#xff0c;当到达t1的时候&#xff0c;我们把定时器清零&#xff0c…

Edge浏览器入门

关于作者&#xff1a; CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP&#xff0c;带领团队单日营收超千万。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业化变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览…

【C++11】Lambda 表达式

Lambda表达式简介 Lambda 表达式是 C11 中语法之一Lambda 表达式把函数看作对象&#xff0c;把这个表达式当做对象使用Lambda 表达式可以赋值给变量&#xff0c;也可以当做参数传给真正的函数 Lambda表达式语法解析 [capture-list] (parameters) mutable -> return-type {…

【汇编要笑着学】汇编模块化编程 | call和ret调用指令 | jmp跳转指令 | inc自加指令

Ⅰ.汇编模块化编程 0x00 一个简单的例子 我们了解模块化编程前先给出一个例子&#xff0c;方便大家快速了解。 SECTION MBR vstart0x7c00 ; 起始地址编译在0x7c00mov ax,cs mov ds,ax mov es,axmov ss,axmov fs,axmov sp,0x7c00 ; 上面这些都没什…

低代码开发平台

低代码开发平台&#xff08;LCDP&#xff09;本身也是一种软件&#xff0c;它为开发者提供了一个创建应用软件的开发环境。看到“开发环境”几个字是不是很亲切&#xff1f;对于程序员而言&#xff0c;低代码开发平台的性质与IDEA、VS等代码IDE&#xff08;集成开发环境&#x…

Python 自学(八) 之模块

目录 1. import语句导入模块 P206 2. from ... import 语句导入模块 P207 3. 模块的搜索目录 sys.path P209 4. 以主程序的形式执行 __name__ P212 5. python中的包 P213 1. import语句导入模块 P206 同一目录下&…

centos7下搭建ldap服务器

参考&#xff1a; 全网最全Centos7.9搭建LDAP服务器图形界面_ldap服务器搭建-CSDN博客 LDAP服务搭建 - 简书 https://www.cnblogs.com/netsa/p/16017326.html 安装 #安装ldap服务 yum install -y openldap-servers openldap-clients openldap openldap-devel compat-openl…

centos docker-compose安装教程-2024最新版 亲测可用

目录 长时间不安装,生疏了,再次记录下 1.下载 2.修改名称 3.提权 4.测试验证 长时间不安装,生疏了,再次记录下 1.下载 官网地址 docker-compose官网地址&#xff1a;https://docs.docker.com/compose/compose-file/compose-file-v3/ #进入目录 cd /usr/local/bin#下载 wg…