Making Tetris in Rust and Wasm (Part 1)

The Tetris Video Framework (Part 1)

HTML, Javascript, and the CanvasRenderingContext


Note: This post ended up a lot longer than I intended so I've split it in to two articles. They're still written as if they're one article. Keep that in mind.


Since the dawn of time people have been making flash games. In 1995, classicgames.com made its way on to the world stage with the classics: Solitaire, Checkers, and Poker. Newgrounds followed in 1977 with its classics: Club a Seal, Assassin, Three Foot Ninja. Now flash is dead, burned to dust by the likes of Mozilla Firefox and Google Chrome, and a new hero is rising. HTML5 and the <canvas> element. Joined by Rust and WebAssembly I will use these tools to create... a complete game of Tetris.

In this post I take a look at the canvas element, Rust/WASM compilation, and embedding a WASM applet in JS. Follow me on my journey to learn the ins and outs of the Modern Day Flash Game.

1 - Lets start at the very beginning

Like everything in this too-much-information age it's often difficult to know where to start. There are so many tutorials out there that all start differently and teach you different things. Below I've listed some of the ones I read. We'll start at the very beginning, with a file.


http://www.chinedufn.com/3d-webgl-basic-water-tutorial/
https://rustwasm.githu b.io/docs/book/
https://www.pmg.com/blog/my-firsthand-experience-with-rust-webassembly/
https://www.reddit.com/r/rust/comments/9t95fd/howto _setting_up_webassembly_ on_stable_rust/
https://dev .to/dandyvica/wasm-in-rust-without-nodejs-2e0c


And now the file:
Computer desktop showing blank html document named 'index.html'
Create a file index.html and open it up in your favorite text editor
Notepad++ showing the skeleton index.html with an h1 tag: 'Tetris'. Go to my 
            github and find src/source/empty_index for the source
Start with a basic HTML skeleton. There are better ones out there. You can tell me about them in the comments. For now we're using this skeleton. It has a doctype and two meta tags.

The doctype is important. It tells your web browser what kind of document you have. It's also vestigial. You'll always use the HTML5 !doctype html. You can view the official list of other doctypes here.

The two meta tags are also important. The charset tag guarantees your fonts are rendered correctly eg when using emoji or Mandarin. The viewport tag is important due to the wide range of device sizes in today's world. Notice how my blog renders on mobile without the need for a separate mobile site. I got these from htmlhead.dev.

Now open index.html in your favorite web browser. Screenshot of index.html open in firefox. 'Tetris' is displayed on the page
If yours doesn't look like mine you did something wrong. Look at your code, compare it to mine, do some research, browse Stack Overflow. If nothing's working feel free to email me or comment below.

2 - A very good place to start

Now we're gonna take a look at some javascript, some graphics, and compile our first wasm.
index.html with a canvas element. Go to my github and find src/source/start_2 for the source
First make your webpage look like mine. We've added a title and an icon, a canvas, and a link to this blog.

The title is simple. It's the name of your webpage. You can see it at the top there next to the favicon.ico. It says "Tetris" instead of "index.html". To generate the favicon head to head over to a favicon generator, I used favicon.io.

Next is the canvas element. Unlike many elements it's got its own width and height attributes (usually you'll control an object's size with the style tag). This is because canvas is a rendering element, it's our graphics bread and butter. Style is applied as a final touch of displaying a web page and canvas needs to have its width and height available for its computations. Speaking of computations, check out the canvas MDN page for more canvas guides, tutorials and libraries and look at the javascript below.
index.html after adding some javascript to draw a rectangle on our canvas element. Go to my github and find src/source/javascript_1 for the source
First thing we did was add some script tags so we can write some javascript. These can go anywhere and you'll often see them in the head so they don't ruin formatting. Next thing we did was get our canvas. getElementsByTagName will return every canvas element in the document (on the page). We only have 1 canvas element so we know our canvas element will be the 0th item in the returned list. We use it to get our rendering context.

The rendering context is what we use to draw to the screen. We're using the 2d rendering context but therer are also the bitmap and webgl2 contexts available. The 2d rendering context has some basic built in drawing functions. Similar to the tools you'd find in Paint rather than Illustrator or Photoshop. Speaking of though, there are some vector graphics functions like Arc, LineTo, and BezierCurveTo.

We drew a rectangle.
index.html after adding more javascript that adds text to our canvas element. Go to my github and find src/source/javascript_2 for the source.
And added some text.
A HAL9000 replica drawn entirely in javascript. See src/source/HAL9000 for the source
Draw the rest of the fucking owl.

3 - Rust and Web Assembly

So yea, I did an art project instead of finishing up this article. It was getting really long though and I was going to have to split it into 3 movies anyway, so goodbye, Here's a picture of a cat.

A sleepy kitty snoozing in a sleepy kitty hammock