Game Development 8 min read

Building a Super Mario MVP with LeaferJS and Vue

This article demonstrates how to create a minimal Super Mario‑style platformer using JavaScript, LeaferJS for graphics rendering, and Vue for UI and map editing, covering background looping, scene management, sprite classes, a simple physics engine with gravity, collision detection, jumping, camera follow, scoring, and a basic victory condition.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Building a Super Mario MVP with LeaferJS and Vue

The tutorial shows how to build a minimal Super Mario‑style game (MVP) using JavaScript, the LeaferJS rendering engine, and Vue for UI and map editing. It starts with creating a looping background, then defines a Scene class to hold and run sprites.

class Scene {
  sprites = [];

  // 添加内容
  add(sprite) {
    this.sprites.push(sprite);
  }

  run() {
    // 绘制内容,传入canvas上下文
    this.sprites.forEach((sprite) => {
      sprite.draw(context)
    })
    ...
  }
}

Next, a generic Sprite base class is introduced, providing position, size, and velocity properties.

class Sprite {
  constructor(options) {
    const { x, y, width, height, vx, vy } = options;
    this.x = x;
    this.y = y;
    this.vx = vx;
    this.vy = vy;
    this.width = width;
    this.height = height;
  }
}

Specific game objects such as Mario extend this base class and implement a draw method that updates position and renders the sprite.

class SpriteMario extends Sprite {
  constructor(options) {
    super(options);
    // ...
  }

  draw(context) {
    this.x += this.vx;
    this.y += this.vy;
    context.drawImage(this.resource, this.x, this.y, this.width, this.height)
  }
}

The main game loop runs the physics engine, the scene, the background, and updates the camera to follow Mario, using requestAnimationFrame for smooth animation.

run() {
    // 运行物理引擎
    this._physicsEngine.run({
      camera: this.camera,
      scene: this.scene,
    });

    // 运行场景中的精灵
    this.scene.run();

    // 运行背景
    this._background.run();

    // 相机跟随玛丽
    this.camera.x =
        this._mario.x < MARIO_VIEW_OFFSET
          ? 0
          : this._mario.x - MARIO_VIEW_OFFSET;

    requestAnimationFrame(this.run.bind(this));
  }

A simple physics engine adds gravity, limiting vertical speed to avoid excessive acceleration.

class PhysicsEngine {
  run (options) {
    // ...
    // 为了防止过快给了个10的速度阈值
    sprite.vy = Math.min(10, sprite.vy + G);
  }
}

Collision detection is performed using axis‑aligned rectangle checks, allowing the game to handle ground contact, brick breaking, and item pickups. Jumping uses a basic projectile‑motion formula with an initial velocity that increases while the up‑key is held.

sprite.v0 -= G;
  sprite.vy = -sprite.v0;

When Mario hits a brick, the brick is destroyed and its fragments follow a parabolic trajectory calculated with a quadratic equation.

this.animatedX += 2;
  this.animatedY = 0.1 * this.animatedX * this.animatedX - b * this.animatedX;

A simple camera system treats the view as a window that follows Mario’s x‑position, ensuring only the visible portion of the world is rendered.

camera.x = mario.x

The score system uses LeaferJS’s Text objects to display points when Mario defeats enemies, collects items, or breaks bricks. A victory flag triggers a win state when collided with.

Finally, a Vue‑based map editor lets developers place sprites manually by clicking, enabling rapid level creation without manually entering coordinates.

The article concludes by noting that the MVP lacks features such as music, turtles, and polished win animations, and provides links to the GitHub repository and a live demo for further exploration.

JavaScriptGame Developmentvuephysics engineLeaferJSSuper Mario
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login 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.