RBS CODE ยท ARRAYS + REAL GAME OBJECTS

One Object โ†’ Many Objects

Arrays are how a game remembers many enemies, platforms, bullets, coins, walls or anything else. These examples show the full bridge from an array to real HTML elements on the screen.

The pattern

1. Make an array
let enemies = [];
2. Create + remember
addSprite(
    enemies,
    game,
    "๐Ÿ‘พ",
    50,
    0,
    40
);
3. Update all
moveAll(
    enemies,
    0,
    4
);
Important: when an enemy or bullet is gone, remove it from BOTH the webpage and the array. The library functions below do both.
GAME 1

Enemy Wave

Create new enemies during the game, move the whole array, detect collisions with any enemy, and clean up enemies that leave the screen.

PLAY FULL GAME

Live game

Your main JavaScript

This is the part to read, copy, change and learn first.

let enemies = [];
let score = 0;

moveWithKeys("player", 14, "game");

function makeEnemy() {
    if (RBS_GAME_ENDED) return;

    let enemy = addSprite(enemies, game, "๐Ÿ‘พ", 0, -48, 40);
    randomX(enemy, game);
}

function gameLoop() {
    if (RBS_GAME_ENDED) return;

    moveAll(enemies, 0, 4);

    let escaped = removeOffscreen(enemies, game);
    score = score + escaped;

    enemyCount.innerText = enemies.length;
    scoreText.innerText = score;

    if (touchingAny(player, enemies)) {
        gameOver(message, "GAME OVER ยท You dodged " + score);
        player.innerText = "๐Ÿ’ฅ";
    }
}

makeEnemy();
every(700, makeEnemy);
every(25, gameLoop);
COPY THE COMPLETE WORKING index.html

Paste this into a new index.html. Keep rbs-game-library.js beside it.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Enemy Wave ยท Arrays</title>
<style>
*{box-sizing:border-box}
body{margin:0;font-family:Arial,sans-serif;background:#eef2f7;color:#172033}
.wrap{width:760px;max-width:calc(100% - 24px);margin:22px auto}
h1{margin:0 0 8px}
.help{margin:0 0 12px;color:#536174}
.hud{background:#fff;padding:11px 14px;border-radius:12px 12px 0 0;display:flex;justify-content:space-between;font-weight:800}
.message{background:#172033;color:#fff;padding:9px 14px;text-align:center;font-weight:800}
.game{position:relative;width:100%;height:430px;overflow:hidden;border:4px solid #172033;background:linear-gradient(#dff4ff,#dff7df)}
.sprite{position:absolute;user-select:none;text-align:center}
button{margin-top:10px;padding:9px 14px;border:0;border-radius:9px;background:#4f46e5;color:white;font-weight:800;cursor:pointer}

#player{font-size:42px;width:48px;height:48px;line-height:48px}
</style>
</head>
<body>
<div class="wrap">
<h1>Enemy Wave</h1>
<p class="help">Arrow keys move. Survive the falling enemies. Watch the array grow and shrink.</p>
<div class="hud"><span>Enemies: <span id="enemyCount">0</span></span><span>Dodged: <span id="scoreText">0</span></span></div>
<div id="message" class="message">GO!</div>
<div id="game" class="game">
  <div id="player" class="sprite" style="left:350px;top:360px">๐Ÿš€</div>
</div>
<button onclick="restartGame()">RESTART</button>
</div>
<script src="rbs-game-library.js"></script>
<script>
let enemies = [];
let score = 0;

moveWithKeys("player", 14, "game");

function makeEnemy() {
    if (RBS_GAME_ENDED) return;

    let enemy = addSprite(enemies, game, "๐Ÿ‘พ", 0, -48, 40);
    randomX(enemy, game);
}

function gameLoop() {
    if (RBS_GAME_ENDED) return;

    moveAll(enemies, 0, 4);

    let escaped = removeOffscreen(enemies, game);
    score = score + escaped;

    enemyCount.innerText = enemies.length;
    scoreText.innerText = score;

    if (touchingAny(player, enemies)) {
        gameOver(message, "GAME OVER ยท You dodged " + score);
        player.innerText = "๐Ÿ’ฅ";
    }
}

makeEnemy();
every(700, makeEnemy);
every(25, gameLoop);
</script>
</body>
</html>
GAME 2

Platform Array

Turn every .platform element into one array. The same gravity/landing code can then work with every platform instead of one platform at a time.

PLAY FULL GAME

Live game

Your main JavaScript

This is the part to read, copy, change and learn first.

let platforms = getAll(".platform");
let ySpeed = 0;

platformCount.innerText = platforms.length;

startKeyTracking();

document.addEventListener("keydown", function(event) {
    if ((event.key === " " || event.key === "ArrowUp") && standingOnAny(player, platforms)) {
        ySpeed = -11;
    }
});

function gameLoop() {
    if (RBS_GAME_ENDED) return;

    if (keyIsDown("ArrowLeft")) move(player, -5, 0);
    if (keyIsDown("ArrowRight")) move(player, 5, 0);

    ySpeed = applyGravity(player, ySpeed, 0.55);
    ySpeed = landOnPlatforms(player, ySpeed, platforms);

    if (player.offsetLeft < 0) player.style.left = "0px";
    if (player.offsetLeft + player.offsetWidth > game.clientWidth) {
        player.style.left = (game.clientWidth - player.offsetWidth) + "px";
    }

    if (player.offsetTop > game.clientHeight) {
        place(player, 45, 342);
        ySpeed = 0;
    }

    if (touching(player, goal)) {
        gameOver(message, "YOU WIN!");
        player.innerText = "๐Ÿ†";
    }
}

every(20, gameLoop);
COPY THE COMPLETE WORKING index.html

Paste this into a new index.html. Keep rbs-game-library.js beside it.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Platform Array ยท Arrays</title>
<style>
*{box-sizing:border-box}
body{margin:0;font-family:Arial,sans-serif;background:#eef2f7;color:#172033}
.wrap{width:760px;max-width:calc(100% - 24px);margin:22px auto}
h1{margin:0 0 8px}
.help{margin:0 0 12px;color:#536174}
.hud{background:#fff;padding:11px 14px;border-radius:12px 12px 0 0;display:flex;justify-content:space-between;font-weight:800}
.message{background:#172033;color:#fff;padding:9px 14px;text-align:center;font-weight:800}
.game{position:relative;width:100%;height:430px;overflow:hidden;border:4px solid #172033;background:linear-gradient(#dff4ff,#dff7df)}
.sprite{position:absolute;user-select:none;text-align:center}
button{margin-top:10px;padding:9px 14px;border:0;border-radius:9px;background:#4f46e5;color:white;font-weight:800;cursor:pointer}

.game{background:linear-gradient(#dff4ff,#fff6cf)}
#player{font-size:38px;width:42px;height:42px;line-height:42px}
.platform{position:absolute;height:18px;background:#475569;border-radius:9px}
.goal{position:absolute;font-size:42px}
</style>
</head>
<body>
<div class="wrap">
<h1>Platform Array</h1>
<p class="help">Left/right arrows move. Space or โ†‘ jumps. Every platform is stored in one array.</p>
<div class="hud"><span>Platforms: <span id="platformCount"></span></span><span>Goal: reach the flag</span></div>
<div id="message" class="message">GO!</div>
<div id="game" class="game">
  <div id="player" class="sprite" style="left:45px;top:342px">๐Ÿƒ</div>

  <div class="platform" style="left:0;top:390px;width:180px"></div>
  <div class="platform" style="left:215px;top:330px;width:140px"></div>
  <div class="platform" style="left:390px;top:270px;width:145px"></div>
  <div class="platform" style="left:560px;top:205px;width:150px"></div>
  <div class="platform" style="left:390px;top:135px;width:125px"></div>
  <div class="platform" style="left:195px;top:75px;width:145px"></div>

  <div id="goal" class="goal" style="left:245px;top:25px">๐Ÿšฉ</div>
</div>
<button onclick="restartGame()">RESTART</button>
</div>
<script src="rbs-game-library.js"></script>
<script>
let platforms = getAll(".platform");
let ySpeed = 0;

platformCount.innerText = platforms.length;

startKeyTracking();

document.addEventListener("keydown", function(event) {
    if ((event.key === " " || event.key === "ArrowUp") && standingOnAny(player, platforms)) {
        ySpeed = -11;
    }
});

function gameLoop() {
    if (RBS_GAME_ENDED) return;

    if (keyIsDown("ArrowLeft")) move(player, -5, 0);
    if (keyIsDown("ArrowRight")) move(player, 5, 0);

    ySpeed = applyGravity(player, ySpeed, 0.55);
    ySpeed = landOnPlatforms(player, ySpeed, platforms);

    if (player.offsetLeft < 0) player.style.left = "0px";
    if (player.offsetLeft + player.offsetWidth > game.clientWidth) {
        player.style.left = (game.clientWidth - player.offsetWidth) + "px";
    }

    if (player.offsetTop > game.clientHeight) {
        place(player, 45, 342);
        ySpeed = 0;
    }

    if (touching(player, goal)) {
        gameOver(message, "YOU WIN!");
        player.innerText = "๐Ÿ†";
    }
}

every(20, gameLoop);
</script>
</body>
</html>
GAME 3

Multi Bullet Blaster

Space creates real bullet elements. Bullets and enemies live in arrays. When they collide, both the DOM elements and array entries are deleted.

PLAY FULL GAME

Live game

Your main JavaScript

This is the part to read, copy, change and learn first.

let bullets = [];
let enemies = [];
let score = 0;
let canShoot = true;

startKeyTracking();

function makeWave() {
    for (let i = 0; i < 8; i++) {
        let x = 55 + i * 82;
        let enemy = addSprite(enemies, game, "๐Ÿ‘พ", x, 35, 34);
        enemy.dataset.direction = (i % 2 === 0) ? "1" : "-1";
    }
}

document.addEventListener("keydown", function(event) {
    if (event.key === " " && canShoot && !RBS_GAME_ENDED) {
        makeBullet(player, game, bullets, "๐Ÿ”ฅ", 18);
        canShoot = false;

        after(170, function() {
            canShoot = true;
        });
    }
});

function gameLoop() {
    if (RBS_GAME_ENDED) return;

    if (keyIsDown("ArrowLeft")) move(player, -6, 0);
    if (keyIsDown("ArrowRight")) move(player, 6, 0);
    keepInside(player, game);

    moveAll(bullets, 0, -8);

    for (let i = 0; i < enemies.length; i++) {
        let dx = Number(enemies[i].dataset.direction) * 1.2;
        move(enemies[i], dx, 0);

        if (atEdge(enemies[i], game, "left") || atEdge(enemies[i], game, "right")) {
            enemies[i].dataset.direction = String(-Number(enemies[i].dataset.direction));
            move(enemies[i], 0, 12);
        }
    }

    removeOffscreen(bullets, game);

    let hits = removeCollisions(bullets, enemies);
    score = score + hits;

    bulletCount.innerText = bullets.length;
    enemyCount.innerText = enemies.length;
    scoreText.innerText = score;

    if (enemies.length === 0) {
        gameOver(message, "YOU WIN! " + score + " HITS");
        player.innerText = "๐Ÿ†";
    }
}

makeWave();
every(20, gameLoop);
COPY THE COMPLETE WORKING index.html

Paste this into a new index.html. Keep rbs-game-library.js beside it.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Multi Bullet Blaster ยท Arrays</title>
<style>
*{box-sizing:border-box}
body{margin:0;font-family:Arial,sans-serif;background:#eef2f7;color:#172033}
.wrap{width:760px;max-width:calc(100% - 24px);margin:22px auto}
h1{margin:0 0 8px}
.help{margin:0 0 12px;color:#536174}
.hud{background:#fff;padding:11px 14px;border-radius:12px 12px 0 0;display:flex;justify-content:space-between;font-weight:800}
.message{background:#172033;color:#fff;padding:9px 14px;text-align:center;font-weight:800}
.game{position:relative;width:100%;height:430px;overflow:hidden;border:4px solid #172033;background:linear-gradient(#dff4ff,#dff7df)}
.sprite{position:absolute;user-select:none;text-align:center}
button{margin-top:10px;padding:9px 14px;border:0;border-radius:9px;background:#4f46e5;color:white;font-weight:800;cursor:pointer}

.game{background:radial-gradient(circle at 50% 120%,#21305b,#070b18 68%);color:white}
#player{font-size:42px;width:46px;height:46px;line-height:46px}
</style>
</head>
<body>
<div class="wrap">
<h1>Multi Bullet Blaster</h1>
<p class="help">โ† โ†’ move. Space shoots. Bullets and enemies are real elements stored in arrays.</p>
<div class="hud"><span>Bullets: <span id="bulletCount">0</span></span><span>Enemies: <span id="enemyCount">0</span></span><span>Score: <span id="scoreText">0</span></span></div>
<div id="message" class="message">DESTROY THE WAVE</div>
<div id="game" class="game">
  <div id="player" class="sprite" style="left:350px;top:365px">๐Ÿš€</div>
</div>
<button onclick="restartGame()">RESTART</button>
</div>
<script src="rbs-game-library.js"></script>
<script>
let bullets = [];
let enemies = [];
let score = 0;
let canShoot = true;

startKeyTracking();

function makeWave() {
    for (let i = 0; i < 8; i++) {
        let x = 55 + i * 82;
        let enemy = addSprite(enemies, game, "๐Ÿ‘พ", x, 35, 34);
        enemy.dataset.direction = (i % 2 === 0) ? "1" : "-1";
    }
}

document.addEventListener("keydown", function(event) {
    if (event.key === " " && canShoot && !RBS_GAME_ENDED) {
        makeBullet(player, game, bullets, "๐Ÿ”ฅ", 18);
        canShoot = false;

        after(170, function() {
            canShoot = true;
        });
    }
});

function gameLoop() {
    if (RBS_GAME_ENDED) return;

    if (keyIsDown("ArrowLeft")) move(player, -6, 0);
    if (keyIsDown("ArrowRight")) move(player, 6, 0);
    keepInside(player, game);

    moveAll(bullets, 0, -8);

    for (let i = 0; i < enemies.length; i++) {
        let dx = Number(enemies[i].dataset.direction) * 1.2;
        move(enemies[i], dx, 0);

        if (atEdge(enemies[i], game, "left") || atEdge(enemies[i], game, "right")) {
            enemies[i].dataset.direction = String(-Number(enemies[i].dataset.direction));
            move(enemies[i], 0, 12);
        }
    }

    removeOffscreen(bullets, game);

    let hits = removeCollisions(bullets, enemies);
    score = score + hits;

    bulletCount.innerText = bullets.length;
    enemyCount.innerText = enemies.length;
    scoreText.innerText = score;

    if (enemies.length === 0) {
        gameOver(message, "YOU WIN! " + score + " HITS");
        player.innerText = "๐Ÿ†";
    }
}

makeWave();
every(20, gameLoop);
</script>
</body>
</html>

Cleanup: remove BOTH

Not enough: sprite.remove() only removes the HTML. Not enough: array.splice() only removes the array entry. A real game should do both.

Use this

function removeAt(list, index) {
    let sprite = list[index];

    sprite.remove();
    list.splice(index, 1);
}

Why loop backwards? Removing an array item makes later items slide left. A backwards loop avoids accidentally skipping the next object.

The most useful array game functions

getAll()

Get many HTML elements into one array.

let platforms =
    getAll(".platform");
addSprite()

Create an element and automatically push it into an array.

addSprite(
    enemies,
    game,
    "๐Ÿ‘พ",
    50, 0, 40
);
touchingAny()

Check one thing against every item in an array.

if (
    touchingAny(
        player,
        enemies
    )
) {
    gameOver(message);
}
removeOffscreen()

Remove dead/outside DOM elements AND array entries.

removeOffscreen(
    bullets,
    game
);
removeCollisions()

Remove colliding pairs from two arrays.

score +=
    removeCollisions(
        bullets,
        enemies
    );
clearSprites()

Delete every sprite in an array.

clearSprites(
    enemies
);