homotopy_word_debug/
homotopy_word_debug.rs

1use bevy::prelude::*;
2use bevy::sprite::MaterialMesh2dBundle;
3use charred_path::{piecewise_linear::PathPlugin, prelude::*};
4
5const PLAYER_COLOR: Color = Color::rgb(0.15, 0.6, 0.5);
6const PLAYER_START: Vec3 = Vec3::new(0.0, 0.0, 0.0);
7
8fn main() {
9    let mut app = App::new();
10    app.add_plugins((DefaultPlugins, PathPlugin, PathDebugPlugin));
11    app.add_systems(Startup, init);
12    app.add_systems(FixedUpdate, player_movement);
13    app.add_systems(Update, homotopy_text_update);
14    app.run();
15}
16
17#[derive(Component)]
18pub struct Player;
19
20#[derive(Component)]
21struct HomotopyWordText;
22
23fn init(
24    mut commands: Commands,
25    mut meshes: ResMut<Assets<Mesh>>,
26    mut materials: ResMut<Assets<ColorMaterial>>,
27) {
28    // spawn the camera
29    commands.spawn(Camera2dBundle::default());
30
31    // Define some puncture points
32    let puncture_points = vec![
33        PuncturePoint::new(Vec2::new(-225.0, 100.0), 'A'),
34        PuncturePoint::new(Vec2::new(-75.0, 150.0), 'B'),
35        PuncturePoint::new(Vec2::new(75.0, 150.0), 'C'),
36        PuncturePoint::new(Vec2::new(225.0, 100.0), 'D'),
37    ];
38
39    // Render puncture points as red circles
40    let radius = 5.0;
41    let material = materials.add(ColorMaterial::from(Color::RED));
42    for point in puncture_points.iter() {
43        commands.spawn(MaterialMesh2dBundle {
44            mesh: meshes.add(Circle::new(radius)).into(),
45            material: material.clone(),
46            transform: Transform::from_translation(point.position().extend(0.0)),
47            ..Default::default()
48        });
49    }
50
51    // spawn the player
52    commands.spawn((
53        Player,
54        MaterialMesh2dBundle {
55            mesh: meshes.add(Circle::new(10.0)).into(),
56            material: materials.add(PLAYER_COLOR),
57            transform: Transform::from_translation(PLAYER_START),
58            ..Default::default()
59        },
60        PathType::new(PLAYER_START.truncate(), puncture_points),
61    ));
62
63    // spawn the text
64    commands.spawn((
65        TextBundle::from_section(
66            "default",
67            TextStyle {
68                font_size: 60.0,
69                ..Default::default()
70            },
71        )
72        .with_text_justify(JustifyText::Center)
73        .with_style(Style {
74            position_type: PositionType::Absolute,
75            bottom: Val::Px(5.0),
76            right: Val::Px(5.0),
77            ..Default::default()
78        }),
79        HomotopyWordText,
80    ));
81}
82
83fn player_movement(
84    mut player_query: Query<&mut Transform, With<Player>>,
85    keyboard_input: Res<ButtonInput<KeyCode>>,
86    time: Res<Time>,
87) {
88    if let Ok(mut transform) = player_query.get_single_mut() {
89        let mut dir = Vec3::ZERO;
90        if keyboard_input.pressed(KeyCode::ArrowUp) {
91            dir.y += 1.0;
92        }
93        if keyboard_input.pressed(KeyCode::ArrowDown) {
94            dir.y -= 1.0;
95        }
96        if keyboard_input.pressed(KeyCode::ArrowRight) {
97            dir.x += 1.0;
98        }
99        if keyboard_input.pressed(KeyCode::ArrowLeft) {
100            dir.x -= 1.0;
101        }
102        transform.translation += 200.0 * dir * time.delta_seconds();
103    }
104}
105
106fn homotopy_text_update(
107    mut text_query: Query<&mut Text, With<HomotopyWordText>>,
108    path_query: Query<&PathType>,
109) {
110    if let Ok(path_type) = path_query.get_single() {
111        if let Ok(mut text) = text_query.get_single_mut() {
112            text.sections[0].value = path_type.word();
113        }
114    }
115}