Before going any further, we actually need a font. I chose Lucida console, but pick the one you prefer, it doesn't really matter. Once downloaded, put it in the assets folder as well. Now, time to actually load the font:
let font = ttf_context.load_font("assets/lucida.ttf", 128).expect("
Couldn't load the font");
Note that if you want to apply a style to your font (such as bold, italic, strikethrough, or underline), that's the object on which you need to apply it. Here is an example:
font.set_style(sdl2::ttf::STYLE_BOLD);
Now, two steps are remaining to be able to actually display text:
- Render the text.
- Create a texture from it.
Let's write a function in order to do so:
fn create_texture_from_text<'a>(texture_creator: &'a
TextureCreator<WindowContext>, font: &sdl2::ttf::Font, text: &str, r: u8, g: u8, b: u8, ) -> Option<Texture<'a>> { if let Ok(surface) = font.render(text) .blended(Color::RGB(r, g, b)) { texture_creator.create_texture_from_surface(&surface).ok() } else { None } }
Looks a lot like create_texture_rect, right?
Why not test it? Let's call the function and paste the texture onto the screen to see:
let rendered_text = create_texture_from_text(&texture_creator,
&font, "test", 255, 255, 255).expect("Cannot render text"); canvas.copy(&rendered_text, None, Some(Rect::new(width as i32 -
40, 0, 40, 30))) .expect("Couldn't copy text");
And it looks like this:

For the texture rectangle, I use the following rule: one character is a block of 10 x 30 pixels. So in this example, since test has 4 letters, we need a block of 40 x 30 pixels. Let's write a function to make this easier:
fn get_rect_from_text(text: &str, x: i32, y: i32) -> Option<Rect> { Some(Rect::new(x, y, text.len() as u32 * 20, 30)) }
Ok, so now is the time to render the game information and write a new function to do it:
fn display_game_information<'a>(tetris: &Tetris, canvas: &mut Canvas<Window>, texture_creator: &'a TextureCreator<WindowContext>, font: &sdl2::ttf::Font, start_x_point: i32) { let score_text = format!("Score: {}", tetris.score); let lines_sent_text = format!("Lines sent: {}", tetris.nb_lines); let level_text = format!("Level: {}", tetris.current_level); let score = create_texture_from_text(&texture_creator, &font, &score_text, 255, 255, 255) .expect("Cannot render text"); let lines_sent = create_texture_from_text(&texture_creator, &font, &lines_sent_text, 255, 255, 255) .expect("Cannot render text"); let level = create_texture_from_text(&texture_creator, &font, &level_text, 255, 255, 255) .expect("Cannot render text"); canvas.copy(&score, None, get_rect_from_text(&score_text,
start_x_point, 90)) .expect("Couldn't copy text"); canvas.copy(&lines_sent, None, get_rect_from_text(&score_text,
start_x_point, 125)) .expect("Couldn't copy text"); canvas.copy(&level, None, get_rect_from_text(&score_text,
start_x_point, 160)) .expect("Couldn't copy text"); }
And then we call it, as follows:
display_game_information(&tetris, &mut canvas, &texture_creator, &font, width as i32 - grid_x - 10);
And now it looks like this:

Wonderful, we have the game information in real time! Isn't it awesome? What? It's ugly and overlaps the game? Let's move the game then! Instead of centering it, we'll give it a fixed x position (which will make our formula way simpler).
First, let's update our grid_x variable:
let grid_x = 20;
Then, let's update so canvas.copy calls:
canvas.copy(&border, None, Rect::new(10, (height - TETRIS_HEIGHT as u32 * 16) as i32 / 2 - 10, TETRIS_HEIGHT as u32 * 10 + 20, TETRIS_HEIGHT as u32 * 16 + 20)) .expect("Couldn't copy texture into window"); canvas.copy(&grid, None, Rect::new(20, (height - TETRIS_HEIGHT as u32 * 16) as i32 / 2, TETRIS_HEIGHT as u32 * 10, TETRIS_HEIGHT as u32 * 16)) .expect("Couldn't copy texture into window");
And that's it. You now have a nice Tetris playing:

We could improve the display a bit by adding a border around the text, or even display a preview of the next piece, or even add a ghost, but I think that, from this point, you can add them easily.
That's it for this Tetris, have fun while playing with the sdl2!