Vector Engine and AssemblyScript Classes
April 30, 2021
NOTE: I skip over a lot of AssemblyScript basics in this tutorial. If you need help, please contact me on twitter (@battagline) or the AssemblyScript Discord (http://discord.gg/assemblyscript) (gamedev channel)
This tutorial is the second in my AssemblyScript / Vector Engine game development series. If
you haven't read my introductory tutorial in this series, you may
want to start there. In the previous tutorial, I showed you how
to draw loops to the canvas by calling renderLoop. The problem with calling
renderLoop directly is that you need to pass all the loop properties every
time. It is even more complicated when you want to render multiple loops for the same
object. Instead, we can declare a class that contains all of our loop data. We can have x, y,
scale, rotation, and color attributes that apply to all the loops for that game object. Doing
this can simplify our code.
Smile class
After importing DisplayString and renderLoop I declare a class
called Smile. This class has an attribute for every value I pass
into renderLoop. These public attributes are color,
x, y, rotation and scale. In addition,
it has four static arrays used to define four different loops used to render a smiley face.
These arrays are main_layer, lefteye_layer, righteye_layer,
and mouth_layer. All of these loops will be rendered within a render
method. Here is what the Smile class declaration looks like:
import { DisplayString, renderLoop } from 'vectorengine';
class Smile {
public color: u32 = 0x00_ff_00_ff;
public x: f32 = 0.0;
public y: f32 = 0.0;
public rotation: f32 = 0.0;
public scale: f32 = 0.0;
private main_layer: StaticArray<f32> =
[-0.125, 0.609375, 0.125, 0.609375, 0.375, 0.5,
0.5, 0.375, 0.625, 0.125, 0.6328125, -0.1328125,
0.5078125, -0.3828125, 0.3828125, -0.5078125, 0.125, -0.625,
-0.125, -0.625, -0.3671875, -0.5078125, -0.4765625, -0.3828125,
-0.6171875, -0.1328125, -0.6171875, 0.1171875, -0.4921875, 0.3671875,
-0.3671875, 0.4921875,];
private lefteye_layer: StaticArray<f32> = [
-0.34375, 0.24375, -0.28125, 0.275, -0.21875, 0.275,
-0.15625, 0.24375, -0.125, 0.18125, -0.125, 0.11875,
-0.15625, 0.05625, -0.21875, 0.025, -0.28125, 0.025,
-0.34375, 0.05625, -0.375, 0.103125, -0.375, 0.18125,];
private righteye_layer: StaticArray<f32> = [
0.34375, 0.24375, 0.28125, 0.275, 0.21875, 0.275,
0.15625, 0.24375, 0.125, 0.18125, 0.125, 0.11875,
0.15625, 0.05625, 0.21875, 0.025, 0.28125, 0.025,
0.34375, 0.05625, 0.375, 0.103125, 0.375, 0.18125,];
private mouth_layer: StaticArray<f32> = [
-0.375, -0.171875, 0.375, -0.171875, 0.3125, -0.375,
0.125, -0.5, -0.125, -0.5, -0.3125, -0.375,];
public render(): void {
renderLoop(this.main_layer, this.x, this.y, this.color, this.rotation, this.scale);
renderLoop(this.lefteye_layer, this.x, this.y, this.color, this.rotation, this.scale);
renderLoop(this.righteye_layer, this.x, this.y, this.color, this.rotation, this.scale);
renderLoop(this.mouth_layer, this.x, this.y, this.color, this.rotation, this.scale);
}
}
Creating Smile Objects
Once the class is declared, we need to create some objects using the Smile class.
I'm going to make three smile objects, each with a scale of 0.15. They will have different x
positions and colors. Here is the code that makes those three smile objects:
var smile = new Smile();
smile.scale = 0.15;
var smile_left = new Smile();
smile_left.x = -0.4;
smile_left.color = 0xff_00_ff_ff;
smile_left.scale = 0.15;
var smile_right = new Smile();
smile_right.x = 0.4;
smile_right.color = 0x00_ff_ff_ff;
smile_right.scale = 0.15;
let timeChange: f32 = 0.0;
const wasmBook = new DisplayString("WasmBook.com", 0.0, 0.3, 0.04, 0xff_ff_00_ff);
After defining the smile objects, the code above creates a timeChange variable
and a DisplayString constant called wasmBook. After these global
variables are declared, we will create the game loop.
The Game Loop
The game loop uses the timeChange variable to modify the rotation attribute for one
smiley faces. I render the other two smiley faces without adjusting the attributes. I also
render the wasmBook DisplayText constant. Here is that code:
export function gameLoop(delta: i32): void {
timeChange += <f32>delta / 1000.0;
smile.rotation = timeChange;
smile.render();
smile_left.render();
smile_right.render();
wasmBook.render();
}
Compile and run
Now you can compile the Wasm binary using the following asc command:
asc class.ts --importMemory -Oz -o class.wasm
HTML
The HTML file that runs this application is almost identical to the code used in the initial
Vector Engine tutorial. The only difference is the name of the
Wasm file, which is class.wasm in this file, and was helloworld.wasm in
the previous. Here is that HTML code:
<html>
<head>
<style>
body {
background-color: #3b3b3b;
text-align: center;
}
</style>
</head>
<body>
<canvas width="640" height="640" id="cnvs"></canvas>
<script type="module">
import { runVectorGame } from "https://unpkg.com/vectorengine/lib/VectorEngine.js";
runVectorGame("cnvs", "class.wasm", "gameLoop", 1);
</script>
</body>
</html>
Keep in mind that you need to serve this file from a web server for it to work. If you try to open the file directly in a web browser, it will throw an error when it tries to load the Wasm file. When you run your web browser and use it to serve the app, it should look something like this:
You can view a working version of the application here. You can also see what the completed AssemblyScript code looks like here. (AssemblyScript code | view application)


