pub struct Buffer { /* private fields */ }
Expand description

A screen buffer that can be rendered to, has a size

This is the backbone of ascii-forge

Example

use ascii_forge::prelude::*;

// A 30x30 buffer window
let mut buffer = Buffer::new(30, 30);

// Render Hello World to the top left of the buffer
render!(
    buffer, [
        (0, 0) => "Hello World!"
    ]
);

Implementations§

source§

impl Buffer

source

pub fn new(size: impl Into<Vec2>) -> Self

Creates a new buffer of empty cells with the given size.

source

pub fn size(&self) -> Vec2

Returns the current size of the buffer.

Examples found in repository?
examples/space_invaders.rs (line 273)
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
pub fn app(window: &mut Window) -> io::Result<String> {
    let mut score = 0;
    let mut player = Player::new(window, 'W'.green());

    let mut projectiles = vec![];

    let mut enemies = vec![];

    let mut delta = Duration::ZERO;

    let mut spawner = Duration::from_millis(800);

    let mut move_timer = Duration::from_millis(200);

    let mut shoot_timer = Duration::from_millis(500);

    let info_text = Buffer::sized_element("Press C-q to quit");

    // Main Game Loop
    loop {
        let start = SystemTime::now();
        // update the window, without blocking the screen
        window.update(Duration::from_secs_f64(1.0 / 60.0))?;

        if window.code(KeyCode::Char(' ')) {
            projectiles.push(Projectile::new(
                vec2(player.loc.x - 1, player.loc.y - 1),
                -0.3,
                "|||".green(),
            ))
        }

        // Render and update projectiles
        projectiles.retain(|x| x.alive(window));

        projectiles.iter_mut().for_each(|x| {
            x.update();
            x.draw(window);
        });

        // Render and update the player.
        player.update(window);
        player.draw(window);

        match spawner.checked_sub(delta) {
            Some(s) => spawner = s,
            None => {
                enemies.push(Enemy::new(vec2(0, 3), 'M'.red(), 10));
                spawner = Duration::from_secs(2);
            }
        }

        match move_timer.checked_sub(delta) {
            Some(m) => move_timer = m,
            None => {
                if enemies.iter_mut().any(|x| x.enemy_move(window)) {
                    return Ok(format!("Game Over\nScore was: {}", score));
                }
                move_timer = Duration::from_millis(200);
            }
        }

        if player.hit(&projectiles) {
            return Ok(format!("Game Over\nScore was: {}", score));
        }

        match shoot_timer.checked_sub(delta) {
            Some(s) => shoot_timer = s,
            None => {
                enemies.iter_mut().for_each(|x| {
                    projectiles.push(Projectile::new(vec2(x.loc.x, x.loc.y + 1), 0.3, "|".red()))
                });
                shoot_timer = Duration::from_millis(500);
            }
        }

        enemies.retain_mut(|x| {
            if x.hit(&projectiles) {
                score += x.score;
                false
            } else {
                true
            }
        });

        enemies.iter_mut().for_each(|x| x.draw(window));

        render!(
            window, [
                vec2(0, 0) => format!("Score: {}", score),
                vec2(window.size().x - info_text.size().x, 0) => info_text
            ]
        );

        if window.key(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL)) {
            break;
        }

        delta = SystemTime::now().duration_since(start).unwrap();
    }

    Ok("Game Exited".to_string())
}
source

pub fn set<C: Into<Cell>>(&mut self, loc: impl Into<Vec2>, cell: C)

Sets a cell at the given location to the given cell

source

pub fn get(&self, loc: impl Into<Vec2>) -> &Cell

Returns a reverence to the cell at the given location.

source

pub fn get_mut(&mut self, loc: impl Into<Vec2>) -> &mut Cell

Returns a mutable reference to the cell at the given location.

source

pub fn clear(&mut self)

Clears the buffer

source

pub fn diff<'a>(&self, other: &'a Buffer) -> Vec<(Vec2, &'a Cell)>

Returns the cells and locations that are different between the two buffers

source

pub fn shrink(&mut self)

Shrinks the buffer to the given size by dropping any cells that are only whitespace

source

pub fn resize(&mut self, new_size: impl Into<Vec2>)

Resizes the buffer while retaining elements that have already been rendered

source

pub fn sized_element<R: Render>(item: R) -> Self

Creates a Buffer from the given element with the minimum size it could have for that element. Useful for if you want to store any set of render elements in a custom element.

Examples found in repository?
examples/space_invaders.rs (line 199)
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
pub fn app(window: &mut Window) -> io::Result<String> {
    let mut score = 0;
    let mut player = Player::new(window, 'W'.green());

    let mut projectiles = vec![];

    let mut enemies = vec![];

    let mut delta = Duration::ZERO;

    let mut spawner = Duration::from_millis(800);

    let mut move_timer = Duration::from_millis(200);

    let mut shoot_timer = Duration::from_millis(500);

    let info_text = Buffer::sized_element("Press C-q to quit");

    // Main Game Loop
    loop {
        let start = SystemTime::now();
        // update the window, without blocking the screen
        window.update(Duration::from_secs_f64(1.0 / 60.0))?;

        if window.code(KeyCode::Char(' ')) {
            projectiles.push(Projectile::new(
                vec2(player.loc.x - 1, player.loc.y - 1),
                -0.3,
                "|||".green(),
            ))
        }

        // Render and update projectiles
        projectiles.retain(|x| x.alive(window));

        projectiles.iter_mut().for_each(|x| {
            x.update();
            x.draw(window);
        });

        // Render and update the player.
        player.update(window);
        player.draw(window);

        match spawner.checked_sub(delta) {
            Some(s) => spawner = s,
            None => {
                enemies.push(Enemy::new(vec2(0, 3), 'M'.red(), 10));
                spawner = Duration::from_secs(2);
            }
        }

        match move_timer.checked_sub(delta) {
            Some(m) => move_timer = m,
            None => {
                if enemies.iter_mut().any(|x| x.enemy_move(window)) {
                    return Ok(format!("Game Over\nScore was: {}", score));
                }
                move_timer = Duration::from_millis(200);
            }
        }

        if player.hit(&projectiles) {
            return Ok(format!("Game Over\nScore was: {}", score));
        }

        match shoot_timer.checked_sub(delta) {
            Some(s) => shoot_timer = s,
            None => {
                enemies.iter_mut().for_each(|x| {
                    projectiles.push(Projectile::new(vec2(x.loc.x, x.loc.y + 1), 0.3, "|".red()))
                });
                shoot_timer = Duration::from_millis(500);
            }
        }

        enemies.retain_mut(|x| {
            if x.hit(&projectiles) {
                score += x.score;
                false
            } else {
                true
            }
        });

        enemies.iter_mut().for_each(|x| x.draw(window));

        render!(
            window, [
                vec2(0, 0) => format!("Score: {}", score),
                vec2(window.size().x - info_text.size().x, 0) => info_text
            ]
        );

        if window.key(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL)) {
            break;
        }

        delta = SystemTime::now().duration_since(start).unwrap();
    }

    Ok("Game Exited".to_string())
}

Trait Implementations§

source§

impl AsMut<Buffer> for Buffer

source§

fn as_mut(&mut self) -> &mut Buffer

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsMut<Buffer> for Window

source§

fn as_mut(&mut self) -> &mut Buffer

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl Debug for Buffer

source§

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

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

impl Render for Buffer

source§

fn render(&self, loc: Vec2, buffer: &mut Buffer)

Auto Trait Implementations§

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