Parallax

Parallax demonstrates how to tile a dynamic background and give the illusion on depth to a 2d scene. It uses the art work of the very talented Liz Molnar (link opens in a new page). Press A and D to scroll the screen.

Code

// MaxCanvas Project
// 10-Parallax.JS File (April 2019)
//
// Required to drag MC.js into Intellisense
// thanks to https://visualstudiomagazine.com/blogs/tool-tracker/2018/07/use-javascript-code.aspx (Dec 2018)
/// <reference path="MC.js" />

window.onload = (function() {

    // AQUIRE HTML DOM CANVAS REFERENCE
    var c=document.getElementById("canvas");

    //////////////////////////
    // INITIALISE MC Engine //
    //////////////////////////
    MC.init(c);

    ///////////////////////////
    // END OF Initialisation //
    ///////////////////////////
    //-----------------------------------------------------------------------------
    //////////////////////////
    // VARIABLE DECLARATION //
    //////////////////////////

    var BG = new MC.SpriteBin();
    var pictures = [];
    var ImageNames = ["Images/11_background.png",
        "Images/10_distant_clouds.png",
        "Images/09_distant_clouds1.png",
        "Images/08_clouds.png",
        "Images/07_huge_clouds.png",
        "Images/06_hill2.png",
        "Images/05_hill1.png",
        "Images/04_bushes.png",
        "Images/03_distant_trees.png",
        "Images/02_trees and bushes.png",
        "Images/01_ground.png"];

    for (var i = 0, len = ImageNames.length; i < len; i++) {
        pictures[i] = new MC.Picture(ImageNames[i]);

        BG.push(getImageSprite(i));

        var sec = getImageSprite(i);
        sec.dev.update = function () { };

        BG.push(sec);
    }

    function getImageSprite(id) {
     var ret = new MC.Sprite({
                type: "pict",
                picture: pictures[id],
                scale: 0.45
            });
            ret.dev.mod = id;
            ret.dev.update = function () {
                if (MC.keys.a.down) {
                    ret.vel.set(-50 * ret.dev.mod, 0);
                }
                else if (MC.keys.d.down) {
                    ret.vel.set(50 * ret.dev.mod, 0);
                }
                else if (!MC.keys.a.down && !MC.keys.d.down) {
                    ret.vel.set(0, 0);
                }
            };
            return ret;
    }

    function updateSecond() {
        for (var i = 0, len = BG.bin.length; i < len; i = i +2) {
            var p = BG.bin[i];
            var width = p.picture.width * p.scale;
            if (p.pos.x < 0) p.moveBy(new MC.Point(width, 0));
            else if (p.pos.x > MC.canvas.width) p.moveBy(new MC.Point(-width, 0));

            var p1 = p.pos.clone();
            if (p1.x > MC.canvas.midX) width *= -1;
            p1.add(width, 0);
            BG.bin[i+1].moveTo(p1);
        }
    }


//////////////////////////
// END OF declarations  //
//////////////////////////
//-----------------------------------------------------------------------------
//////////////////////////
//      GAME LOOP       //
//////////////////////////

// first call, request subsequently made within
gameLoop();

function gameLoop() {
    // ESSENTIAL MAINTAINANCE
    requestAnimationFrame(gameLoop);
    MC.game.update();                   
    
    // NON-PHYSICS UPDATES
    BG.update();
    updateSecond();

    // RENDER
    // Stage 1.  Clear the canvas

    // Stage 2.  Render Sprites
     BG.render();

    // Stage 3.  Render GUI
    MC.draw.text("[a] left - right [d]", new MC.Point(20, 25));

}

}); // EoF