Skills

Melonjs Renderables

Use this skill when subclassing Renderable, writing a custom draw() method, handling...

Install

npx skills add melonjs/melonJS --skill melonjs-renderables -g -a claude-code -y
Repository
melonjs/melonJS6.4k
Category
Writing
Updated
3d ago
License
MIT
Context cost
Mediumabout 3,000 tokens
Runs scripts
No, instructions only

What it does

Use this skill when subclassing Renderable, writing a custom draw() method, handling pointer or click events on game objects, applying post effects and shaders, or controlling draw order. Covers the pos-relative draw contract, isKinematic and input, addPostEffect vs the deprecated shader property, and z-ordering. Triggers on: Tween, easing, animate, Renderable, extends Renderable, draw(, update(, isKinematic, pointerEvent, registerPointerEvent, onClick, addPostEffect, removePostEffect, ShaderEffect, addChild, z-order, anchorPoint, floating.

Renderables, input and effects

Subclassing Renderable, custom drawing, receiving pointer events, and applying post effects, with the traps that produce silently wrong output rather than an error.

Everything here is a silent failure: the code runs, nothing throws, and the result is wrong. Those are the cases worth memorising, because nothing in the type signatures warns you.

1. A custom draw() must position itself from this.pos

The renderer is not pre-translated to the renderable's position when draw() is called. Container.draw translates by the container's own pos and then calls child.preDraw / draw / postDraw; preDraw never translates by the child's pos. Read this.pos and draw relative to it.

class Marker extends Renderable {
    draw(renderer) {
        // ✗ draws at the parent container's origin, not at the marker
        renderer.fillRect(0, 0, this.width, this.height);

        // ✓
        renderer.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    }
}

The symptom is an object that renders correctly at position (0, 0) and appears stuck at the top-left as soon as you move it.

Zero the anchor in custom-draw renderables. preDraw does not translate to pos, but it does apply the anchor offset (-width * anchorPoint.x, -height * anchorPoint.y). With the default centred anchor, drawing at this.pos therefore lands half a size off:

constructor(x, y, w, h) {
    super(x, y, w, h);
    this.anchorPoint.set(0, 0);   // ← or every custom draw is offset by -w/2, -h/2
}

2. isKinematic must be false to receive input or collisions

Renderable.isKinematic defaults to true, which means "physics collision and input events will not impact this renderable". A kinematic renderable is skipped by the pointer-event dispatcher entirely.

Read the whole SKILL.md on GitHub

More in Writing