Moving Background Fundamentals

JavaScript items you must know before beginning this project.

Canvas

Your drawing board

A canvas is an HTML element that acts as a drawing board for your website. Most projects need a canvas in order for the items coded in it to actually appear. Otherwise, you'll just have an empty page.

  • Draw shapes, text, images, and animations
  • Use a canvas in JavaScript by using the id that you've given it
const canvasWidth = window.innerWidth;
const canvasHeight = window.innerHeight;

canvas.width = canvasWidth;
canvas.height = canvasHeight;
canvas.style.width = `${canvasWidth}px`;
canvas.style.height = `${canvasHeight}px`;

CSS

Cascading Style Sheets

CSS is a languagsed used to style HTML. So, if your website is looking a little ugly, it's probably because you aren't using enough CSS!

  • Making cute buttons
  • Changing the font of your webpages
  • Having colored text
/* all normal text */
body {
font-family: 'Quicksand', sans-serif !important;
font-size: 1em;
color: white;
}

Constant Variables

Const

Constant Variables (commonly just called a 'constant') are variables whose value cannot be changed once it's assigned.

const spriteWidth = spriteImg.naturalWidth / 2;
const spriteHeight = spriteImg.naturalHeight / 2;
const spriteX = (canvasWidth - spriteWidth) / 2;
const spriteY = (canvasHeight - spriteHeight) / 2;
const spriteObj = new GameObject(spriteImg, spriteWidth, spriteHeight, spriteX, spriteY);

JavaScript Classes

Class

A class in JavaScript is like a blueprint for creating objects. Instead of writing object structures repeatedly, you can define a class once and then create multiple objects (called instances) from it.

class GameObject {
  constructor(image, width, height, x = 0, y = 0, speedRatio = 0) {
    this.image = image;
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.speedRatio = speedRatio;
    this.speed = gameSpeed * this.speedRatio;

Moving Background

A lot of games, mostly platformer 2D games use moving backgrounds. For example, when Mario runs to save the princess, the background moves so it seems like he’s actually going somewhere.

There are a lot of JavaScript components that go into the code to have a moving background. We’re going to go through them.

Canvas


In order for anything to show up on your screen in the first place, we have to create a canvas for everything to be drawn on.

We’re going to need to declare a constant variable using the keyword const

const canvas = document.getElementById("world");
// document.getElementById("world") finds the <canvas id="world"> element in the DOM.

const ctx = canvas.getContext('2d');
// every canvas has a drawing context. for example, getContext('2d') returns the 2D drawing API (methods like drawImage, fillRect, clearRect).
// canvas is the DOM element; ctx is what draws pixels

Sizing the Canvas


Now, we need to size the canvas to the window. Again, this is so the things being drawn isn’t too small or too big for your window screen.

const canvasWidth = window.innerWidth;
const canvasHeight = window.innerHeight;

canvas.width = canvasWidth;
canvas.height = canvasHeight;
canvas.style.width = `${canvasWidth}px`;
canvas.style.height = `${canvasHeight}px`;


canvas.width / canvas.height set the drawing buffer size (pixel resolution of the canvas).

canvas.style.width / canvas.style.height set the CSS size (how big it appears on screen). They set both equal so the drawing area matches the visible size.

There are other variables that need to be constant in order for the moving background to work, two are very important because they are the main items that make the moving background a moving background.


const background //self explanatory 
const sprite // whatever you want to place in the middle of the screen 


Now, you can see that those lines are missing some details. Based on the example that was given, try to set both the background and sprite to images of you choice.

Game Objects
In our game, everything that shows up on the screen (like the background or the character sprite) can be thought of as a game object. Instead of writing separate code for each image, we create a class that acts like a blueprint.

class GameObject {
  constructor(image, width, height, x = 0, y = 0, speedRatio = 0) {
    this.image = image;       // what picture to draw
    this.width = width;       // how wide to draw it
    this.height = height;     // how tall to draw it
    this.x = x;               // where it is horizontally
    this.y = y;               // where it is vertically
    this.speedRatio = speedRatio;
    this.speed = gameSpeed * this.speedRatio; // how fast it moves
  }
  update() {
    // gets filled in by subclasses (like Background)
  }
  draw(ctx) {
    ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
  }
}

Instead of hardcoding the background or sprite separately, we can now make them instances of this GameObject class.

Background Object
Our background is special: it has to move sideways forever to look like we’re running. To make it seamless, we draw two copies of the background image side-by-side. As one scrolls off the screen, the other one takes its place.

class Background extends GameObject {
  update() {
    this.x = (this.x - this.speed) % this.width;
  }
  draw(ctx) {
    ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
    ctx.drawImage(this.image, this.x + this.width, this.y, this.width, this.height);
  }
}

update() moves the background a little bit every frame.

The % this.width (modulo) makes sure it “wraps around” so it never disappears.

draw() paints two backgrounds so there’s no empty gap.

The Game Loop (Animation)
The most important piece of a game is the loop that keeps running forever. This is where things get updated and redrawn, frame after frame.

function animate() {
  ctx.clearRect(0, 0, canvasWidth, canvasHeight); // clear the canvas
  backgroundObj.update();  // move the background
  backgroundObj.draw(ctx); // redraw background
  spriteObj.draw(ctx);     // draw the player sprite in the center
  requestAnimationFrame(animate); // call animate() again
}
animate();

clearRect wipes the screen so old frames don’t overlap.

update changes object positions.

draw puts the new images onto the canvas.

requestAnimationFrame tells the browser: “do this again on the next frame.”

That’s what makes the background look alive — it’s being redrawn 60 times per second!