blit/
blit.rs

1use bevy_app::{App, Startup, Update};
2use bevy_doryen::doryen::{AppOptions, Color, Console as DoryenConsole, TextAlign};
3use bevy_doryen::prelude::*;
4use bevy_ecs::bundle::Bundle;
5use bevy_ecs::prelude::Component;
6use bevy_ecs::system::{Commands, Query, Res, ResMut, Resource};
7
8#[derive(Component)]
9struct Console(DoryenConsole);
10
11#[derive(Copy, Component, Clone, Default, PartialEq)]
12struct Position {
13    x: i32,
14    y: i32,
15}
16
17#[derive(Copy, Component, Clone, Default, PartialEq)]
18struct Speed {
19    x: i32,
20    y: i32,
21}
22
23#[derive(Copy, Component, Clone, Default, PartialEq)]
24struct Alpha {
25    value: f32,
26    step: f32,
27    inverted: bool,
28}
29
30#[derive(Copy, Component, Clone, Default, PartialEq)]
31struct KeyColor(Option<Color>);
32
33#[derive(Bundle)]
34struct ConsoleBundle {
35    console: Console,
36    position: Position,
37    speed: Speed,
38    alpha: Alpha,
39    key_color: KeyColor,
40}
41
42#[derive(Copy, Clone, Default, PartialEq, Resource)]
43struct Step(usize);
44
45pub fn main() {
46    App::new()
47        .insert_resource(DoryenPluginSettings {
48            app_options: AppOptions {
49                window_title: String::from("blitting demo"),
50                ..Default::default()
51            },
52            ..Default::default()
53        })
54        .add_plugins(DoryenPlugin)
55        .init_resource::<Step>()
56        .add_systems(Startup, init)
57        .add_systems(
58            Update,
59            (update_position_and_speed, update_alpha, update_step),
60        )
61        .add_systems(Render, render)
62        .run();
63}
64
65fn init(mut commands: Commands) {
66    let mut c1 = DoryenConsole::new(20, 20);
67    let mut c2 = DoryenConsole::new(20, 20);
68    for y in 0..20 {
69        for x in 0..20 {
70            c1.back(x, y, (((x + y * 10) % 255) as u8, 0, 0, 255));
71            c2.back(
72                x,
73                y,
74                if (x - 10) * (x - 10) + (y - 10) * (y - 10) < 100 {
75                    (255, 192, 32, 255 - x as u8 * 10)
76                } else {
77                    (0, 0, 0, 255)
78                },
79            );
80        }
81    }
82    c1.print(10, 10, "Hello", TextAlign::Center, None, None);
83    c2.print(10, 10, "Circle", TextAlign::Center, None, None);
84
85    commands.spawn(ConsoleBundle {
86        console: Console(c1),
87        position: Position { x: 5, y: 5 },
88        speed: Speed { x: 1, y: 1 },
89        alpha: Alpha {
90            value: 1.0,
91            step: 0.01,
92            inverted: false,
93        },
94        key_color: KeyColor(None),
95    });
96
97    commands.spawn(ConsoleBundle {
98        console: Console(c2),
99        position: Position { x: 15, y: 20 },
100        speed: Speed { x: -1, y: 1 },
101        alpha: Alpha {
102            value: 1.0,
103            step: 0.01,
104            inverted: true,
105        },
106        key_color: KeyColor(Some((0, 0, 0, 255))),
107    });
108}
109
110fn update_position_and_speed(
111    root_console: Res<RootConsole>,
112    step: Res<Step>,
113    mut position_speed_query: Query<(&mut Position, &mut Speed)>,
114) {
115    if step.0 == 0 {
116        for (mut position, mut speed) in position_speed_query.iter_mut() {
117            let size = (
118                root_console.get_width() as i32,
119                root_console.get_height() as i32,
120            );
121            position.x += speed.x;
122            if position.x == size.0 - 20 || position.x == 0 {
123                speed.x = -speed.x;
124            }
125            position.y += speed.y;
126            if position.y == size.1 - 20 || position.y == 0 {
127                speed.y = -speed.y;
128            }
129        }
130    }
131}
132
133fn update_alpha(mut console_query: Query<(&mut Alpha, &Console)>) {
134    for (mut alpha, _) in console_query.iter_mut() {
135        if alpha.value <= 0.0 || alpha.value >= 1.0 {
136            alpha.step = -alpha.step;
137        }
138        alpha.value += alpha.step;
139    }
140}
141
142fn update_step(mut step: ResMut<Step>) {
143    step.0 = (step.0 + 1) % 10;
144}
145
146fn render(
147    mut root_console: ResMut<RootConsole>,
148    console_query: Query<(&Position, &Alpha, &KeyColor, &Console)>,
149) {
150    let root_console = &mut **root_console;
151    root_console.clear(Some((0, 0, 0, 255)), None, Some(' ' as u16));
152    for x in 0..root_console.get_width() as i32 {
153        for y in 0..root_console.get_height() as i32 {
154            root_console.back(
155                x,
156                y,
157                if (x + y) & 1 == 1 {
158                    (96, 64, 32, 255)
159                } else {
160                    (32, 64, 96, 255)
161                },
162            );
163        }
164    }
165    root_console.print(
166        (root_console.get_width() / 2) as i32,
167        (root_console.get_height() / 2) as i32,
168        "You create offscreen consoles\nand blit them on other consoles",
169        TextAlign::Center,
170        Some((255, 255, 255, 255)),
171        None,
172    );
173
174    for (position, alpha, key_color, console) in console_query.iter() {
175        let alpha = if alpha.inverted {
176            1.0 - alpha.value
177        } else {
178            alpha.value
179        };
180        console.0.blit(
181            position.x,
182            position.y,
183            root_console,
184            alpha,
185            alpha,
186            key_color.0,
187        );
188    }
189}