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