Struct View

Source
pub struct View {
    pub width: usize,
    pub height: usize,
    pub background_char: ColChar,
    pub wrapping_mode: WrappingMode,
    pub block_until_resized: bool,
    /* private fields */
}
Expand description

The View struct implements Canvas, and draws to stdout upon calling display_render.

use gemini_engine::{view::{WrappingMode, View}, core::{ColChar, Vec2D}, primitives::Pixel};

let mut view = View::new(9, 3, ColChar::BACKGROUND)
    .with_wrapping_mode(WrappingMode::Panic);
let pixel = Pixel::new(view.center(), ColChar::SOLID);

view.draw(&pixel);

view.display_render().unwrap();

Fields§

§width: usize

The width of the View. If modified, the View should be cleared to account for the new size

§height: usize

The height of the View. If modified, the View should be cleared to account for the new size

§background_char: ColChar

The character that the View will be filled with by default when View::clear is called

§wrapping_mode: WrappingMode

Determine how to handle pixels that are plotted outside the View

§block_until_resized: bool

If true, View::display_render will block until the console window is resized to fit the View

Implementations§

Source§

impl View

Source

pub fn new(width: usize, height: usize, background_char: ColChar) -> Self

Create a new View

Examples found in repository?
examples/game-loop-root.rs (line 18)
16    fn new() -> Self {
17        Self {
18            view: View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap),
19            pixel: Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID),
20        }
21    }
More examples
Hide additional examples
examples/quick-start.rs (line 12)
11fn main() {
12    let mut view = View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
13    let mut pixel = Pixel::new(Vec2D::new(10, 5), ColChar::SOLID);
14
15    loop {
16        view.clear();
17
18        pixel.pos.x += 1;
19
20        view.draw(&pixel);
21        let _ = view.display_render();
22
23        let _ = gameloop::sleep_fps(FPS, None);
24    }
25}
examples/multi-movement.rs (line 15)
14fn main() {
15    let mut view = View::new(50, 12, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
16
17    let mut blocks: Vec<Rect> = (0..=5)
18        .map(|offset| Rect::new(Vec2D::new(0, offset * 2), BLOCK_SIZE, FILL_CHAR))
19        .collect();
20
21    let mut i = 0;
22    loop {
23        if blocks.iter().all(|b| b.pos.x % view.width as i64 == 0) {
24            thread::sleep(Duration::from_secs(2));
25        };
26
27        i += 1;
28        for (j, block) in (0u32..).zip(blocks.iter_mut()) {
29            if i % 2_u32.pow(j) == 0 {
30                block.pos.x += 1;
31            }
32        }
33
34        view.clear();
35        for block in &blocks {
36            view.draw(block);
37        }
38        let _ = view.display_render();
39
40        thread::sleep(Duration::from_secs_f32(1.0 / 60.0));
41    }
42}
examples/donut.rs (line 14)
13fn main() {
14    let mut view = View::new(100, 45, ColChar::EMPTY);
15    let mut viewport = Viewport::new(
16        Transform3D::look_at_lh(Vec3D::new(0.0, -3.0, 6.0), Vec3D::ZERO, Vec3D::Y),
17        FOV,
18        view.center(),
19    );
20
21    viewport.display_mode = DisplayMode::Illuminated {
22        lights: vec![
23            Light::new_ambient(0.3),
24            Light::new_directional(0.7, Vec3D::new(1.0, 1.0, 1.0)),
25        ],
26    };
27
28    viewport.objects.push(Mesh3D::torus(1.8, 1.0, 32, 16));
29
30    loop {
31        let donut_tr = &mut viewport.objects[0].transform;
32        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_y(-0.03));
33        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_x(0.03));
34
35        view.clear();
36        view.draw(&viewport);
37        let _ = view.display_render();
38
39        thread::sleep(Duration::from_secs_f32(1.0 / FPS));
40    }
41}
examples/spinning-cube.rs (line 15)
14fn main() {
15    let mut view = View::new(100, 50, ColChar::EMPTY);
16
17    let mut viewport = Viewport::new(
18        Transform3D::look_at_lh(Vec3D::new(0.0, -1.5, 4.3), Vec3D::ZERO, Vec3D::Y),
19        FOV,
20        view.center(),
21    );
22    viewport.objects.push(Mesh3D::default_cube());
23
24    viewport.display_mode = DisplayMode::Illuminated {
25        lights: vec![
26            Light::new_ambient(0.3),
27            Light::new_directional(0.6, Vec3D::new(0.5, 1.0, 1.0)),
28        ],
29    };
30
31    fps_gameloop!(
32        {
33            viewport.objects[0].transform = viewport.objects[0]
34                .transform
35                .mul_mat4(&Transform3D::from_rotation_y(-0.05));
36        },
37        {
38            view.clear();
39            view.draw(&viewport);
40            let _ = view.display_render();
41        },
42        FPS,
43        |elapsed: Duration, frame_skip| {
44            println!(
45                "Elapsed: {:.2?}µs | Frame skip: {}",
46                elapsed.as_micros(),
47                frame_skip
48            );
49        }
50    );
51}
examples/complex-scene.rs (line 16)
15fn main() {
16    let mut view = View::new(60, 10, BACKGROUND_CHAR);
17
18    let mut pixel = Pixel::new(Vec2D::new(5, 9), FILL_CHAR);
19
20    let mut line = Line::new(Vec2D::new(2, 8), Vec2D::new(28, 7), FILL_CHAR);
21    let mut line1_direction = -1;
22
23    let rect = Rect::new(
24        Vec2D { x: 11, y: 1 },
25        Vec2D { x: 9, y: 3 },
26        ColChar::SOLID.with_rgb(200, 30, 0),
27    );
28
29    let test_image = r"
30  ______
31 /|_||_\`.__
32(   _    _ _\
33=`-(_)--(_)-'   ";
34    let mut sprite = Sprite::new(
35        Vec2D::new(30, 1),
36        test_image,
37        Modifier::from_rgb(20, 200, 0),
38    );
39
40    let mut draw_elapsed = Duration::default();
41    let mut render_elapsed = Duration::default();
42    fps_gameloop!(
43        {
44            pixel.pos.x += 2;
45            // loop the position back to the other side. This can be done with `WrappingMode::Wrap` but it won't change the element's actual position, so the pixel position being printed would continue to increase without looping
46            pixel.pos %= view.size();
47
48            line.pos1.y += line1_direction;
49            line.pos0.y = 10 - line.pos1.y;
50            if line.pos1.y > 7 {
51                line1_direction = -1;
52            } else if line.pos1.y < 3 {
53                line1_direction = 1;
54            }
55
56            sprite.pos.x += 1;
57        },
58        {
59            view.clear();
60
61            let now = Instant::now();
62            view.wrapping_mode = WrappingMode::Panic;
63            view.draw(&pixel);
64            view.draw(&line);
65            view.draw(&rect);
66            view.wrapping_mode = WrappingMode::Wrap;
67            view.draw(&sprite);
68            draw_elapsed = now.elapsed();
69
70            let now = Instant::now();
71            let _ = view.display_render();
72            render_elapsed = now.elapsed();
73        },
74        FPS,
75        |total_elapsed: Duration, _frame_skip| {
76            println!(
77                "Drawing: {:.2?} microseconds | Rendering: {:.2?} microseconds| Total: {:.2?}",
78                draw_elapsed.as_micros(),
79                render_elapsed.as_micros(),
80                total_elapsed.as_micros()
81            );
82            println!("Pixel position: {}", pixel.pos);
83        }
84    );
85}
Source

pub const fn with_wrapping_mode(self, wrapping_mode: WrappingMode) -> Self

Return the View with an updated wrapping_mode property. Consumes the original View

§Example
let mut view = View::new(20, 7, ColChar::BACKGROUND)
    .with_wrapping_mode(WrappingMode::Wrap);
// The pixel will be wrapped and drawn at `(0, 4)`
view.plot(Vec2D::new(20,4), ColChar::SOLID);
Examples found in repository?
examples/game-loop-root.rs (line 18)
16    fn new() -> Self {
17        Self {
18            view: View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap),
19            pixel: Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID),
20        }
21    }
More examples
Hide additional examples
examples/quick-start.rs (line 12)
11fn main() {
12    let mut view = View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
13    let mut pixel = Pixel::new(Vec2D::new(10, 5), ColChar::SOLID);
14
15    loop {
16        view.clear();
17
18        pixel.pos.x += 1;
19
20        view.draw(&pixel);
21        let _ = view.display_render();
22
23        let _ = gameloop::sleep_fps(FPS, None);
24    }
25}
examples/multi-movement.rs (line 15)
14fn main() {
15    let mut view = View::new(50, 12, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
16
17    let mut blocks: Vec<Rect> = (0..=5)
18        .map(|offset| Rect::new(Vec2D::new(0, offset * 2), BLOCK_SIZE, FILL_CHAR))
19        .collect();
20
21    let mut i = 0;
22    loop {
23        if blocks.iter().all(|b| b.pos.x % view.width as i64 == 0) {
24            thread::sleep(Duration::from_secs(2));
25        };
26
27        i += 1;
28        for (j, block) in (0u32..).zip(blocks.iter_mut()) {
29            if i % 2_u32.pow(j) == 0 {
30                block.pos.x += 1;
31            }
32        }
33
34        view.clear();
35        for block in &blocks {
36            view.draw(block);
37        }
38        let _ = view.display_render();
39
40        thread::sleep(Duration::from_secs_f32(1.0 / 60.0));
41    }
42}
Source

pub const fn with_block_until_resized(self) -> Self

Return the View with an updated block_until_resized property. Consumes the original View

§Example
let mut view = View::new(20, 7, ColChar::BACKGROUND)
    .with_block_until_resized();
// If the terminal size is smaller than (20, 7), this will wait until the terminal has been resized
view.display_render().unwrap();
Source

pub const fn size(&self) -> Vec2D

Return the width and height of the View as a Vec2D

Examples found in repository?
examples/complex-scene.rs (line 46)
15fn main() {
16    let mut view = View::new(60, 10, BACKGROUND_CHAR);
17
18    let mut pixel = Pixel::new(Vec2D::new(5, 9), FILL_CHAR);
19
20    let mut line = Line::new(Vec2D::new(2, 8), Vec2D::new(28, 7), FILL_CHAR);
21    let mut line1_direction = -1;
22
23    let rect = Rect::new(
24        Vec2D { x: 11, y: 1 },
25        Vec2D { x: 9, y: 3 },
26        ColChar::SOLID.with_rgb(200, 30, 0),
27    );
28
29    let test_image = r"
30  ______
31 /|_||_\`.__
32(   _    _ _\
33=`-(_)--(_)-'   ";
34    let mut sprite = Sprite::new(
35        Vec2D::new(30, 1),
36        test_image,
37        Modifier::from_rgb(20, 200, 0),
38    );
39
40    let mut draw_elapsed = Duration::default();
41    let mut render_elapsed = Duration::default();
42    fps_gameloop!(
43        {
44            pixel.pos.x += 2;
45            // loop the position back to the other side. This can be done with `WrappingMode::Wrap` but it won't change the element's actual position, so the pixel position being printed would continue to increase without looping
46            pixel.pos %= view.size();
47
48            line.pos1.y += line1_direction;
49            line.pos0.y = 10 - line.pos1.y;
50            if line.pos1.y > 7 {
51                line1_direction = -1;
52            } else if line.pos1.y < 3 {
53                line1_direction = 1;
54            }
55
56            sprite.pos.x += 1;
57        },
58        {
59            view.clear();
60
61            let now = Instant::now();
62            view.wrapping_mode = WrappingMode::Panic;
63            view.draw(&pixel);
64            view.draw(&line);
65            view.draw(&rect);
66            view.wrapping_mode = WrappingMode::Wrap;
67            view.draw(&sprite);
68            draw_elapsed = now.elapsed();
69
70            let now = Instant::now();
71            let _ = view.display_render();
72            render_elapsed = now.elapsed();
73        },
74        FPS,
75        |total_elapsed: Duration, _frame_skip| {
76            println!(
77                "Drawing: {:.2?} microseconds | Rendering: {:.2?} microseconds| Total: {:.2?}",
78                draw_elapsed.as_micros(),
79                render_elapsed.as_micros(),
80                total_elapsed.as_micros()
81            );
82            println!("Pixel position: {}", pixel.pos);
83        }
84    );
85}
Source

pub fn center(&self) -> Vec2D

Return Vec2D coordinates of the centre of the View

Examples found in repository?
examples/donut.rs (line 18)
13fn main() {
14    let mut view = View::new(100, 45, ColChar::EMPTY);
15    let mut viewport = Viewport::new(
16        Transform3D::look_at_lh(Vec3D::new(0.0, -3.0, 6.0), Vec3D::ZERO, Vec3D::Y),
17        FOV,
18        view.center(),
19    );
20
21    viewport.display_mode = DisplayMode::Illuminated {
22        lights: vec![
23            Light::new_ambient(0.3),
24            Light::new_directional(0.7, Vec3D::new(1.0, 1.0, 1.0)),
25        ],
26    };
27
28    viewport.objects.push(Mesh3D::torus(1.8, 1.0, 32, 16));
29
30    loop {
31        let donut_tr = &mut viewport.objects[0].transform;
32        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_y(-0.03));
33        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_x(0.03));
34
35        view.clear();
36        view.draw(&viewport);
37        let _ = view.display_render();
38
39        thread::sleep(Duration::from_secs_f32(1.0 / FPS));
40    }
41}
More examples
Hide additional examples
examples/spinning-cube.rs (line 20)
14fn main() {
15    let mut view = View::new(100, 50, ColChar::EMPTY);
16
17    let mut viewport = Viewport::new(
18        Transform3D::look_at_lh(Vec3D::new(0.0, -1.5, 4.3), Vec3D::ZERO, Vec3D::Y),
19        FOV,
20        view.center(),
21    );
22    viewport.objects.push(Mesh3D::default_cube());
23
24    viewport.display_mode = DisplayMode::Illuminated {
25        lights: vec![
26            Light::new_ambient(0.3),
27            Light::new_directional(0.6, Vec3D::new(0.5, 1.0, 1.0)),
28        ],
29    };
30
31    fps_gameloop!(
32        {
33            viewport.objects[0].transform = viewport.objects[0]
34                .transform
35                .mul_mat4(&Transform3D::from_rotation_y(-0.05));
36        },
37        {
38            view.clear();
39            view.draw(&viewport);
40            let _ = view.display_render();
41        },
42        FPS,
43        |elapsed: Duration, frame_skip| {
44            println!(
45                "Elapsed: {:.2?}µs | Frame skip: {}",
46                elapsed.as_micros(),
47                frame_skip
48            );
49        }
50    );
51}
Source

pub fn clear(&mut self)

Clear the View of all pixels, overwriting them all with the set background_char

Examples found in repository?
examples/game-loop-root.rs (line 34)
33    fn render_frame(&mut self) {
34        self.view.clear();
35        self.view.draw(&self.pixel);
36        let _ = self.view.display_render();
37    }
More examples
Hide additional examples
examples/quick-start.rs (line 16)
11fn main() {
12    let mut view = View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
13    let mut pixel = Pixel::new(Vec2D::new(10, 5), ColChar::SOLID);
14
15    loop {
16        view.clear();
17
18        pixel.pos.x += 1;
19
20        view.draw(&pixel);
21        let _ = view.display_render();
22
23        let _ = gameloop::sleep_fps(FPS, None);
24    }
25}
examples/multi-movement.rs (line 34)
14fn main() {
15    let mut view = View::new(50, 12, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
16
17    let mut blocks: Vec<Rect> = (0..=5)
18        .map(|offset| Rect::new(Vec2D::new(0, offset * 2), BLOCK_SIZE, FILL_CHAR))
19        .collect();
20
21    let mut i = 0;
22    loop {
23        if blocks.iter().all(|b| b.pos.x % view.width as i64 == 0) {
24            thread::sleep(Duration::from_secs(2));
25        };
26
27        i += 1;
28        for (j, block) in (0u32..).zip(blocks.iter_mut()) {
29            if i % 2_u32.pow(j) == 0 {
30                block.pos.x += 1;
31            }
32        }
33
34        view.clear();
35        for block in &blocks {
36            view.draw(block);
37        }
38        let _ = view.display_render();
39
40        thread::sleep(Duration::from_secs_f32(1.0 / 60.0));
41    }
42}
examples/donut.rs (line 35)
13fn main() {
14    let mut view = View::new(100, 45, ColChar::EMPTY);
15    let mut viewport = Viewport::new(
16        Transform3D::look_at_lh(Vec3D::new(0.0, -3.0, 6.0), Vec3D::ZERO, Vec3D::Y),
17        FOV,
18        view.center(),
19    );
20
21    viewport.display_mode = DisplayMode::Illuminated {
22        lights: vec![
23            Light::new_ambient(0.3),
24            Light::new_directional(0.7, Vec3D::new(1.0, 1.0, 1.0)),
25        ],
26    };
27
28    viewport.objects.push(Mesh3D::torus(1.8, 1.0, 32, 16));
29
30    loop {
31        let donut_tr = &mut viewport.objects[0].transform;
32        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_y(-0.03));
33        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_x(0.03));
34
35        view.clear();
36        view.draw(&viewport);
37        let _ = view.display_render();
38
39        thread::sleep(Duration::from_secs_f32(1.0 / FPS));
40    }
41}
examples/spinning-cube.rs (line 38)
14fn main() {
15    let mut view = View::new(100, 50, ColChar::EMPTY);
16
17    let mut viewport = Viewport::new(
18        Transform3D::look_at_lh(Vec3D::new(0.0, -1.5, 4.3), Vec3D::ZERO, Vec3D::Y),
19        FOV,
20        view.center(),
21    );
22    viewport.objects.push(Mesh3D::default_cube());
23
24    viewport.display_mode = DisplayMode::Illuminated {
25        lights: vec![
26            Light::new_ambient(0.3),
27            Light::new_directional(0.6, Vec3D::new(0.5, 1.0, 1.0)),
28        ],
29    };
30
31    fps_gameloop!(
32        {
33            viewport.objects[0].transform = viewport.objects[0]
34                .transform
35                .mul_mat4(&Transform3D::from_rotation_y(-0.05));
36        },
37        {
38            view.clear();
39            view.draw(&viewport);
40            let _ = view.display_render();
41        },
42        FPS,
43        |elapsed: Duration, frame_skip| {
44            println!(
45                "Elapsed: {:.2?}µs | Frame skip: {}",
46                elapsed.as_micros(),
47                frame_skip
48            );
49        }
50    );
51}
examples/complex-scene.rs (line 59)
15fn main() {
16    let mut view = View::new(60, 10, BACKGROUND_CHAR);
17
18    let mut pixel = Pixel::new(Vec2D::new(5, 9), FILL_CHAR);
19
20    let mut line = Line::new(Vec2D::new(2, 8), Vec2D::new(28, 7), FILL_CHAR);
21    let mut line1_direction = -1;
22
23    let rect = Rect::new(
24        Vec2D { x: 11, y: 1 },
25        Vec2D { x: 9, y: 3 },
26        ColChar::SOLID.with_rgb(200, 30, 0),
27    );
28
29    let test_image = r"
30  ______
31 /|_||_\`.__
32(   _    _ _\
33=`-(_)--(_)-'   ";
34    let mut sprite = Sprite::new(
35        Vec2D::new(30, 1),
36        test_image,
37        Modifier::from_rgb(20, 200, 0),
38    );
39
40    let mut draw_elapsed = Duration::default();
41    let mut render_elapsed = Duration::default();
42    fps_gameloop!(
43        {
44            pixel.pos.x += 2;
45            // loop the position back to the other side. This can be done with `WrappingMode::Wrap` but it won't change the element's actual position, so the pixel position being printed would continue to increase without looping
46            pixel.pos %= view.size();
47
48            line.pos1.y += line1_direction;
49            line.pos0.y = 10 - line.pos1.y;
50            if line.pos1.y > 7 {
51                line1_direction = -1;
52            } else if line.pos1.y < 3 {
53                line1_direction = 1;
54            }
55
56            sprite.pos.x += 1;
57        },
58        {
59            view.clear();
60
61            let now = Instant::now();
62            view.wrapping_mode = WrappingMode::Panic;
63            view.draw(&pixel);
64            view.draw(&line);
65            view.draw(&rect);
66            view.wrapping_mode = WrappingMode::Wrap;
67            view.draw(&sprite);
68            draw_elapsed = now.elapsed();
69
70            let now = Instant::now();
71            let _ = view.display_render();
72            render_elapsed = now.elapsed();
73        },
74        FPS,
75        |total_elapsed: Duration, _frame_skip| {
76            println!(
77                "Drawing: {:.2?} microseconds | Rendering: {:.2?} microseconds| Total: {:.2?}",
78                draw_elapsed.as_micros(),
79                render_elapsed.as_micros(),
80                total_elapsed.as_micros()
81            );
82            println!("Pixel position: {}", pixel.pos);
83        }
84    );
85}
Source

pub fn draw(&mut self, element: &impl CanDraw)

Draw a struct implementing CanDraw to the View

Examples found in repository?
examples/game-loop-root.rs (line 35)
33    fn render_frame(&mut self) {
34        self.view.clear();
35        self.view.draw(&self.pixel);
36        let _ = self.view.display_render();
37    }
More examples
Hide additional examples
examples/quick-start.rs (line 20)
11fn main() {
12    let mut view = View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
13    let mut pixel = Pixel::new(Vec2D::new(10, 5), ColChar::SOLID);
14
15    loop {
16        view.clear();
17
18        pixel.pos.x += 1;
19
20        view.draw(&pixel);
21        let _ = view.display_render();
22
23        let _ = gameloop::sleep_fps(FPS, None);
24    }
25}
examples/self-resizing.rs (line 31)
16fn main() {
17    let mut scale_view = ScaleFitView::new(ColChar::BACKGROUND);
18
19    let mut text = Text::new(Vec2D::ZERO, "This is some centered text!", Modifier::None)
20        .with_align(TextAlign::Centered);
21
22    let mut sprite =
23        Sprite::new(Vec2D::ZERO, TEXTURE, Modifier::None).with_align(TextAlign2D::CENTERED);
24
25    loop {
26        text.pos = scale_view.intended_size() / 2;
27        sprite.pos = scale_view.intended_size() / 2;
28        sprite.pos.y -= 5;
29
30        scale_view.update();
31        scale_view.view.draw(&text);
32        scale_view.view.draw(&sprite);
33        let _ = scale_view.view.display_render();
34
35        thread::sleep(Duration::from_millis(10));
36    }
37}
examples/multi-movement.rs (line 36)
14fn main() {
15    let mut view = View::new(50, 12, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
16
17    let mut blocks: Vec<Rect> = (0..=5)
18        .map(|offset| Rect::new(Vec2D::new(0, offset * 2), BLOCK_SIZE, FILL_CHAR))
19        .collect();
20
21    let mut i = 0;
22    loop {
23        if blocks.iter().all(|b| b.pos.x % view.width as i64 == 0) {
24            thread::sleep(Duration::from_secs(2));
25        };
26
27        i += 1;
28        for (j, block) in (0u32..).zip(blocks.iter_mut()) {
29            if i % 2_u32.pow(j) == 0 {
30                block.pos.x += 1;
31            }
32        }
33
34        view.clear();
35        for block in &blocks {
36            view.draw(block);
37        }
38        let _ = view.display_render();
39
40        thread::sleep(Duration::from_secs_f32(1.0 / 60.0));
41    }
42}
examples/donut.rs (line 36)
13fn main() {
14    let mut view = View::new(100, 45, ColChar::EMPTY);
15    let mut viewport = Viewport::new(
16        Transform3D::look_at_lh(Vec3D::new(0.0, -3.0, 6.0), Vec3D::ZERO, Vec3D::Y),
17        FOV,
18        view.center(),
19    );
20
21    viewport.display_mode = DisplayMode::Illuminated {
22        lights: vec![
23            Light::new_ambient(0.3),
24            Light::new_directional(0.7, Vec3D::new(1.0, 1.0, 1.0)),
25        ],
26    };
27
28    viewport.objects.push(Mesh3D::torus(1.8, 1.0, 32, 16));
29
30    loop {
31        let donut_tr = &mut viewport.objects[0].transform;
32        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_y(-0.03));
33        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_x(0.03));
34
35        view.clear();
36        view.draw(&viewport);
37        let _ = view.display_render();
38
39        thread::sleep(Duration::from_secs_f32(1.0 / FPS));
40    }
41}
examples/spinning-cube.rs (line 39)
14fn main() {
15    let mut view = View::new(100, 50, ColChar::EMPTY);
16
17    let mut viewport = Viewport::new(
18        Transform3D::look_at_lh(Vec3D::new(0.0, -1.5, 4.3), Vec3D::ZERO, Vec3D::Y),
19        FOV,
20        view.center(),
21    );
22    viewport.objects.push(Mesh3D::default_cube());
23
24    viewport.display_mode = DisplayMode::Illuminated {
25        lights: vec![
26            Light::new_ambient(0.3),
27            Light::new_directional(0.6, Vec3D::new(0.5, 1.0, 1.0)),
28        ],
29    };
30
31    fps_gameloop!(
32        {
33            viewport.objects[0].transform = viewport.objects[0]
34                .transform
35                .mul_mat4(&Transform3D::from_rotation_y(-0.05));
36        },
37        {
38            view.clear();
39            view.draw(&viewport);
40            let _ = view.display_render();
41        },
42        FPS,
43        |elapsed: Duration, frame_skip| {
44            println!(
45                "Elapsed: {:.2?}µs | Frame skip: {}",
46                elapsed.as_micros(),
47                frame_skip
48            );
49        }
50    );
51}
Source

pub fn draw_double_width(&mut self, element: &impl CanDraw)

Draw a struct implementing CanDraw to the View with a doubled width. Drawing a Pixel at Vec2D(5,3), for example, will result in pixels at at Vec2D(10,3) and Vec2D(11,3) being plotted to. Useful when you want to work with more square pixels, as single text characters are much taller than they are wide

Source

pub fn display_render(&self) -> Result<()>

Display the View. View implements the Display trait and so can be rendered in many ways (such as println!("{view}");), but this is intended to be the fastest way possible.

§Errors

Returns the Result from writing to io::stdout().lock(). You can simply ignore it with let _ = or .unwrap() most of the time

Examples found in repository?
examples/game-loop-root.rs (line 36)
33    fn render_frame(&mut self) {
34        self.view.clear();
35        self.view.draw(&self.pixel);
36        let _ = self.view.display_render();
37    }
More examples
Hide additional examples
examples/quick-start.rs (line 21)
11fn main() {
12    let mut view = View::new(40, 8, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
13    let mut pixel = Pixel::new(Vec2D::new(10, 5), ColChar::SOLID);
14
15    loop {
16        view.clear();
17
18        pixel.pos.x += 1;
19
20        view.draw(&pixel);
21        let _ = view.display_render();
22
23        let _ = gameloop::sleep_fps(FPS, None);
24    }
25}
examples/self-resizing.rs (line 33)
16fn main() {
17    let mut scale_view = ScaleFitView::new(ColChar::BACKGROUND);
18
19    let mut text = Text::new(Vec2D::ZERO, "This is some centered text!", Modifier::None)
20        .with_align(TextAlign::Centered);
21
22    let mut sprite =
23        Sprite::new(Vec2D::ZERO, TEXTURE, Modifier::None).with_align(TextAlign2D::CENTERED);
24
25    loop {
26        text.pos = scale_view.intended_size() / 2;
27        sprite.pos = scale_view.intended_size() / 2;
28        sprite.pos.y -= 5;
29
30        scale_view.update();
31        scale_view.view.draw(&text);
32        scale_view.view.draw(&sprite);
33        let _ = scale_view.view.display_render();
34
35        thread::sleep(Duration::from_millis(10));
36    }
37}
examples/multi-movement.rs (line 38)
14fn main() {
15    let mut view = View::new(50, 12, ColChar::BACKGROUND).with_wrapping_mode(WrappingMode::Wrap);
16
17    let mut blocks: Vec<Rect> = (0..=5)
18        .map(|offset| Rect::new(Vec2D::new(0, offset * 2), BLOCK_SIZE, FILL_CHAR))
19        .collect();
20
21    let mut i = 0;
22    loop {
23        if blocks.iter().all(|b| b.pos.x % view.width as i64 == 0) {
24            thread::sleep(Duration::from_secs(2));
25        };
26
27        i += 1;
28        for (j, block) in (0u32..).zip(blocks.iter_mut()) {
29            if i % 2_u32.pow(j) == 0 {
30                block.pos.x += 1;
31            }
32        }
33
34        view.clear();
35        for block in &blocks {
36            view.draw(block);
37        }
38        let _ = view.display_render();
39
40        thread::sleep(Duration::from_secs_f32(1.0 / 60.0));
41    }
42}
examples/donut.rs (line 37)
13fn main() {
14    let mut view = View::new(100, 45, ColChar::EMPTY);
15    let mut viewport = Viewport::new(
16        Transform3D::look_at_lh(Vec3D::new(0.0, -3.0, 6.0), Vec3D::ZERO, Vec3D::Y),
17        FOV,
18        view.center(),
19    );
20
21    viewport.display_mode = DisplayMode::Illuminated {
22        lights: vec![
23            Light::new_ambient(0.3),
24            Light::new_directional(0.7, Vec3D::new(1.0, 1.0, 1.0)),
25        ],
26    };
27
28    viewport.objects.push(Mesh3D::torus(1.8, 1.0, 32, 16));
29
30    loop {
31        let donut_tr = &mut viewport.objects[0].transform;
32        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_y(-0.03));
33        *donut_tr = donut_tr.mul_mat4(&Transform3D::from_rotation_x(0.03));
34
35        view.clear();
36        view.draw(&viewport);
37        let _ = view.display_render();
38
39        thread::sleep(Duration::from_secs_f32(1.0 / FPS));
40    }
41}
examples/spinning-cube.rs (line 40)
14fn main() {
15    let mut view = View::new(100, 50, ColChar::EMPTY);
16
17    let mut viewport = Viewport::new(
18        Transform3D::look_at_lh(Vec3D::new(0.0, -1.5, 4.3), Vec3D::ZERO, Vec3D::Y),
19        FOV,
20        view.center(),
21    );
22    viewport.objects.push(Mesh3D::default_cube());
23
24    viewport.display_mode = DisplayMode::Illuminated {
25        lights: vec![
26            Light::new_ambient(0.3),
27            Light::new_directional(0.6, Vec3D::new(0.5, 1.0, 1.0)),
28        ],
29    };
30
31    fps_gameloop!(
32        {
33            viewport.objects[0].transform = viewport.objects[0]
34                .transform
35                .mul_mat4(&Transform3D::from_rotation_y(-0.05));
36        },
37        {
38            view.clear();
39            view.draw(&viewport);
40            let _ = view.display_render();
41        },
42        FPS,
43        |elapsed: Duration, frame_skip| {
44            println!(
45                "Elapsed: {:.2?}µs | Frame skip: {}",
46                elapsed.as_micros(),
47                frame_skip
48            );
49        }
50    );
51}

Trait Implementations§

Source§

impl Canvas for View

Source§

fn plot(&mut self, pos: Vec2D, c: ColChar)

Plot a pixel to the View. Accepts a Vec2D (the position of the pixel) and a ColChar (what the pixel should look like/what colour it should be)

§Panics

Will panic if the position is out of bounds of the View and wrapping_mode is WrappingMode::Panic

Source§

impl Clone for View

Source§

fn clone(&self) -> View

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for View

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for View

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for View

§

impl RefUnwindSafe for View

§

impl Send for View

§

impl Sync for View

§

impl Unpin for View

§

impl UnwindSafe for View

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.