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