Coding Academy home

Help & Lessons / Working With Other Shapes

Working With Other Shapes

Making New Shapes

Every shape so far has existed from the moment the game starts — set up once in the editor, with its own tab and its own code file. Game.spawnShape(type, x, y, color, size) is different: it makes a brand-new shape while the game is running, and hands you back its id so you can control it afterwards:

export function update(self) {
    if (self.isTouchingOnce("food")) {
        const newId = Game.spawnShape("circle", self.getX(), self.getY(), "lime", 10);
        self.tail.push(newId);
    }
}

type is "circle" or "rectangle", color and size are optional (size is the radius for a circle, or the width and height for a rectangle). This is exactly what grows a snake's tail: every time it eats something, spawn one more segment and remember its id.

A spawned shape doesn't have any code of its own — there's no .js file behind it, so nothing moves it by itself. That's on purpose: it means whichever shape spawned it is fully in control, the same way it already controls any other shape:

export function update(self) {
    for (const segmentId of self.tail) {
        const segment = Game.getShape(segmentId);
        if (segment) {
            segment.setX(self.getX());
            segment.setY(self.getY());
        }
    }
}

And since a spawned shape is a real shape, it works with everything you already know — including self.isTouching(id), which is how a snake would notice it just ran into its own tail:

export function update(self) {
    for (const segmentId of self.tail) {
        if (self.isTouching(segmentId)) {
            UI.showMessage("Game Over!", "red");
        }
    }
}
Spawned shapes are never saved anywhere, so Game.restart() (a page reload) makes every one of them disappear along with everything else resetting — you don't need to clean them up yourself.