Build a doodle jump html5 web game with kaboom.js

What we create

This tutorial teaches you how to build a very simple doodle jump clone. You control a player that can jump on platforms to get higher in the air. You have to avoid falling to the bottom of the screen.

Check out the finished game here: game demo

You can find the final source code here: Code at gitHub

What is kaboom.js

Kaboom.js is a framework to create html5 games with javascript. It's kept very simple what makes it easy to get started. You can learn more about kaboom.js in general at https://kaboomjs.com.

Setting up the project

Getting started with kaboom.js is easy. Just create a blank html file and call it whatever you like. Add the following bare html structure:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="https://kaboomjs.com/lib/0.5.1/kaboom.js"></script>
    <script type="module">
      <!-- Our game code will go here -->
    </script>
  </body>
</html>

It's just a regular html file that loads the kaboom engine. I already added another script tag that will contain our game code later on.

Create two scenes

you define a scene with the function. We need two scenes one for the main menu and one for the actual game.

scene("menu", (args) => {
  //the code for our scene goes here
});

scene("game", () => {
  //the code for our scene goes here
});

start("game");

the function actually starts our game and runs the scene we provided as an argument (in our case 'game').

Create the player

Let's start with our player first. You add something to scene with the help of the function. It takes a list of components as argument. An object in kaboomjs is made up of several components. The code for adding scene obejcts and their logic belongs into the function that defines our scene.

var player = add([
  rect(50, 50),
  origin("center"),
  color(rgb(1, 1, 1)),
  pos(width() / 2, height() / 2),
  body(),
]);

We added the following components to our player:

  • rect: That's the visual part of out player. A 50x50 px square.
  • origin: We set the origin of our player rect to its center.
  • color: We set the color of our player to white.
  • pos: The position of out player. returns the width of the game canvas. And returns the height of the game canvas. So we place our player in the middle of the screen.
  • body: Body is a component that attaches gravity and the ability to jump to our player. Attaching this component makes it fall (when not on a solid object) and gives it the ability to jump by calling the method on it.

When you open your game file in a browser now, you should see a square in the middle of the game canvas that immediately starts to fall down.

Player movement

We want the player to move left and right by pressing th arrow keys. We do this by adding listeners for the left and right arrow keys. Add the following code directly under the code that creates the player:

keyDown("left", () => {
  player.move(-100, 0);
});
keyDown("right", () => {
  player.move(100, 0);
});

Whenever the left or right key is down, the corresponding tuction provided as the second argument to the function gets executed. We can call the method on the player, because we attached the component to it. Calling will move the player in x and y direction taking in consideration the current framerate.

We want the player to appear on the other side of the screen, if it leaves it on one side. Add the following code right under the movement code:

action(() => {
  if (player.pos.x > width() + player.width / 2) {
    player.pos.x = -player.width / 2;
  }
  if (player.pos.x < -player.width / 2) {
    player.pos.x = width() + player.width / 2;
  }
});

A function that's provided as an argument to the function gets called every frame of the game (basically all the time). We check if the players x position is greater than the screenwidth (player left the screen on the right) and set it straigth to the left edge of the screen. Also when the player left the screen on the left side, we set its position straight ton the right side of the screen.

If you open your game file in a browser, you should have a square that starts to fall down but can move left and right.

Create platforms

Creating the platforms and the ability for the player to jump on them is the hardest part of this tutorial. But we will tackle it step by step.

Let's define a variable needed for the platform creation first:

var highestPlatformY = height();

In this variable we store the y position of the highest plaform in the game. We will need it to determine the possible y positions when we create a new platform.

We will define a separate function that's responsible for creating a single platform. We do that so we don't have to repeat the code over and over again.

function createPlatform() {
  let newPlatform = add([
    rect(120, 24),
    origin("center"),
    color(rgb(1, 1, 1)),
    pos(
      rand(60, width() - 60),
      rand(highestPlatformY - 40, highestPlatformY - 200)
    ),
    "platform",
  ]);
  if (newPlatform.pos.y < highestPlatformY) {
    highestPlatformY = newPlatform.pos.y;
  }
}

When this function gets called, a new rectangle with a width of 120px and a height of 24px will get added to the scene. It's pretty much the same as for the player. The only difference is the 'platform' tag that we asigned (we will use this to change properties of all obejcts in the game with the tag 'platform' at once later), and the position. The x value of the position is just random value between the left and the right end of the screen. The y value is a random value that is at least 40px above the y position of the highest platform that's currently in the game and at most 200px above the highest platform in the game. And finally, if the new platform is above the current highest platform (it always should), we reasign the variable with the y position of the new platform.

So whenever we create a new platform, it will be above all other platforms. And that makes totally sense, because the player has to move upwards by jumping on platforms.

To create the first 10 platforms that are already on the screen when the game starts, we call the function in a loop.

//create first 10 platforms
for (let i = 0; i < 10; i++) {
  createPlatform();
}

The next thing we're going to add is the destruction of platforms that are out of screen. Whenever a platform leaves the screen at the bootom, we destroy it and create a new platform with the hekp of our function.

action("platform", (platform) => {
  if (platform.pos.y > player.pos.y + height() / 2) {
    destroy(platform);
    createPlatform();
  }
});

Do you remember the function we used to keep the player in bounds, that was running every frame? Kabbomjs also let's us register actions for certain tags. Here we registered a function that runs for every object with the 'platform' tag that we added to the scene. Every platform gets passed as a parameter to the function. We check if the y position of a platform is larger than the player position plus the half of the screen (bottom edge). If yes, we destroy it and create a new platform.

Player jumping on platforms

We want the player to automatically jump when it touches a platform. But only if the player is currently falling. It can jump through platforms from the bottom. To achieve this, we need a variable to store the players y position of the last frame. We can compare it with the current y position and determine if it's currently falling (when the previous y position is greater than the current, th eplayer falls). So lets's define a variable to store the players y position:

var lastPosY = player.pos.y;

We want to update this variable every frame. So we add another action that updates the variable:

action(() => {
  lastPosY = player.pos.y;
});

This action needs to be at the end of your scene definition function, as we want to update the position after everything else. Otherwise we would compare the current y player position with itself every frame.

Now that we have the y position of the plaer in the last frame, let's use it to check if the polayer is falling and touching a platform:

player.collides("platform", (p) => {
  if (player.pos.y > lastPosY) {
    player.jump(700);
  }
});

Every kaboom object with a rect (or sprite) component (more detailed: These components add another component called that provides this function) has a collides method. It takes a tag as its first argument. The second argument is a function that gets called whenever the player collides with an object with tag platform. When a collision occurs, we check if the current player y position is greater than the y position in the last frame (falling). If this is also true, the player needs to jump. As we attached the component to our player, it has a method called . We call it with a jump strength of 700. Changing that value, will change how high the player jumps.

If you open your game file in a browser now, you player should jump when it touches a platform from above.

Keep the player in the middle of the screen

We don't want the player to leave the screen. So we need to focus the camera on the player. Add the following code snippet to the end of your scene definition function:

action(() => {
  camPos({ x: width() / 2, y: player.pos.y });
});

The function focuses the camera on the given point. We use the center of the screen on the horizontal axis and the players y position on the vertical axis. That way we always habe the player in the middle of the screen.

Next

In the next part of the tutorial we will add a score system and a main menu to the game. If you don't want to miss it, sign up to my newsletter below and I will send you a short email when the second part is available.

Imprint© MiniGameEngine 2021 Template by TailwindToolbox.com