Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon Join the GFS Discord Server!
18. June 2018

The PlayCanvas HTML5 game engine just added 2D support in the form of Sprites, texture atlases, animated sprites, sprite components and 9 patch support.

From the PlayCanvas blog:

PlayCanvas is one of the most popular ways to build 3D interactive web content today. But before 3D graphics was a thing, there was 2D graphics!

Today we’re excited to launch the first part of our 2D graphics support. Great for building classic 2D games.

There are 5 great new features which will help you build 2D games using PlayCanvas.

Those new features are:

  • Texture Atlas assets
  • Sprite Asset
  • Sprite Component
  • Sprite Editor
  • 9 Slicing

For more details on the new 2D functionality in the PlayCanvas editor, be sure to check out this hands-on video where we illustrate how to import a texture atlas and use it to create 2D sprite animations:

If you are interested in learning more about PlayCanvas, be sure to check out our two part tutorial on building a simple bowling title in PlayCanvas available here and here.

GameDev News

3. May 2018

Impactjs is a 2D HTML5 game engine with a built in level editor called Weltmeister.  Previously it was commercial software with a $99 price tag.  Earlier today the author made the following tweet:


The engine is now available under the MIT open source license.  It’s available on Github right here.  Unfortunately the editor has some PHP dependencies, making it somewhat tricky to get up and running without a full blown PHP install.

It’s been several years since Impact was updated, so unless a community forms around this libraries open sourcing, I see little reason to recommend it.

GameDev News

15. March 2018

Google just open sourced Resonance Audio, their 3D spatial audio rendering SDK.  It supports multiple platforms and game engines including Unreal, Unity, wWise, FMod, iOS, Android and Web.  You can learn more about Resonance Audio here, while the source is hosted on Github under the liberal Apache 2 source license.  Resonance enables you to create and position audio sources in 3D, define audio properties of your world, position the listener and it then calculates the results for you.

The following is a simple HTML5 sample that illustrates creating a 3D audioscape using the Web api.  It creates 3 different sounds, a laughing woman, a waterfall and a bird chirping, all downloaded from  The lady laughing can be moved around using the arrow keys as well as page up/down to move around the Z axis.  You can move the listeners ear left and right using the A and D key.  Finally the bird chirping will appear every 4 seconds in a random location relative to the users ear, + or – 1 meter.

You can get more details and hear the demo results in this video, which I will also embed below.  The sound works best when heard through a set of headphones.

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>GFS Resonance Audio Test</title>

    <script src=""></script>

        var laughX = 0.0;
        var laughY = 0.0;
        var laughZ = 0.0;

        var x = 0.0;
        var y = 0.0;
        var z = 0.0;

        // Create an AudioContext
        let audioContext = new AudioContext();

        // Create a (first-order Ambisonic) Resonance Audio scene and pass it
        // the AudioContext.
        let resonanceAudioScene = new ResonanceAudio(audioContext);

        // Connect the scene’s binaural output to stereo out.

        // Define room dimensions.
        // By default, room dimensions are undefined (0m x 0m x 0m).
        let roomDimensions = {
            width: 3.1,
            height: 2.5,
            depth: 3.4,

        // Define materials for each of the room’s six surfaces.
        // Room materials have different acoustic reflectivity.
        let roomMaterials = {
            // Room wall materials
            left: 'metal',
            right: 'curtain-heavy',
            front: 'curtain-heavy',
            back: 'curtain-heavy',
            // Room floor
            down: 'grass',
            // Room ceiling
            up: 'grass',

        // Add the room definition to the scene.
        resonanceAudioScene.setRoomProperties(roomDimensions, roomMaterials);

        /// -----------------  Laugh audio
        // Create an AudioElement.
        let audioElement = document.createElement('audio');

        // Load an audio file into the AudioElement.
        audioElement.src = 'laugh.wav';
        audioElement.loop = true;
        // Generate a MediaElementSource from the AudioElement.
        let audioElementSource = audioContext.createMediaElementSource(audioElement);
        // Add the MediaElementSource to the scene as an audio input source.
        let source = resonanceAudioScene.createSource();
        // Set the source position relative to the room center (source default position).
        source.setPosition(laughX, laughY, laughZ);

        /// -----------------  Waterfall
        // Create an AudioElement.
        let audioElement2 = document.createElement('audio');
        audioElement2.src = 'waterfall.wav';
        audioElement2.loop = true;
        let audioElementSource2 = audioContext.createMediaElementSource(audioElement2);
        let source2 = resonanceAudioScene.createSource();

        /// -----------------  Bird noises
        let audioElement3 = document.createElement('audio');
        audioElement3.src = 'bird.wav';
        audioElement3.loop = false;
        let audioElementSource3 = audioContext.createMediaElementSource(audioElement3);
        let source3 = resonanceAudioScene.createSource();

        // Play the audio.;;

            //randomly position bird  -1 to +1 x/y relative to the listeners location every 4 seconds
            source3.setPosition(x + Math.random() * 2 - 1 ,y + Math.random() * 2 - 1,1);

        window.addEventListener("keyup", function(event) {

            // Move laugh audio source around when arrow keys pressed
            if (event.which == 37) // left arrow key
                    source.setPosition(laughX -= 0.10, laughY, laughZ);
            if (event.which == 39) // right arrow key
                    source.setPosition(laughX += 0.10, laughY, laughZ);
            if (event.which == 38) // up arrow key
                    source.setPosition(laughX , laughY += 0.10, laughZ);
            if (event.which == 40) // down arrow key
                    source.setPosition(laughX, laughY -= 0.10, laughZ);
            if (event.which == 33) // page up arrow key
                source.setPosition(laughX , laughY, laughZ += 0.10);
            if (event.which == 34) // page down arrow key
                source.setPosition(laughX, laughY, laughZ -= 0.10);
            if (event.which == 32) // space key
                laughX = 0;
                laughY = 0;
                laughZ = 0;
                source.setPosition(laughX, laughY, laughZ);

            // Move the listener left or right on A/D keys
            if (event.which == 65){ //A
            if (event.which == 68){ //D
        }, this);



The video

GameDev News Programming

30. May 2017

Back in Part One of our look at the PlayCanvas HTML5 3D game engine, we started creating our simple bowling game.  We already created our lane and pins.  Now it is time to continue on and create our bowling ball.  Attached to our bowling ball will also be the script the controls the majority of our game.  Let’s jump back in.

Creating the Bowling Ball

This time, instead of importing a model, we are simply going to use a built in procedurally generated mesh.  Simply right click the Root in the Hierarchy view, select New Entity then Sphere.


Scale the newly created ball down and position it accordingly.


Under the Entity properties, I renamed it from Sphere to BowlingBall.  Right now our ball doesn’t look all that great.  Let’s go ahead and make it a bit shiny.  Right click in the asset area, select New Asset->Material.


Select the newly created material from the assets tab.  In the Material panel, I rename it to BowlingBallMaterial.  What I want to do is make the bowling ball a bit shiny.  I am going to leave it white, but if you want to change the color, do so under the Diffuse tab.  Next head on down to the Specular tab.  I used the following settings


Finally we need to apply the material to our bowling ball.  In the Hierarchy view, select the BowlingBall entity, under the Model panel, select our newly created Material.


Our bowling ball also needs to have a Collision shape and Rigid Body attached to it.



Be sure to set the Collision object to a Sphere and size the radius to be only slightly larger than our bowling ball model.

Now we have all the pieces needed for our game.  The pins, the lane and the bowling ball.  Now all we need to do is add some logic to the game.  This is done by attaching scripts to entities within our game.  In this case we are going to attach the logic to our bowling ball.


With our BowlingBall entity active, add a component and select Script.


Scroll down to the Script panel, select Add Script->New Script.


Enter a name for the script.


Now click Edit Script to launch the script editor.


Now enter the following script:

var BallScript = pc.createScript('ballScript');

BallScript.attributes.add('speed', {
    type: 'number',
    default: -8

BallScript.prototype.initialize = function() {
    this.entity.collision.on('collisionstart', this.onCollisionStart, this);'keydown', this.onKeyDown, this);
    var pins ="Pin");
    this.startingPositions = [];
    this.startingRotations = [];
    for(var i = 0; i < pins.length; i++){
    this.ballPosition ="BowlingBall").getLocalPosition().clone();
    this.ballMoving = false;

BallScript.prototype.onCollisionStart = function (result) {
    if (result.other.rigidbody) {
        if( == "BowlingPin")

BallScript.prototype.onKeyDown = function(e) {
    if(e.key == pc.KEY_SPACE || e.key == pc.KEY_W){
        this.entity.rigidbody.applyImpulse(0,0, this.speed);
        this.ballMoving = true;
    if(e.key == pc.KEY_R){
        var pins ="pin");
        for(var i = 0; i < pins.length; i++){
                pins[i].rigidbody.linearVelocity = pc.Vec3.ZERO;
                pins[i].rigidbody.angularVelocity = pc.Vec3.ZERO;
        // now the ball
        this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO;
        this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO;
        this.ballMoving = false;
    if(e.key == pc.KEY_B){
         // Just the ball
        this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO;
        this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO;
        this.ballMoving = false;
    if(e.key == pc.KEY_LEFT || e.key == pc.KEY_A){
    if(e.key == pc.KEY_RIGHT || e.key == pc.KEY_D){

// update code called every frame
BallScript.prototype.update = function(dt) {

One thing you may notice in the script above is the definition of the speed attribute.  This exposes this variable back to the editor, like so:


You may notice the line of code in the script for playing audio when we collide with a pin:

    if (result.other.rigidbody) {
        if( == "BowlingPin")

Now we need to add this audio asset to our bowling ball.  First add the audio file as an asset.  Simply click add asset –> Upload, then upload a WAV file.  Now we need to add a sound component to our BowlingBall entity. 


Now scroll down to Slot 1 and add the asset you just uploaded and be sure to set name to Hit.


And done.  A complete, rather simple but fully functioning 3D bowling game in just a few minutes.

The Video


25. May 2017

I featured the PlayCanvas engine a couple years ago in this Closer Look review.  PlayCanvas is a 3D HTML5 powered game engine with a full suite of editing tools.  In the time since that initial review, PlayCanvas has advanced a great deal, so I have decided to revisit the engine.  Much of the engine has remained the same as it was, just generally improved all around.  Therefore I have decided instead of another review, I will do a hands on tutorial showing how to create a simple game using PlayCanvas.  In this case, a bowling game.  For Patreon backers all the assets used to make this tutorial are now available including Blender files, FBX, textures and more.

There is a video version of this tutorial available here.

Spoiler alert... here is the “game” we are about to create in this tutorial.

Click the window to focus.

Press spacebar or W to throw bowling ball.

Press left | A and right | D to move the bowling ball.

Press R to reset the table.

Press B to reset just the ball.

Creating your Project

Alright, lets jump in and build this game.  First head on over to  Now you either need to create an account or log in to your existing account.


A free account is sufficient for what we are doing here.  Once your account is created and you’ve logged in, click the New button


Select  Blank Project:


Now name your game and hit Create.  Unless you have a premium account, you can’t make private projects.


This will open your project after it’s created.  Now head into the settings.


You can set the resolution, change the name, description, etc...  but what we want to do in this case is enable physics for our project.


Next scroll to the bottom right corner and click the save button.


Now we are ready to fire up the editor.  Scroll back up and locate the Editor button.


Creating your Game

Welcome to the default editor!


Now that we are in the editor, it’s time to start creating our game.  You will notice on the left there is the Hierarchy, this is your games scene graph.


We have no need of the Box or Plane, simply right click each and delete them.

Now let’s get our assets into the game.  In Blender I created the bowling lane and pin textured meshes, then exported them as FBX ready for importing.  Let’s import them for use into our game, along with the required textures.  Locate the Assets window, click the + Icon, select Upload then select your FBX file(s).  Repeat the process with any texture maps you require.


This process will create a .json for each of your 3D models.  It also creates an empty material for both.


Now let’s set the texture for each material.  Simply select the Material, then in the Material tab to your right, scroll down and select Diffuse.  Click ... then select your texture map from the asset pane, like so:


I also have a normal map for the bowling lane, I repeat the above process, but instead of Diffuse I select Normal:


Creating the Bowling Lane

Ok, now that we have our raw assets and our textures linked, lets start creating some game objects.  Simply drag the lane into the scene like so:


You will notice this creates a new entity in our scene graph:


PlayCanvas takes the traditional Entity Component model that is rapidly becoming the norm in the world of game development. 


You will notice that we have a Transform component, which enables us to position our entity in the world.  It also automatically created a Model component for us.  Now we want to add some physics to the game.  Since this is the lane, it wont be moving, so we create it as a static physics object.  To accomplish this we need to add two components, one for collisions that define the shape of our object to the physics engine, the second a RigidBody that defines our physical properties.  Let’s create the Collision shape first.

First click the Add Component button:


Then select Collision


Select Box then set the dimensions to surround your mesh as tightly as possible (note that PlayCanvas is a Y-up game engine):



Now Add Component again, this time selecting Rigid Body.  The default value should be Static, which is what we want.


Static means the object will be part of the physics simulation, but wont be moved by it.  Friction determines how well other objects slide over this surface, while Restitution determines how objects “bounce” off of it.

That’s it!  Our lane is completed.  Now it’s on to creating the bowling pin object.

Creating the Bowling Pins

Now it’s time to create the bowling pin.  Follow the exact same process you did earlier, drag the .json file onto the scene.  Position and scale it appropriately for your scene.


Just like last time, we want to create a collision component for this object.  This time instead of a cube, a cylinder is a better fit.



We also need to create a rigid body to control physics for this entity.  This time we create our entity as Dynamic ( static means stationary, dynamic is fully simulated, while kinematic takes part in the simulation but expects the movement to come directly from code, not the simulation).


Finally we are going to set a tag under the Entity section so we can identify all pins via code.  In the Tags section, enter “Pin” then hit enter to add a tag.  You can add multiple tags to an entity, a quick easy way to create ad-hoc groups of objects as we will see in a moment.


We are simulating 5 pin bowling here, so we need 4 more of them.  In the Hierarchy review, right click the pin and select Duplicate (not copy!).  This creates a copy of the entity and all of it’s components.


Repeat this process 3 more times, then go ahead and position the pins in a V like so.


Obviously if you are a 10 pin fan, other than being a heathen, you simply have to duplicate and position 5 more pins.

This post is getting pretty long so I’ve decided to split it into two parts.  Click here to continue on to part two.


See More Tutorials on!

Month List