Making a game in JavaScript Part 7 : The Background

For the sake of learning, fun, simplicity, and getting something playable on the screen as soon as possible, we are .. going for a scrolling background, and randomised level platform patterns.

We have the ninja running and idle animations, but now it is still sitting on a blank white canvas with no background. Let’s change this. We can add the scrolling background that scrolls in time with the directional movement of the player, or to be clear the player will appear to be running but in fact will be standing in place, with the background moving behind the player.

We could go for a full camera and definitive level loading set up – but that is not what I will be covering for this project. In fact, this project does not demonstrate the way that this could be done with best practice, but rather this highlights something else. This is an introductory project, designed in a way that cuts some corners to allow us to speed up the process and get something playable on the screen. In addition to that, we want to leave some things that can be added, or edited, after the completion of the project demonstration. A good place to start extending beyond this documented project will be the camera and level set up. For the sake of learning, fun, simplicity, and getting something playable on the screen as soon as possible, we are instead going for a scrolling background, and randomised level platform patterns. Beyond the completion of these articles, it might make an interesting platform to add a follow camera, fixed levels, and perhaps even some other additional game mechanics to make the game more complete.

For the scrolling background, we first need the background image files, which can be downloaded here:

( Broken Link TBU) Winter TileSet – including the scrolling background image files

In the \GameJS\images\ folder, add the downloaded tileset so that the folder structure is made up of
\GameJS\images\TileSets\Winter\

The background image files should be located here: \GameJS\images\TileSets\Winter\BG\BG.png

When the TileSets folder has the Winter tileset added to it, we can go back to the \GameJS\js\ folder and add a script file called ‘background.js’.

Add this code to background.js

export class ScrollingBackground
{|
constructor()
{
this.backgroundImages = [];
this.backgroundImagePath = ”;
this.scrollingSpeed = 5.0;
this.backgroundIndex = 0;
this.backgroundCount = 2;
this.backgroundImageWidth = 1800;
this.backgroundImageHeight = 893;
this.canvasWidth = 1280;
this.canvasHeight = 680;

this.backgroundAXPosition = -200.0;
this.backgroundAYPosition = 0.0;

this.backgroundBuffer = 200.0;

this.onScreenImages = [];

var ratio = this.canvasHeight / this.backgroundImageHeight;

this.xSizeRatio = ratio this.backgroundImageWidth;
this.ySizeRatio = ratio
this.backgroundImageHeight;

this.backgroundBXPosition = (1800.0 * ratio) – this.backgroundBuffer;
this.backgroundBYPosition = 0.0;

}

initialise()
{
this.backgroundImagePath = ‘../images/TileSets/Winter/BG/BG.png’;
this.backgroundImages[0] = new Image();
this.backgroundImages[0].src = this.backgroundImagePath;
this.backgroundImages[1] = new Image();
this.backgroundImages[1].src = this.backgroundImagePath;
}

update(scrollingXVelocity)
{

if(scrollingXVelocity !== 0.0)
{
this.backgroundAXPosition += (scrollingXVelocity this.scrollingSpeed);
this.backgroundBXPosition += (scrollingXVelocity this.scrollingSpeed);
}

if(this.backgroundAXPosition > this.canvasWidth * 0.5)
{
var temp = this.backgroundAXPosition;
this.backgroundAXPosition = this.backgroundBXPosition;
this.backgroundBXPosition = temp;
this.backgroundBXPosition = this.backgroundAXPosition – this.xSizeRatio + 0.95;
}
else if((this.backgroundBXPosition > 0.0) && (this.backgroundBXPosition < this.canvasWidth * 0.5))
{
var temp = this.backgroundAXPosition;
this.backgroundAXPosition = this.backgroundBXPosition;
this.backgroundBXPosition = temp;
this.backgroundBXPosition = this.backgroundAXPosition + this.xSizeRatio – 0.95;
}

if(this.backgroundAXPosition < 10)
{
this.backgroundBXPosition = this.backgroundAXPosition + this.xSizeRatio – 0.95;
return;
}
else if(this.backgroundAXPosition > 10.0)
{
this.backgroundBXPosition = this.backgroundAXPosition – this.xSizeRatio + 0.95;
}

}

render(context)
{
context.drawImage(this.backgroundImages[0], 0, 0, this.backgroundImageWidth, this.backgroundImageHeight, this.backgroundBXPosition, this.backgroundBYPosition, this.xSizeRatio, this.ySizeRatio);

context.drawImage(this.backgroundImages[1], 0, 0, this.backgroundImageWidth, this.backgroundImageHeight, this.backgroundAXPosition, this.backgroundAYPosition, this.xSizeRatio, this.ySizeRatio);

}

}

export default ScrollingBackground;

And in the playablecontext.js script, add the following import to the top of the file:

import { ScrollingBackground } from ‘./background.js’;

And in the constructor of the PlayableContext object, add the following initialisation for the background scrolling:


this.background = new ScrollingBackground();

And in the initialise function, add this to the end of the initialise code:


// Initialise the scrolling background
this.background.initialise();

And in the end of the update() function, add the call to the background object update function, including the player speed in the arguments for the function call:

var backgroundSpeed = (-15.0 * this.player.xVelocity);
this.background.update(backgroundSpeed);

We multiply the player velocity by a negative number because we want the background to move in the opposite direction to what the player is ‘running’ or facing, and we increase it by the factor of 15 because we want the ninja character to appear to be running very fast, like a ninja!

In the render function, we want to now render the background to the screen. We need to consider the order that the canvas will be drawn on. If we draw the player, then draw the background, the player will disappear behind the background. We want to draw the background first, then draw the player over the background. To do this, we will add the call to draw the background right after the existing ‘clear screen’ call in the render function. This way, the screen will be cleared, the background will be drawn, then the player. Like this:

this.context.clearRect(0,0,1280,600);

this.background.render(this.context);

The background will now be visible and if you press and hold either ‘a’ or ‘d’, the player should run and the background should scroll according to which direction the player is ‘running’, which is moving in the opposite direction to the way it is facing.

You can see the screenshots below to see how this should look, and I have also included the screenshots demonstrating how the http server needs to be running in the background to ensure that the page and javascript modules can be loaded correctly.

Brent McEwan