How to Implement Infinite Scrolling, Random Stair Generation, and Auto-Falling Bricks in an HTML5 Endless Runner

This article explains the core techniques for building an endless runner game, covering infinite background scrolling, random stair creation with weighted probabilities, and automatic brick dropping, complete with pseudocode, algorithms, and performance considerations.

Aotu Lab
Aotu Lab
Aotu Lab
How to Implement Infinite Scrolling, Random Stair Generation, and Auto-Falling Bricks in an HTML5 Endless Runner

The article introduces a simplified version of the "Finger Adventure" SNS game, an endless runner where the player taps left or right to control a robot jumping across an infinite staircase. The game is divided into three layers: scenery, stairs, and background, each responsible for rendering decorations, stair generation, and user interaction.

1. Implementing Infinite Scrolling

The scenery layer renders leaf decorations on both sides of the game container. When the robot moves, the leaves slide in the opposite direction to create motion. To achieve seamless infinite scrolling, the scene image must be larger than the container and drawn twice: once at the bottom and once offset by the image height. Both copies move down uniformly, and when a copy reaches the reset threshold (the container height), its position is reset to the top.

Draw the scene image twice at different vertical offsets.

Move both images downward by the same offset each frame.

When an image passes the reset line, reposition it to the start.

Pseudocode:

// Set loop threshold
transThreshold = stageHeight;
// Update positions
lastPosY1 = leafCon1.y + transY;
lastPosY2 = leafCon2.y + transY;
if (leafCon1.y >= transThreshold) {
    leafCon1.y = lastPosY2 - leafHeight;
} else {
    leafCon1.y = lastPosY1;
}
if (leafCon2.y >= transThreshold) {
    leafCon2.y = lastPosY1 - leafHeight;
} else {
    leafCon2.y = lastPosY2;
}

2. Random Stair Generation

Stairs consist of safe bricks (forming a continuous path) and obstacle bricks. Safe bricks are placed either left‑up or right‑up relative to the previous brick, represented by 0 (left) or 1 (right). An array of random 0/1 values records this direction.

Obstacle bricks appear opposite the safe direction, at a random distance of 1–3 bricks, encoded as 0{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{none}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 0 To generate the non‑uniform obstacle array, the article describes converting the desired probabilities into a discrete array using the least common multiple (LCM) of the probability denominators, then selecting random indices. While this yields O(1) sampling, the initialization can be memory‑intensive. The Vose’s Alias Method is suggested as an optimized alternative, offering O(n) preprocessing and O(1) sampling with stable performance.

3. Automatic Brick Dropping

A timer removes bricks that have fallen off the screen. Two challenges are addressed: detecting adjacent or same‑Y obstacle bricks and determining when bricks are outside the visible area.

Adjacent obstacles are identified by checking if the obstacle array value at the same index equals 1.

Bricks sharing the same Y coordinate are considered part of the same level and are removed together.

Pseudocode for dropping bricks at the same Y level:

// Record Y of the brick to drop
thisStairY = stair.y;
// Remove the safe brick
stairCon.removeChild(stair);
// Remove obstacle bricks at the same or lower Y
for (i in barrArr) {
    barr = barrArr[i];
    if (barr.y >= thisStairY) {
        barrCon.removeChild(barr);
    }
}

To drop bricks outside the screen, the article checks the length of the safe‑brick array; if it exceeds nine, the excess bricks and their associated obstacles are removed.

// Drop safe brick
stair = stairArr.shift();
stair && _dropStair(stair);
// If more than 9 bricks exist, batch‑drop the oldest ones
if (stairArr.length >= 9) {
    num = stairArr.length - 9;
    arr = stairArr.splice(0, num);
    for (i = 0; i < arr.length; i++) {
        _dropStair(arr[i]);
    }
}

Conclusion

The article selects these three techniques because they are common pain points in game development: looping backgrounds, generating objects with custom probability distributions, and managing off‑screen resources. Understanding both visual and logical layers helps simplify solutions and improve performance in HTML5 game projects. References: Keith Schwarz’s "Darts, Dice, and Coins" and a GitHub implementation of Vose’s Alias Method.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

HTML5collision detectionrandom generationalias methodinfinite scrolling
Aotu Lab
Written by

Aotu Lab

Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.