Rust Web Assembly - Building a Canvas Snake Game using Stdweb - Part 1
Repository
https://github.com/rust-lang/rust
What Will I Learn?
- You will learn how to use the Cargo Web server
- You will learn how to scale a Canvas element
- You will learn about variable shadowing
- You will learn how to use query selector
- You will learn how to create animations by redrawing the screen
- You will learn how to manipulate HTML Canvas with Stdweb
Requirements
System Requirements:
- Visual Studio Code or any other Text Editor with Rust language plugins
- The Rustup command line tool and the nightly Rust compiler
Required Knowledge
- Some understanding of JavaScript and Node.Js
- Some basic understanding of Rust
- A fair amount of knowledge on web technologies and how they work
Resources for Rust
- Rust Website: https://www.rust-lang.org/
- Web Assembly Website: https://webassembly.org/
- Awesome Rust: https://github.com/rust-unofficial/awesome-rust
- Wasm Bindgen Repo: https://github.com/rustwasm/wasm-bindgen
Sources
- WASM Logo: https://webassembly.org/
Difficulty
- Intermediate
Description
Outline and Overview
In this Web Assembly Rust Video Tutorial, we take a look at how we can build a renderer and a direction module for a snake game using HTML canvas and stdweb
. The direction module contains an enum which defines the valid directions for the snake's movement and the canvas module contains a structure which generates and renders out canvas animations. We add functionality that allows us to scale the components of our game with the canvas as well as draw and clear any element on the canvas.
Building a Movement Directional Enum
The direction Enum that we created in this project allows us to define a type that contains multiple variants. Each of these variants is a direction but is also distinct from the other directions. This enumerated type acts like an algebraic data type from other functional languages and is the best way to describe the movement of a object like a snake.
The direction enum has types for up, down, left and right. We also created a small little method which allows us to run a boolean expression to check to see if the user is attempting to move the snake in an opposite direction from the one it is currently moving in. We do this to prevent the user from automatically and accidentally initiating a game fail state. Since the snake head can not overlap with the snake body, moving to the left after having the snake move right would automatically cause a game over.
Using Shadow Variables for Better Code Readability
In Rust, variables are immutable by default. This means that you are unable to mutate a variable or reassign it to the same variable name. You can however, create a variable shadow by using the same variable name for a different variable declaration. In this way, rather then mutating the variable value, we are able to create a new variable with the same name and have that value replace the old value for the rest of the variable's scope. Shadowing also makes it possible to change the type of a variable so long as you use the let
keyword to define the shadowed variable.
In our application's Canvas renderer, we use shadowed variables to help with the readability of our code. Because we want to rescale our canvas resolution to a more easy to work with structure, we need to rescale any position that we are passing into the draw method that we defined. We do this by taking the value and multiplying it by the scaled value that is connected to its dimension. This allows us to keep our scaling consistent across the entire code base.
Rendering and Manipulating HTML canvas with Stdweb
The most important part of the project thus far is the canvas renderer. The Canvas render allow the code to properly attach itself to the HTML document and then produce the shapes that will be needed to create the game. This is done through the CanvasElement
and the CanvasRenderingContext2d
which are both grouped together on the canvas struct. The renderer also is the part of the code that allows us to scale the canvas element into a more usable coordinate plane.
We bind the CanvasElement
and the CanvasRenderingContext2d
together to the scaled width and height as well as the width and height that is used to derive that scaled width and height. This then allows us to verify that the point that we are drawing is indeed inside of the coordinate plane. We can then take the context and attach a color to it which then allows us to fill out the rendered squares with that color.
The source code for this project can be found here
Video Tutorial
Curriculum
- Intro to Rust Web Assembly with Rust's Wasm Bindgen Library
- Rust Web Assembly - Building a Simple Markdown Parser with Rust's Wasm Bindgen
- Rust Web Assembly - Using Stdweb to Build a Client side Application with Rust and WASM
Excellent work @tensor. I always love following your video tutorials. Your coverage of these functions is thorough and concise. You make no assumptions of the learners' skills and knowledge and you do not seem to tire of providing context. These attributes make for excellent learning resources. Thank you.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thanks again @buckydurddle for reviewing my contributions. I know that you are at a festival so I do appreciate you taking the time to do this.
My pleasure @tensor.
Cheers
Hey @tensor
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!