1use std::time::Duration;
2
3use bevy::app::AppExit;
4use bevy::app::ScheduleRunnerPlugin;
5use bevy::log::LogPlugin;
6use bevy::prelude::*;
7use bevy::winit::WinitPlugin;
8use bevy_ratatui::event::KeyEvent;
9use bevy_ratatui::RatatuiPlugins;
10use bevy_ratatui_render::{RatatuiRenderContext, RatatuiRenderPlugin};
11use crossterm::event::{KeyCode, KeyEventKind};
12
13#[derive(Component)]
14pub struct Cube;
15
16fn main() {
17 App::new()
18 .add_plugins((
19 DefaultPlugins
20 .set(ImagePlugin::default_nearest())
21 .disable::<WinitPlugin>()
22 .disable::<LogPlugin>(),
23 ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1. / 60.)),
24 RatatuiPlugins::default(),
25 RatatuiRenderPlugin::new("main", (256, 256))
26 .print_full_terminal()
27 .autoresize()
28 .autoresize_conversion_fn(|(width, height)| (width * 4, height * 3)),
29 ))
30 .insert_resource(ClearColor(Color::BLACK))
31 .add_systems(Startup, setup_scene_system)
32 .add_systems(Update, handle_input_system)
33 .add_systems(Update, rotate_cube_system.after(handle_input_system))
34 .run();
35}
36
37fn setup_scene_system(
38 mut commands: Commands,
39 mut meshes: ResMut<Assets<Mesh>>,
40 mut materials: ResMut<Assets<StandardMaterial>>,
41 ratatui_render: Res<RatatuiRenderContext>,
42) {
43 commands.spawn((
44 Cube,
45 Mesh3d(meshes.add(Cuboid::default())),
46 MeshMaterial3d(materials.add(StandardMaterial {
47 base_color: Color::srgb(0.4, 0.54, 0.7),
48 ..Default::default()
49 })),
50 ));
51 commands.spawn((
52 Mesh3d(meshes.add(Cuboid::new(15., 15., 1.))),
53 Transform::from_xyz(0., 0., -6.),
54 ));
55 commands.spawn((
56 PointLight {
57 shadows_enabled: true,
58 ..Default::default()
59 },
60 Transform::from_xyz(3., 4., 6.),
61 ));
62 commands.spawn((
63 Camera3d::default(),
64 Camera {
65 target: ratatui_render.target("main").unwrap(),
66 ..default()
67 },
68 Transform::from_xyz(3., 3., 3.).looking_at(Vec3::ZERO, Vec3::Z),
69 ));
70}
71
72pub fn handle_input_system(
73 mut ratatui_events: EventReader<KeyEvent>,
74 mut exit: EventWriter<AppExit>,
75) {
76 for key_event in ratatui_events.read() {
77 if let KeyEventKind::Press | KeyEventKind::Repeat = key_event.kind {
78 if let KeyCode::Char('q') = key_event.code {
79 exit.send_default();
80 }
81 }
82 }
83}
84
85fn rotate_cube_system(time: Res<Time>, mut cube: Query<&mut Transform, With<Cube>>) {
86 cube.single_mut().rotate_z(time.delta_secs());
87}