Struct gemini_engine::elements::view::View

source ·
pub struct View {
    pub width: usize,
    pub height: usize,
    pub background_char: ColChar,
    pub coord_numbers_in_render: bool,
    pub block_until_resized: bool,
    /* private fields */
}
Expand description

The View struct is the canvas on which you will print all of your ViewElements. In normal use, you would clear the View, blit all your ViewElements to it and then render. The following example demonstrates a piece of code that will render a View of width 9 and height 3, with a single Pixel in the middle

use gemini_engine::elements::{view::{Wrapping, ColChar}, View, Pixel, Vec2D};

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

view.blit(&pixel, Wrapping::Panic);

view.display_render().unwrap();

Fields§

§width: usize

The width of the View

§height: usize

The height of the View

§background_char: ColChar

The character that the View will be filled with by default on clear

§coord_numbers_in_render: bool

A boolean determining whether the render should contain numbers on the top and left signifying the corresponding pixels’ X/Y value values

§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 using width, height and background_char parameters

Examples found in repository?
examples/game-loop-root.rs (line 19)
17
18
19
20
21
22
    fn new() -> Self {
        Self {
            view: View::new(40, 8, ColChar::BACKGROUND),
            pixel: Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID),
        }
    }
More examples
Hide additional examples
examples/quick-start.rs (line 11)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fn main() {
    let mut view = View::new(40, 8, ColChar::BACKGROUND);
    let mut pixel = Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID);

    loop {
        view.clear();

        pixel.pos.x += 1;

        view.blit(&pixel, Wrapping::Wrap);
        let _ = view.display_render();

        let _ = gameloop::sleep_fps(FPS, None);
    }
}
examples/spinning-cube.rs (line 11)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
examples/donut.rs (line 15)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}
examples/multi-movement.rs (line 19)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
fn main() {
    let mut view = View::new(50, 12, ColChar::BACKGROUND);

    let mut blocks = vec![
        Rect::new(Vec2D::new(0, 0), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 2), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 4), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 6), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 8), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 10), BLOCK_SIZE, FILL_CHAR),
    ];

    let mut i = 0;
    fps_gameloop!(
        {
            i += 1;
            for (j, block) in (0u32..).zip(blocks.iter_mut()) {
                if i % 2_u32.pow(j) == 0 {
                    block.pos.x += 1;
                }
            }
        },
        {
            view.clear();
            for block in &blocks {
                view.blit(block, Wrapping::Wrap);
            }
            let _ = view.display_render();

            if blocks
                .iter()
                .all(|b| b.pos.x % isize::try_from(view.width).expect("Wrapped usize") == 0)
            {
                thread::sleep(Duration::from_secs(2));
            };
        },
        200.0
    );
}
examples/complex-scene.rs (line 14)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
fn main() {
    let mut view = View::new(60, 10, BACKGROUND_CHAR);
    view.coord_numbers_in_render = true;

    let mut pixel = Pixel::new(Vec2D::from((5u8, 9u8)), FILL_CHAR);

    let mut line = Line::new(Vec2D::new(2, 8), Vec2D::new(28, 7), FILL_CHAR);
    let mut line1_direction = -1;

    let rect = Rect::new(
        Vec2D { x: 11, y: 1 },
        Vec2D { x: 9, y: 3 },
        ColChar::SOLID.with_rgb(200, 30, 0),
    );

    let test_image = r"
  ______
 /|_||_\`.__
(   _    _ _\
=`-(_)--(_)-'   ";
    let mut sprite = Sprite::new(
        Vec2D::new(30, 1),
        test_image,
        Modifier::from_rgb(20, 200, 0),
    );

    let mut blit_elapsed = Duration::default();
    let mut render_elapsed = Duration::default();
    fps_gameloop!(
        {
            pixel.pos.x += 2;
            // loop the position back to the other side. This can be done with `Wrapping::Wrap` but it won't change the element's actual position, so the pixel position being printed would continue to increase without looping
            pixel.pos %= view.size();

            line.pos1.y += line1_direction;
            line.pos0.y = 10 - line.pos1.y;
            if line.pos1.y > 7 {
                line1_direction = -1;
            } else if line.pos1.y < 3 {
                line1_direction = 1;
            }

            sprite.pos.x += 1;
        },
        {
            view.clear();

            let now = Instant::now();
            view.blit(&pixel, Wrapping::Panic);
            view.blit(&line, Wrapping::Panic);
            view.blit(&rect, Wrapping::Panic);
            view.blit(&sprite, Wrapping::Wrap);
            blit_elapsed = now.elapsed();

            let now = Instant::now();
            let _ = view.display_render();
            render_elapsed = now.elapsed();
        },
        FPS,
        |total_elapsed: Duration, _frame_skip| {
            println!(
                "Blitting: {:.2?} microseconds | Rendering: {:.2?} microseconds| Total: {:.2?}",
                blit_elapsed.as_micros(),
                render_elapsed.as_micros(),
                total_elapsed.as_micros()
            );
            println!("Pixel position: {}", pixel.pos);
        }
    );
}
source

pub const fn with_coord_numbers(self, coord_numbers_in_render: bool) -> Self

Return the View with its coord_numbers_in_render field set to the chosen value. Consumes the original View

source

pub const fn with_block_until_resized(self, block_until_resized: bool) -> Self

Return the View with its block_until_resized field set to the chosen value. Consumes the original View

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 45)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
fn main() {
    let mut view = View::new(60, 10, BACKGROUND_CHAR);
    view.coord_numbers_in_render = true;

    let mut pixel = Pixel::new(Vec2D::from((5u8, 9u8)), FILL_CHAR);

    let mut line = Line::new(Vec2D::new(2, 8), Vec2D::new(28, 7), FILL_CHAR);
    let mut line1_direction = -1;

    let rect = Rect::new(
        Vec2D { x: 11, y: 1 },
        Vec2D { x: 9, y: 3 },
        ColChar::SOLID.with_rgb(200, 30, 0),
    );

    let test_image = r"
  ______
 /|_||_\`.__
(   _    _ _\
=`-(_)--(_)-'   ";
    let mut sprite = Sprite::new(
        Vec2D::new(30, 1),
        test_image,
        Modifier::from_rgb(20, 200, 0),
    );

    let mut blit_elapsed = Duration::default();
    let mut render_elapsed = Duration::default();
    fps_gameloop!(
        {
            pixel.pos.x += 2;
            // loop the position back to the other side. This can be done with `Wrapping::Wrap` but it won't change the element's actual position, so the pixel position being printed would continue to increase without looping
            pixel.pos %= view.size();

            line.pos1.y += line1_direction;
            line.pos0.y = 10 - line.pos1.y;
            if line.pos1.y > 7 {
                line1_direction = -1;
            } else if line.pos1.y < 3 {
                line1_direction = 1;
            }

            sprite.pos.x += 1;
        },
        {
            view.clear();

            let now = Instant::now();
            view.blit(&pixel, Wrapping::Panic);
            view.blit(&line, Wrapping::Panic);
            view.blit(&rect, Wrapping::Panic);
            view.blit(&sprite, Wrapping::Wrap);
            blit_elapsed = now.elapsed();

            let now = Instant::now();
            let _ = view.display_render();
            render_elapsed = now.elapsed();
        },
        FPS,
        |total_elapsed: Duration, _frame_skip| {
            println!(
                "Blitting: {:.2?} microseconds | Rendering: {:.2?} microseconds| Total: {:.2?}",
                blit_elapsed.as_micros(),
                render_elapsed.as_micros(),
                total_elapsed.as_micros()
            );
            println!("Pixel position: {}", pixel.pos);
        }
    );
}
source

pub fn center(&self) -> Vec2D

Return Vec2D coordinates of the centre of the View

Examples found in repository?
examples/spinning-cube.rs (line 16)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
More examples
Hide additional examples
examples/donut.rs (line 19)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}
source

pub fn clear(&mut self)

Clear the View of all pixels

Examples found in repository?
examples/game-loop-root.rs (line 31)
30
31
32
33
34
    fn render_frame(&mut self) {
        self.view.clear();
        self.view.blit(&self.pixel, Wrapping::Wrap);
        let _ = self.view.display_render();
    }
More examples
Hide additional examples
examples/quick-start.rs (line 15)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fn main() {
    let mut view = View::new(40, 8, ColChar::BACKGROUND);
    let mut pixel = Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID);

    loop {
        view.clear();

        pixel.pos.x += 1;

        view.blit(&pixel, Wrapping::Wrap);
        let _ = view.display_render();

        let _ = gameloop::sleep_fps(FPS, None);
    }
}
examples/spinning-cube.rs (line 23)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
examples/donut.rs (line 35)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}
examples/multi-movement.rs (line 41)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
fn main() {
    let mut view = View::new(50, 12, ColChar::BACKGROUND);

    let mut blocks = vec![
        Rect::new(Vec2D::new(0, 0), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 2), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 4), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 6), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 8), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 10), BLOCK_SIZE, FILL_CHAR),
    ];

    let mut i = 0;
    fps_gameloop!(
        {
            i += 1;
            for (j, block) in (0u32..).zip(blocks.iter_mut()) {
                if i % 2_u32.pow(j) == 0 {
                    block.pos.x += 1;
                }
            }
        },
        {
            view.clear();
            for block in &blocks {
                view.blit(block, Wrapping::Wrap);
            }
            let _ = view.display_render();

            if blocks
                .iter()
                .all(|b| b.pos.x % isize::try_from(view.width).expect("Wrapped usize") == 0)
            {
                thread::sleep(Duration::from_secs(2));
            };
        },
        200.0
    );
}
examples/complex-scene.rs (line 58)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
fn main() {
    let mut view = View::new(60, 10, BACKGROUND_CHAR);
    view.coord_numbers_in_render = true;

    let mut pixel = Pixel::new(Vec2D::from((5u8, 9u8)), FILL_CHAR);

    let mut line = Line::new(Vec2D::new(2, 8), Vec2D::new(28, 7), FILL_CHAR);
    let mut line1_direction = -1;

    let rect = Rect::new(
        Vec2D { x: 11, y: 1 },
        Vec2D { x: 9, y: 3 },
        ColChar::SOLID.with_rgb(200, 30, 0),
    );

    let test_image = r"
  ______
 /|_||_\`.__
(   _    _ _\
=`-(_)--(_)-'   ";
    let mut sprite = Sprite::new(
        Vec2D::new(30, 1),
        test_image,
        Modifier::from_rgb(20, 200, 0),
    );

    let mut blit_elapsed = Duration::default();
    let mut render_elapsed = Duration::default();
    fps_gameloop!(
        {
            pixel.pos.x += 2;
            // loop the position back to the other side. This can be done with `Wrapping::Wrap` but it won't change the element's actual position, so the pixel position being printed would continue to increase without looping
            pixel.pos %= view.size();

            line.pos1.y += line1_direction;
            line.pos0.y = 10 - line.pos1.y;
            if line.pos1.y > 7 {
                line1_direction = -1;
            } else if line.pos1.y < 3 {
                line1_direction = 1;
            }

            sprite.pos.x += 1;
        },
        {
            view.clear();

            let now = Instant::now();
            view.blit(&pixel, Wrapping::Panic);
            view.blit(&line, Wrapping::Panic);
            view.blit(&rect, Wrapping::Panic);
            view.blit(&sprite, Wrapping::Wrap);
            blit_elapsed = now.elapsed();

            let now = Instant::now();
            let _ = view.display_render();
            render_elapsed = now.elapsed();
        },
        FPS,
        |total_elapsed: Duration, _frame_skip| {
            println!(
                "Blitting: {:.2?} microseconds | Rendering: {:.2?} microseconds| Total: {:.2?}",
                blit_elapsed.as_micros(),
                render_elapsed.as_micros(),
                total_elapsed.as_micros()
            );
            println!("Pixel position: {}", pixel.pos);
        }
    );
}
source

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

Plot a pixel to the View. Accepts a Vec2D (the position of the pixel), ColChar (what the pixel should look like/what colour it should be), and a Wrapping enum variant (Please see the Wrapping documentation for more info)

source

pub fn blit(&mut self, element: &impl ViewElement, wrapping: Wrapping)

Blit a struct implementing ViewElement to the View

Examples found in repository?
examples/game-loop-root.rs (line 32)
30
31
32
33
34
    fn render_frame(&mut self) {
        self.view.clear();
        self.view.blit(&self.pixel, Wrapping::Wrap);
        let _ = self.view.display_render();
    }
More examples
Hide additional examples
examples/quick-start.rs (line 19)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fn main() {
    let mut view = View::new(40, 8, ColChar::BACKGROUND);
    let mut pixel = Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID);

    loop {
        view.clear();

        pixel.pos.x += 1;

        view.blit(&pixel, Wrapping::Wrap);
        let _ = view.display_render();

        let _ = gameloop::sleep_fps(FPS, None);
    }
}
examples/self-resizing.rs (line 32)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
fn main() {
    let mut scale_view = ScaleFitView::new(ColChar::BACKGROUND);

    let mut text = Text::new(Vec2D::ZERO, "This is some centered text!", Modifier::None)
        .with_align(TextAlign::Centered);

    let mut sprite =
        Sprite::new(Vec2D::ZERO, TEXTURE, Modifier::None).with_align(TextAlign2D::CENTERED);

    loop {
        text.pos = scale_view.intended_size() / 2;
        sprite.pos = scale_view.intended_size() / 2;
        sprite.pos.y -= 5;

        scale_view.update();
        scale_view.view.blit(&text, Wrapping::Wrap);
        scale_view.view.blit(&sprite, Wrapping::Wrap);
        let _ = scale_view.view.display_render();

        sleep(Duration::from_millis(10));
    }
}
examples/spinning-cube.rs (lines 27-30)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
examples/donut.rs (lines 36-44)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}
examples/multi-movement.rs (line 43)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
fn main() {
    let mut view = View::new(50, 12, ColChar::BACKGROUND);

    let mut blocks = vec![
        Rect::new(Vec2D::new(0, 0), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 2), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 4), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 6), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 8), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 10), BLOCK_SIZE, FILL_CHAR),
    ];

    let mut i = 0;
    fps_gameloop!(
        {
            i += 1;
            for (j, block) in (0u32..).zip(blocks.iter_mut()) {
                if i % 2_u32.pow(j) == 0 {
                    block.pos.x += 1;
                }
            }
        },
        {
            view.clear();
            for block in &blocks {
                view.blit(block, Wrapping::Wrap);
            }
            let _ = view.display_render();

            if blocks
                .iter()
                .all(|b| b.pos.x % isize::try_from(view.width).expect("Wrapped usize") == 0)
            {
                thread::sleep(Duration::from_secs(2));
            };
        },
        200.0
    );
}
source

pub fn blit_double_width( &mut self, element: &impl ViewElement, wrapping: Wrapping )

Blit a struct implementing ViewElement to the View with a doubled width. Blitting a Pixel at Vec2D(5,3), for example, will result in a blit 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 ignore it with let _ = ... most of the time

Examples found in repository?
examples/game-loop-root.rs (line 33)
30
31
32
33
34
    fn render_frame(&mut self) {
        self.view.clear();
        self.view.blit(&self.pixel, Wrapping::Wrap);
        let _ = self.view.display_render();
    }
More examples
Hide additional examples
examples/quick-start.rs (line 20)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fn main() {
    let mut view = View::new(40, 8, ColChar::BACKGROUND);
    let mut pixel = Pixel::new(Vec2D { x: 10, y: 5 }, ColChar::SOLID);

    loop {
        view.clear();

        pixel.pos.x += 1;

        view.blit(&pixel, Wrapping::Wrap);
        let _ = view.display_render();

        let _ = gameloop::sleep_fps(FPS, None);
    }
}
examples/self-resizing.rs (line 34)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
fn main() {
    let mut scale_view = ScaleFitView::new(ColChar::BACKGROUND);

    let mut text = Text::new(Vec2D::ZERO, "This is some centered text!", Modifier::None)
        .with_align(TextAlign::Centered);

    let mut sprite =
        Sprite::new(Vec2D::ZERO, TEXTURE, Modifier::None).with_align(TextAlign2D::CENTERED);

    loop {
        text.pos = scale_view.intended_size() / 2;
        sprite.pos = scale_view.intended_size() / 2;
        sprite.pos.y -= 5;

        scale_view.update();
        scale_view.view.blit(&text, Wrapping::Wrap);
        scale_view.view.blit(&sprite, Wrapping::Wrap);
        let _ = scale_view.view.display_render();

        sleep(Duration::from_millis(10));
    }
}
examples/spinning-cube.rs (line 31)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
examples/donut.rs (line 45)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}
examples/multi-movement.rs (line 45)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
fn main() {
    let mut view = View::new(50, 12, ColChar::BACKGROUND);

    let mut blocks = vec![
        Rect::new(Vec2D::new(0, 0), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 2), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 4), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 6), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 8), BLOCK_SIZE, FILL_CHAR),
        Rect::new(Vec2D::new(0, 10), BLOCK_SIZE, FILL_CHAR),
    ];

    let mut i = 0;
    fps_gameloop!(
        {
            i += 1;
            for (j, block) in (0u32..).zip(blocks.iter_mut()) {
                if i % 2_u32.pow(j) == 0 {
                    block.pos.x += 1;
                }
            }
        },
        {
            view.clear();
            for block in &blocks {
                view.blit(block, Wrapping::Wrap);
            }
            let _ = view.display_render();

            if blocks
                .iter()
                .all(|b| b.pos.x % isize::try_from(view.width).expect("Wrapped usize") == 0)
            {
                thread::sleep(Duration::from_secs(2));
            };
        },
        200.0
    );
}

Trait Implementations§

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> 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,

§

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§

default 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>,

§

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>,

§

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.