For now, the main function is very small. First, let's add the following lines at the top of the function:
let sdl_context = sdl2::init().expect("SDL initialization
failed"); let video_subsystem = sdl_context.video().expect("Couldn't get
SDL video subsystem"); let width = 600; let height = 800;
No need for explanations, we've already explained everything in the previous chapters, so let's continue.
Just after the following lines:
let sdl_context = sdl2::init().expect("SDL initialization
failed"); let mut tetris = Tetris::new(); let mut timer = SystemTime::now(); let mut event_pump = sdl_context.event_pump().expect("Failed to
get SDL event pump"); let grid_x = (width - TETRIS_HEIGHT as u32 * 10) as i32 / 2; let grid_y = (height - TETRIS_HEIGHT as u32 * 16) as i32 / 2;
Let's add the following ones:
let window = video_subsystem.window("Tetris", width, height) .position_centered() // to put it in the middle of the screen .build() // to create the window .expect("Failed to create window"); let mut canvas = window.into_canvas() .target_texture() .present_vsync() // To enable v-sync. .build() .expect("Couldn't get window's canvas"); let texture_creator: TextureCreator<_> = canvas.texture_creator(); let grid = create_texture_rect(&mut canvas, &texture_creator, 0, 0, 0, TETRIS_HEIGHT as u32 * 10, TETRIS_HEIGHT as u32 * 16).expect("Failed to create
a texture"); let border = create_texture_rect(&mut canvas, &texture_creator, 255, 255, 255, TETRIS_HEIGHT as u32 * 10 + 20, TETRIS_HEIGHT as u32 * 16 + 20).expect("Failed to create
a texture"); macro_rules! texture { ($r:expr, $g:expr, $b:expr) => ( create_texture_rect(&mut canvas, &texture_creator, $r, $g, $b, TETRIS_HEIGHT as u32, TETRIS_HEIGHT as u32).unwrap() ) } let textures = [texture!(255, 69, 69), texture!(255, 220, 69),
texture!(237, 150, 37),texture!(171, 99, 237), texture!(77, 149,
239), texture!(39, 218, 225), texture!(45, 216, 47)];
There's even a macro in the middle, so yes, a few explanations are required!
let window = video_subsystem.window("Tetris", width, height) .position_centered() .build() .expect("Failed to create window"); let mut canvas = window.into_canvas() .target_texture() .present_vsync() .build() .expect("Couldn't get window's canvas"); let texture_creator: TextureCreator<_> = canvas.texture_creator();
We've already seen all this, so we'll just go very quickly through each:
- We create the window.
- We initialize the area where we'll draw.
- We initialize the texture engine.
The two next calls are more interesting and are the start of the actual UI rendering:
let grid = create_texture_rect(&mut canvas, &texture_creator, 0, 0, 0, TETRIS_HEIGHT as u32 * 10, TETRIS_HEIGHT as u32 * 16).expect("Failed to create a texture"); let border = create_texture_rect(&mut canvas, &texture_creator, 255, 255, 255, TETRIS_HEIGHT as u32 * 10 + 20, TETRIS_HEIGHT as u32 * 16 + 20).expect("Failed to create a texture");
They both call a function defined in Chapter 2, Starting with SDL. grid is where we'll draw the tetriminoes and border to represent the borders of the game area. The first one is black, whereas the other one is white. The following is a screenshot of what they'll look like:

So now let's write down the code to load more easily:
macro_rules! texture { ($r:expr, $g:expr, $b:expr) => ( create_texture_rect(&mut canvas, &texture_creator, $r, $g, $b, TETRIS_HEIGHT as u32, TETRIS_HEIGHT as u32).unwrap() ) }
We already introduced macros in Chapter 1, Basics of Rust, so we will assume you'll understand pretty easily what this one is doing. (It calls the create_texture_rect function with $r, $g, and $b being the color we want the texture to be.)
let textures = [texture!(255, 69, 69), texture!(255, 220, 69),
texture!(237, 150, 37), texture!(171, 99, 237), texture!(77, 149,
239), texture!(39, 218, 225), texture!(45, 216, 47)];
In here, we create the textures for our tetriminoes blocks. So seven textures for seven types of tetrimino blocks.
We initialized everything we needed for the rendering. So now, let's render!