upgrade: bevy 0.15, bevy_ratatui_camera 0.8

This commit is contained in:
cxreiff 2025-01-01 15:51:24 -08:00
parent 5e2ae54718
commit c20207815e
8 changed files with 1060 additions and 921 deletions

1428
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -12,10 +12,10 @@ categories = ["command-line-interface"]
keywords = ["bevy", "ratatui", "terminal", "tui", "screensaver"]
[dependencies]
avian2d = "0.1.1"
bevy = "0.14.2"
bevy_ratatui = "0.6.4"
bevy_ratatui_render = "0.6.0"
avian2d = { git = "https://github.com/Jondolf/avian.git", branch = "main" }
bevy = "0.15.0"
bevy_ratatui = "0.7.0"
bevy_ratatui_camera = "0.8.2"
clap = { version = "4.5.13", features = ["derive"] }
rand = "0.8.5"
rand_chacha = "0.3.1"

View file

@ -5,7 +5,7 @@ use avian2d::{
};
use bevy::prelude::*;
use bevy_ratatui::event::ResizeEvent;
use bevy_ratatui_render::RatatuiRenderContext;
use bevy_ratatui_camera::RatatuiCamera;
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;
@ -49,41 +49,36 @@ pub struct BubbleSprite(Handle<Image>);
#[derive(Resource, Deref, DerefMut, Default)]
pub struct BubbleVisibleRegion(Vec2);
#[derive(Bundle)]
pub struct BubbleBundle {
bubble: Bubble,
sprite: SpriteBundle,
rigidbody: RigidBody,
collider: Collider,
locked_axes: LockedAxes,
friction: Friction,
}
impl BubbleBundle {
fn new(rng: &mut BubbleRng, sprite: &BubbleSprite, region: &Rectangle) -> Self {
Self {
bubble: Bubble {
target: region.sample_interior(&mut rng.0),
timer: Timer::from_seconds(3., TimerMode::Repeating),
},
sprite: SpriteBundle {
transform: Transform::from_translation(
region.sample_interior(&mut rng.0).extend(0.),
),
texture: (**sprite).clone(),
sprite: Sprite {
color: Color::hsl(rng.gen_range(0.0..360.0), 1.0, 0.8),
custom_size: Some(Vec2::splat(BUBBLE_RADIUS * 2.)),
..default()
},
..default()
},
rigidbody: RigidBody::Dynamic,
collider: Collider::circle(BUBBLE_RADIUS as Scalar),
locked_axes: LockedAxes::ROTATION_LOCKED,
friction: Friction::new(0.0),
}
}
fn create_bubble(
rng: &mut BubbleRng,
sprite: &BubbleSprite,
region: &Rectangle,
) -> (
Bubble,
Sprite,
Transform,
RigidBody,
Collider,
LockedAxes,
Friction,
) {
(
Bubble {
target: region.sample_interior(&mut rng.0),
timer: Timer::from_seconds(3., TimerMode::Repeating),
},
Sprite {
image: (**sprite).clone(),
color: Color::hsl(rng.gen_range(0.0..360.0), 1.0, 0.8),
custom_size: Some(Vec2::splat(BUBBLE_RADIUS * 2.)),
..default()
},
Transform::from_translation(region.sample_interior(&mut rng.0).extend(0.)),
RigidBody::Dynamic,
Collider::circle(BUBBLE_RADIUS as Scalar),
LockedAxes::ROTATION_LOCKED,
Friction::new(0.0),
)
}
#[derive(Resource, Deref, DerefMut)]
@ -95,15 +90,15 @@ impl Default for BubbleTimer {
}
}
fn bubbles_setup_system(
mut commands: Commands,
ratatui_render: Res<RatatuiRenderContext>,
asset_server: Res<AssetServer>,
) {
let mut camera = Camera2dBundle::default();
camera.projection.scale = ORTHO_SCALING;
camera.camera.target = ratatui_render.target("main").unwrap_or_default();
commands.spawn(camera);
fn bubbles_setup_system(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
Camera2d,
Projection::Orthographic(OrthographicProjection {
scale: ORTHO_SCALING,
..OrthographicProjection::default_2d()
}),
RatatuiCamera::autoresize(),
));
let rng = ChaCha8Rng::seed_from_u64(19878367467712);
commands.insert_resource(BubbleRng(rng));
@ -126,7 +121,7 @@ fn bubbles_spawn_system(
timer.tick(time.delta());
if timer.finished() && *count < **spawn_amount {
*count += 1;
commands.spawn(BubbleBundle::new(
commands.spawn(create_bubble(
&mut rng,
&sprite,
&Rectangle::from_size(**visible_region - BUBBLE_RADIUS * 2.),
@ -138,10 +133,9 @@ fn handle_resize_system(
mut resize_events: EventReader<ResizeEvent>,
mut visible_region: ResMut<BubbleVisibleRegion>,
mut spawn_amount: ResMut<BubbleAmount>,
ratatui_render: Res<RatatuiRenderContext>,
) {
for _ in resize_events.read() {
let (width, height) = ratatui_render.dimensions("main").unwrap();
for resize in resize_events.read() {
let (width, height) = (resize.width * 2, resize.height * 4);
let terminal_dimensions = Vec2::new(width as f32, height as f32);
**visible_region = terminal_dimensions * ORTHO_SCALING;
**spawn_amount = ((visible_region.x * visible_region.y) / 777.) as u32;
@ -170,7 +164,7 @@ fn bubble_movement_system(
bubble.target = bubble
.target
.move_towards(next_point, time.delta_seconds() * 10.);
.move_towards(next_point, time.delta_secs() * 10.);
**velocity += diff * 0.01;
**velocity = velocity.clamp(
@ -183,7 +177,7 @@ fn bubble_movement_system(
fn bubble_color_system(time: Res<Time>, mut bubbles: Query<&mut Sprite, With<Bubble>>) {
for mut sprite in &mut bubbles {
let new_hue = (sprite.color.hue() + time.delta_seconds() * 10.) % 360.;
let new_hue = (sprite.color.hue() + time.delta_secs() * 10.) % 360.;
sprite.color.set_hue(new_hue);
}
}

View file

@ -1,233 +0,0 @@
use avian2d::{
math::{Scalar, Vector},
prelude::{Collider, Gravity, RigidBody},
PhysicsPlugins,
};
use bevy::{prelude::*, render::camera::ScalingMode};
use bevy_ratatui::event::ResizeEvent;
use bevy_ratatui_render::RatatuiRenderContext;
use rand::{seq::IteratorRandom, Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;
const ORTHO_SCALING: f32 = 32.;
const BUBBLE_RATE: f32 = 1.;
const BUBBLE_MAX: u32 = 16;
const BUBBLE_RADIUS: f32 = 0.75;
pub(super) fn plugin(app: &mut App) {
app.add_plugins(PhysicsPlugins::default())
.insert_resource(Gravity(Vector::ZERO))
.init_resource::<BubbleVisibleRegion>()
.add_systems(Startup, bubbles_setup_system)
.add_systems(Update, (bubbles_spawn_system, handle_resize_system));
}
#[derive(Component)]
pub struct Bubble;
#[derive(Resource, Deref, DerefMut)]
pub struct BubbleRng(ChaCha8Rng);
#[derive(Resource, Deref)]
pub struct BubbleMaterials(Vec<Handle<StandardMaterial>>);
#[derive(Resource, Deref)]
pub struct BubbleMesh(Handle<Mesh>);
#[derive(Resource, Deref, Default)]
pub struct BubbleVisibleRegion(Vec2);
#[derive(Bundle)]
pub struct BubbleBundle {
bubble: Bubble,
pbr: PbrBundle,
rigidbody: RigidBody,
collider: Collider,
}
impl BubbleBundle {
fn new(
rng: &mut BubbleRng,
materials: &BubbleMaterials,
mesh: &BubbleMesh,
region: &Rectangle,
) -> Self {
Self {
bubble: Bubble,
pbr: PbrBundle {
transform: Transform::from_translation(
region.sample_interior(&mut rng.0).extend(0.),
),
material: materials
.iter()
.choose(&mut rng.0)
.expect("bubble materials were not generated.")
.clone(),
mesh: mesh.0.clone(),
..default()
},
rigidbody: RigidBody::Dynamic,
collider: Collider::circle(BUBBLE_RADIUS as Scalar),
}
}
}
#[derive(Resource, Deref, DerefMut)]
pub struct BubbleTimer(Timer);
impl Default for BubbleTimer {
fn default() -> Self {
Self(Timer::from_seconds(BUBBLE_RATE, TimerMode::Repeating))
}
}
#[derive(Component)]
pub struct BubbleTopWall;
#[derive(Component)]
pub struct BubbleBottomWall;
#[derive(Component)]
pub struct BubbleLeftWall;
#[derive(Component)]
pub struct BubbleRightWall;
fn bubbles_setup_system(
mut commands: Commands,
ratatui_render: Res<RatatuiRenderContext>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(Camera3dBundle {
camera: Camera {
target: ratatui_render.target("main").unwrap_or_default(),
..default()
},
projection: Projection::Orthographic(OrthographicProjection {
scaling_mode: ScalingMode::WindowSize(ORTHO_SCALING),
..default()
}),
transform: Transform::from_xyz(0., 0., 5.).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(0., 0., -5.),
point_light: PointLight {
intensity: 10_000.,
shadows_enabled: true,
..default()
},
..default()
});
let mut rng = ChaCha8Rng::seed_from_u64(19878367467712);
commands.insert_resource(BubbleMaterials(
(0..8)
.map(|_| {
materials.add(StandardMaterial {
base_color: Color::hsl(rng.gen_range(0.0..360.0), 1.0, 0.8),
specular_transmission: 0.9,
diffuse_transmission: 1.0,
thickness: 1.8,
ior: 1.5,
perceptual_roughness: 0.12,
..default()
})
})
.collect(),
));
commands.insert_resource(BubbleRng(rng));
commands.insert_resource(BubbleMesh(meshes.add(Sphere::new(BUBBLE_RADIUS))));
let wall_bundle = (
PbrBundle {
mesh: meshes.add(Cuboid::from_size(Vec3::new(1., 1., 1.))),
material: materials.add(StandardMaterial::default()),
..default()
},
RigidBody::Static,
Collider::rectangle(0.95, 0.95),
);
commands.spawn((wall_bundle.clone(), BubbleBottomWall));
commands.spawn((wall_bundle.clone(), BubbleTopWall));
commands.spawn((wall_bundle.clone(), BubbleLeftWall));
commands.spawn((wall_bundle.clone(), BubbleRightWall));
}
#[allow(clippy::too_many_arguments)]
fn bubbles_spawn_system(
mut commands: Commands,
time: Res<Time>,
mut rng: ResMut<BubbleRng>,
materials: Res<BubbleMaterials>,
mesh: Res<BubbleMesh>,
visible_region: Res<BubbleVisibleRegion>,
mut timer: Local<BubbleTimer>,
mut count: Local<u32>,
) {
timer.tick(time.delta());
if timer.finished() && *count < BUBBLE_MAX {
*count += 1;
commands.spawn(BubbleBundle::new(
&mut rng,
&materials,
&mesh,
&Rectangle::from_size(**visible_region - BUBBLE_RADIUS * 2.),
));
}
}
type BottomWallQuery = (
With<BubbleBottomWall>,
Without<BubbleTopWall>,
Without<BubbleLeftWall>,
Without<BubbleRightWall>,
);
type TopWallQuery = (
With<BubbleTopWall>,
Without<BubbleBottomWall>,
Without<BubbleLeftWall>,
Without<BubbleRightWall>,
);
type LeftWallQuery = (
With<BubbleLeftWall>,
Without<BubbleBottomWall>,
Without<BubbleTopWall>,
Without<BubbleRightWall>,
);
type RightWallQuery = (
With<BubbleRightWall>,
Without<BubbleBottomWall>,
Without<BubbleTopWall>,
Without<BubbleLeftWall>,
);
fn handle_resize_system(
mut resize_events: EventReader<ResizeEvent>,
mut visible_region: ResMut<BubbleVisibleRegion>,
ratatui_render: Res<RatatuiRenderContext>,
mut bottom_wall: Query<&mut Transform, BottomWallQuery>,
mut top_wall: Query<&mut Transform, TopWallQuery>,
mut left_wall: Query<&mut Transform, LeftWallQuery>,
mut right_wall: Query<&mut Transform, RightWallQuery>,
) {
for _ in resize_events.read() {
let (width, height) = ratatui_render.dimensions("main").unwrap();
let terminal_dimensions = Vec2::new(width as f32, height as f32);
visible_region.0 = terminal_dimensions / ORTHO_SCALING;
bottom_wall.single_mut().translation = Vec3::new(0.0, -visible_region.y / 2., 0.0);
bottom_wall.single_mut().scale = Vec3::new(visible_region.x, 0.5, 1.0);
top_wall.single_mut().translation = Vec3::new(0.0, visible_region.y / 2., 0.0);
top_wall.single_mut().scale = Vec3::new(visible_region.x, 0.5, 1.0);
left_wall.single_mut().translation = Vec3::new(-visible_region.x / 2., 0.0, 0.0);
left_wall.single_mut().scale = Vec3::new(0.5, visible_region.y, 1.0);
right_wall.single_mut().translation = Vec3::new(visible_region.x / 2., 0.0, 0.0);
right_wall.single_mut().scale = Vec3::new(0.5, visible_region.y, 1.0);
}
}

View file

@ -4,7 +4,7 @@ use bevy::utils::error;
use bevy::{diagnostic::DiagnosticsStore, prelude::*};
use bevy_ratatui::event::{KeyEvent, MouseEvent};
use bevy_ratatui::terminal::RatatuiContext;
use bevy_ratatui_render::RatatuiRenderContext;
use bevy_ratatui_camera::RatatuiCameraWidget;
use crate::Flags;
@ -21,23 +21,13 @@ pub(super) fn plugin(app: &mut App) {
fn draw_scene_system(
mut ratatui: ResMut<RatatuiContext>,
ratatui_render: Res<RatatuiRenderContext>,
widget: Query<&RatatuiCameraWidget>,
_flags: Res<Flags>,
_diagnostics: Res<DiagnosticsStore>,
) -> io::Result<()> {
ratatui.draw(|frame| {
if let Some(widget) = ratatui_render.widget("main") {
if let Ok(widget) = widget.get_single() {
frame.render_widget(widget, frame.area());
// frame.render_widget(
// Paragraph::new(flags.msgs.join("\n")).fg(Color::DarkBlue),
// ratatui::layout::Rect {
// x: 1,
// y: 1,
// width: 30,
// height: 30,
// },
// );
}
})?;

View file

@ -4,7 +4,7 @@ use bevy::prelude::*;
use bevy::winit::WinitPlugin;
use bevy::{app::ScheduleRunnerPlugin, log::LogPlugin};
use bevy_ratatui::RatatuiPlugins;
use bevy_ratatui_render::RatatuiRenderPlugin;
use bevy_ratatui_camera::RatatuiCameraPlugin;
use logo::LogoPath;
pub use logo::{LOGO_PATH_DVD, LOGO_PATH_TTY};
use maze::MazePaths;
@ -30,9 +30,8 @@ impl Plugin for AppPlugin {
.disable::<LogPlugin>(),
ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1. / 60.)),
RatatuiPlugins::default(),
RatatuiRenderPlugin::new("main", (256, 256)).autoresize(),
RatatuiCameraPlugin,
))
.insert_resource(Msaa::Off)
.init_resource::<Flags>();
app.add_plugins((assets::plugin, common::plugin));

View file

@ -1,12 +1,13 @@
use bevy::prelude::*;
use bevy_ratatui::event::ResizeEvent;
use bevy_ratatui_render::RatatuiRenderContext;
use bevy_ratatui_camera::RatatuiCamera;
use rand::SeedableRng;
use rand_chacha::ChaCha8Rng;
pub const LOGO_PATH_DVD: &str = "embedded://ttysvr/../assets/dvd_logo.png";
pub const LOGO_PATH_TTY: &str = "embedded://ttysvr/../assets/tty_logo.png";
const STARTING_DIMENSIONS: (u32, u32) = (256, 256);
const ORTHO_SCALING: f32 = 0.5;
const LOGO_RADIUS: f32 = 32.;
const LOGO_SPEED: f32 = 24.;
@ -29,61 +30,47 @@ pub struct LogoPath(pub String);
#[derive(Resource, Deref, DerefMut, Default)]
struct LogoVisibleRegion(Vec2);
#[derive(Bundle)]
struct LogoBundle {
logo: Logo,
sprite: SpriteBundle,
}
impl LogoBundle {
fn new(rng: &mut ChaCha8Rng, texture: Handle<Image>, region: Rectangle) -> Self {
Self {
logo: Logo {
velocity: Vec2::new(LOGO_SPEED, -LOGO_SPEED),
},
sprite: SpriteBundle {
transform: Transform::from_translation(region.sample_interior(rng).extend(0.)),
texture,
sprite: Sprite {
color: Color::hsl(0., 1.0, 0.6),
custom_size: Some(Vec2::splat(LOGO_RADIUS * 2.)),
..default()
},
..default()
},
}
}
}
fn logo_setup_system(
mut commands: Commands,
ratatui_render: Res<RatatuiRenderContext>,
asset_server: Res<AssetServer>,
mut visible_region: ResMut<LogoVisibleRegion>,
logo_path: Res<LogoPath>,
) {
let mut camera = Camera2dBundle::default();
camera.projection.scale = ORTHO_SCALING;
camera.camera.target = ratatui_render.target("main").unwrap_or_default();
commands.spawn(camera);
commands.spawn((
RatatuiCamera::autoresize().with_dimensions(STARTING_DIMENSIONS),
Camera2d,
OrthographicProjection {
scale: ORTHO_SCALING,
..OrthographicProjection::default_2d()
},
));
**visible_region = get_visible_region(&ratatui_render);
let texture = asset_server.load(&**logo_path);
**visible_region = get_visible_region(STARTING_DIMENSIONS);
let image = asset_server.load(&**logo_path);
let mut rng = ChaCha8Rng::seed_from_u64(19878367467712);
commands.spawn(LogoBundle::new(
&mut rng,
texture,
Rectangle::from_size(**visible_region * 0.5 - LOGO_RADIUS * 2.),
let region = Rectangle::from_size(**visible_region * 0.5 - LOGO_RADIUS * 2.);
commands.spawn((
Logo {
velocity: Vec2::new(LOGO_SPEED, -LOGO_SPEED),
},
Sprite {
image,
color: Color::hsl(0., 1., 0.6),
custom_size: Some(Vec2::splat(LOGO_RADIUS * 2.)),
..default()
},
Transform::from_translation(region.sample_interior(&mut rng).extend(0.)),
));
}
fn handle_resize_system(
mut resize_events: EventReader<ResizeEvent>,
mut visible_region: ResMut<LogoVisibleRegion>,
ratatui_render: Res<RatatuiRenderContext>,
) {
for _ in resize_events.read() {
**visible_region = get_visible_region(&ratatui_render);
for resize in resize_events.read() {
let (width, height) = (resize.width * 2, resize.height * 4);
**visible_region = get_visible_region((width as u32, height as u32));
}
}
@ -96,7 +83,7 @@ fn logo_movement_system(
let visible_area = Rectangle::from_size(**visible_region - LOGO_RADIUS * 1.95);
let visible_half = visible_area.half_size.extend(0.);
transform.translation += velocity.extend(0.) * time.delta_seconds();
transform.translation += velocity.extend(0.) * time.delta_secs();
if (transform.translation.x < -visible_half.x && velocity.x < 0.)
|| (transform.translation.x > visible_half.x && velocity.x > 0.)
@ -116,8 +103,7 @@ fn logo_movement_system(
}
}
fn get_visible_region(ratatui_render: &RatatuiRenderContext) -> Vec2 {
let (width, height) = ratatui_render.dimensions("main").unwrap();
fn get_visible_region((width, height): (u32, u32)) -> Vec2 {
let terminal_dimensions = Vec2::new(width as f32, height as f32);
terminal_dimensions * ORTHO_SCALING
}

View file

@ -1,8 +1,7 @@
use std::collections::BTreeMap;
use std::{collections::BTreeMap, f32::consts::PI};
use avian2d::math::PI;
use bevy::prelude::*;
use bevy_ratatui_render::RatatuiRenderContext;
use bevy_ratatui_camera::RatatuiCamera;
use rand::{seq::SliceRandom, thread_rng};
pub const MAZE_WALL_PATH_BRICK: &str = "embedded://ttysvr/../assets/maze_wall_brick.png";
@ -22,8 +21,8 @@ type MazeGraph = BTreeMap<(i32, i32), (bool, bool, bool, bool)>;
const MAZE_SIZE: i32 = 12;
const MAZE_SCALE: f32 = 1.0;
const MAZE_WALK_SPEED: f32 = 1.5;
const MAZE_TURN_SPEED: f32 = 2.5;
const MAZE_WALK_SPEED: f32 = 0.4;
const MAZE_TURN_SPEED: f32 = 2.0;
const WALL_DIMENSIONS: Vec3 = Vec3::new(1.0, 0.01, 1.0);
const DIRECTION_LIST: &[MazeDirection] = &[
MazeDirection::North,
@ -111,7 +110,6 @@ fn maze_generation_system(mut commands: Commands) {
fn maze_setup_system(
mut commands: Commands,
ratatui_render: Res<RatatuiRenderContext>,
maze: Res<Maze>,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
@ -150,89 +148,72 @@ fn maze_setup_system(
let translation = target_to_vec3((*x, *y));
if !*north {
let transform =
Transform::default().with_translation(translation + Vec3::Y * MAZE_SCALE * 0.5);
commands.spawn(PbrBundle {
transform,
mesh: wall_mesh.clone(),
material: wall_material.clone(),
..default()
});
commands.spawn((
Transform::default().with_translation(translation + Vec3::Y * MAZE_SCALE * 0.5),
Mesh3d(wall_mesh.clone()),
MeshMaterial3d(wall_material.clone()),
));
}
if !*east {
let transform = Transform::default()
.with_translation(translation + Vec3::X * MAZE_SCALE * 0.5)
.with_rotation(Quat::from_rotation_z(PI / 2.));
commands.spawn(PbrBundle {
transform,
mesh: wall_mesh.clone(),
material: wall_material.clone(),
..default()
});
commands.spawn((
Transform::default()
.with_translation(translation + Vec3::X * MAZE_SCALE * 0.5)
.with_rotation(Quat::from_rotation_z(PI / 2.)),
Mesh3d(wall_mesh.clone()),
MeshMaterial3d(wall_material.clone()),
));
}
if !*south && *y == 0 {
let transform = Transform::default()
.with_translation(translation - Vec3::Y * MAZE_SCALE * 0.5)
.with_rotation(Quat::from_rotation_z(PI));
commands.spawn(PbrBundle {
transform,
mesh: wall_mesh.clone(),
material: wall_material.clone(),
..default()
});
commands.spawn((
Transform::default()
.with_translation(translation - Vec3::Y * MAZE_SCALE * 0.5)
.with_rotation(Quat::from_rotation_z(PI)),
Mesh3d(wall_mesh.clone()),
MeshMaterial3d(wall_material.clone()),
));
}
if !*west && *x == 0 {
let transform = Transform::default()
.with_translation(translation - Vec3::X * MAZE_SCALE * 0.5)
.with_rotation(Quat::from_rotation_z(PI * 3. / 2.));
commands.spawn(PbrBundle {
transform,
mesh: wall_mesh.clone(),
material: wall_material.clone(),
..default()
});
commands.spawn((
Transform::default()
.with_translation(translation - Vec3::X * MAZE_SCALE * 0.5)
.with_rotation(Quat::from_rotation_z(PI * 3. / 2.)),
Mesh3d(wall_mesh.clone()),
MeshMaterial3d(wall_material.clone()),
));
}
commands.spawn(PbrBundle {
transform: Transform::default()
commands.spawn((
Transform::default()
.with_translation(translation - Vec3::Z * 0.5 * MAZE_SCALE * WALL_DIMENSIONS.z),
mesh: floor_ceiling_mesh.clone(),
material: floor_material.clone(),
..default()
});
Mesh3d(floor_ceiling_mesh.clone()),
MeshMaterial3d(floor_material.clone()),
));
commands.spawn(PbrBundle {
transform: Transform::default()
commands.spawn((
Transform::default()
.with_translation(translation + Vec3::Z * 0.5 * MAZE_SCALE * WALL_DIMENSIONS.z),
mesh: floor_ceiling_mesh.clone(),
material: ceiling_material.clone(),
..default()
});
Mesh3d(floor_ceiling_mesh.clone()),
MeshMaterial3d(ceiling_material.clone()),
));
}
commands
.spawn(Camera3dBundle {
camera: Camera {
target: ratatui_render.target("main").unwrap_or_default(),
..default()
},
projection: Projection::Perspective(PerspectiveProjection {
.spawn((
Msaa::Sample8,
RatatuiCamera::autoresize().with_autoresize_fn(|(w, h)| (w * 4, h * 4)),
Camera3d::default(),
Projection::Perspective(PerspectiveProjection {
fov: PI / 2.,
..default()
}),
transform: Transform::from_translation(Vec3::new(0., 0., 0.))
.looking_at(Vec3::new(0., 1., 0.), Vec3::Z),
..default()
})
Transform::default().looking_at(Vec3::Y, Vec3::Z),
))
.with_children(|commands| {
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 10_000.,
..default()
},
commands.spawn(PointLight {
intensity: 10_000.,
..default()
});
});
@ -242,9 +223,9 @@ fn movement_system(
time: Res<Time>,
maze: Res<Maze>,
mut target: ResMut<MazeTarget>,
mut camera: Query<&mut Transform, With<Camera>>,
mut camera: Query<&mut Transform, With<Camera3d>>,
) {
let delta = time.delta_seconds();
let delta = time.delta_secs();
let mut camera_transform = camera.single_mut();
let target_vec = target_to_vec3(**target);