melonJS
    Preparing search index...

    Class Camera3d

    A perspective camera that extends Camera2d with a view Frustum (fov / aspect / near / far) and orientation (pitch / yaw). Slots into Stage.cameras as a drop-in replacement for Camera2d — inherits the post-effect FBO bracket, color-matrix, fade / shake / follow plumbing, and screen viewport.

    GPU backend required. Camera3d's perspective projection, depth-buffer painter sort and retained mesh draw path need a renderer with a depth buffer (renderer.supportsDepthBuffer — WebGL 2 or WebGPU); the Canvas backend has none of these and would render a stuck blank scene. Construct the Application with renderer: video.WEBGL or video.WEBGPU to make app.init() reject when that backend is unavailable. Pairing cameraClass: Camera3d with video.AUTO will emit a console.warn (and silently misrender) when AUTO falls back to Canvas — see ApplicationSettings.renderer for the contract.

    Conventions:

    • Y-down + +Z forward. Sprite at higher pos.y appears lower on screen (same as Camera2d). Sprite at higher pos.z is farther from the camera and renders smaller. Matches melonJS's 2D conventions so existing Camera2d code translates directly.
    • Rotations are extrinsic XY. pitch (X axis, look up/down) and yaw (Y axis, look left/right). There is no roll: the inherited Camera2d.rotation is not read by the view transform or the frustum rebuild, so a screen-plane bank has no effect on a 3D camera.
    • Follow offset (PR B scope). When a target is set, followOffset is applied in world space: camera.pos = target.pos + followOffset. Target-rotation-aware follow (spring-arm style, where the offset rotates with the target's orientation) is deferred until a showcase needs it (e.g. AfterBurner's banking jet).

    Known limitations (PR B scope):

    • Light2d is 2D-only — visible artifacts under perspective. Avoid combining with Camera3d for now.
    • localToWorld / worldToLocal overrides fall back to the ortho-equivalent 2D projection at z=0. Full 3D unproject for arbitrary depth is future work.
    // opt in app-wide:
    const app = new Application(1024, 768, {
    parent: "screen",
    cameraClass: Camera3d,
    });

    // or per-stage with custom fov:
    class GameStage extends Stage {
    constructor() {
    super({
    cameras: [new Camera3d(0, 0, 1024, 768, { fov: Math.PI / 3 })],
    });
    }
    }

    Hierarchy (View Summary)

    Index
    • Parameters

      • minX: number

        start x offset

      • minY: number

        start y offset

      • maxX: number

        end x offset

      • maxY: number

        end y offset

      • Optionalopts: FrustumOptions

        perspective parameters (see FrustumOptions)

      Returns Camera3d

    alpha: number

    Define the renderable opacity
    Set to zero if you do not wish an object to be drawn

    • Renderable#setOpacity
    • Renderable#getOpacity
    1.0
    
    alwaysUpdate: boolean

    Whether the renderable object will always update, even when outside of the viewport

    false
    
    ancestor: Container | Entity

    a reference to the parent object that contains this renderable

    undefined
    
    anchorPoint: ObservablePoint

    The anchor point is used for attachment behavior, and/or when applying transformations.
    The coordinate system places the origin at the top left corner of the frame (0, 0) and (1, 1) means the bottom-right corner

    a Renderable's anchor point defaults to (0.5,0.5), which corresponds to the center position.

    Note: Object created through Tiled will have their anchorPoint set to (0, 0) to match Tiled Level editor implementation. To specify a value through Tiled, use a json expression like json:{"x":0.5,"y":0.5}, or (since 19.9) a plain string preset such as bottom.
    At construction time, settings.anchorPoint also accepts the named presets "center", "top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right" on every renderable that consumes it (Sprite, Entity, Collectable, ImageLayer, Text, BitmapText, Sprite3d and subclasses).

    <0.5,0.5>
    
    applyAnchorTransform: boolean

    Whether Renderable#preDraw applies the Renderable#anchorPoint offset to the renderer transform.

    When true (the default), the renderable is shifted by -anchorPoint × (width, height) so its anchor — not its top-left corner — aligns with its position. Correct for sprites and other 2D renderables.

    Set to false for a renderable that emits its own final world coordinates and takes its origin from geometry rather than a bounds box — e.g. a Mesh on the Camera3d world-space path (a 3D mesh is positioned by its transform and has no anchor). The WebGL mesh batcher reuses this same renderer transform as its view matrix, so applying the normalized anchor there would shift every mesh by half its OWN bounds box; because scene meshes size that box per node, props and the platforms they rest on would drift apart and overlap.

    true
    

    Mesh#preDraw

    autoResize: boolean

    Whether this camera should automatically resize when the canvas resizes. Set to false for non-default cameras with fixed dimensions (e.g. minimap, split-screen viewports).

    true
    
    autoTransform: boolean

    When enabled, an object container will automatically apply any defined transformation before calling the child draw method.

    true
    
    // enable "automatic" transformation when the object is activated
    onActivateEvent: function () {
    // reset the transformation matrix
    this.currentTransform.identity();
    // ensure the anchor point is the renderable center
    this.anchorPoint.set(0.5, 0.5);
    // enable auto transform
    this.autoTransform = true;
    ....
    }
    AXIS: AxisEnum

    Axis definition NONE no axis HORIZONTAL horizontal axis only VERTICAL vertical axis only BOTH both axis

    blendMode: string

    the blend mode to be applied to this renderable — any of the modes listed on CanvasRenderer#setBlendMode, honoured identically by every renderer

    "normal"
    
    • CanvasRenderer#setBlendMode
    • WebGLRenderer#setBlendMode
    body: PhysicsBody

    the renderable physics body — the handle returned by the active PhysicsAdapter's addBody (or constructed imperatively via new Body(...)). Typed as the portable PhysicsBody interface; cast to the adapter-specific concrete type (MatterAdapter.Body, BuiltinAdapter.Body, or the legacy Body class) to reach native fields.

    // define a new Player Class
    class PlayerEntity extends me.Sprite {
    // constructor
    constructor(x, y, settings) {
    // call the parent constructor
    super(x, y , settings);

    // define a basic walking animation
    this.addAnimation("walk", [...]);
    // define a standing animation (using the first frame)
    this.addAnimation("stand", [...]);
    // set the standing animation as default
    this.setCurrentAnimation("stand");

    // add a physic body
    this.body = new me.Body(this);
    // add a default collision shape
    this.body.addShape(new me.Rect(0, 0, this.width, this.height));
    // configure max speed, friction, and initial force to be applied
    this.body.setMaxVelocity(3, 15);
    this.body.setFriction(0.4, 0);
    this.body.force.set(3, 0);
    this.isKinematic = false;

    // set the display to follow our position on both axis
    app.viewport.follow(this, app.viewport.AXIS.BOTH);
    }

    ...

    }
    bodyDef: object | undefined

    Declarative body definition consumed by the active PhysicsAdapter when this renderable is added to a container. Adapter API only — leave undefined if you build a body imperatively via this.body = new Body(...).

    When set, the parent container forwards it to world.adapter.addBody(this, this.bodyDef), which constructs the underlying physics body (matter, builtin SAT, …) and assigns the engine-portable wrapper to this.body. This is the engine-portable path: the same bodyDef produces an equivalent body under any adapter.

    Typical fields: type ("static"/"dynamic"/"kinematic"), shapes, collisionType, collisionMask, restitution, frictionAir, density, gravityScale, isSensor, maxVelocity, fixedRotation. See BodyDefinition.

    undefined
    
    bounds: Bounds

    Camera bounds

    cameraEffects: CameraEffect[]

    active camera effects (shake, fade, etc.)

    colorMatrix: ColorMatrix

    A built-in color transformation matrix applied as the final post-processing pass. Provides convenient color grading (brightness, contrast, saturation, etc.) that is always applied after any effects added via addPostEffect. When set to identity (default), no effect is applied and there is zero overhead.

    // warm HDR-like color grading
    camera.colorMatrix.contrast(1.2).saturate(1.1);
    // reset to no color grading
    camera.colorMatrix.identity();
    currentTransform: Matrix3d

    the renderable transformation matrix (4x4). For standard 2D use, only the 2D components are used (rotate around Z, scale X/Y, translate X/Y). For 3D use (e.g. Mesh), the full 4x4 matrix supports rotation around any axis, 3D translation, and perspective projection. Use the rotate(), scale(), and translate() methods rather than modifying this directly.

    damping: number

    Camera damping for smooth follow [0 .. 1]. 1 snaps the camera to the target every frame (no smoothing); lower values produce a trailing follow — 0.1 is a soft springy follow, 0.5 is snappy.

    Frame-rate independent (since 19.7 / #1478). The value is the fraction of the gap covered per frame at the engine's target framerate (timer.maxfps, default 60). The underlying implementation switched from pos.lerp to pos.damp with lambda = -ln(1 - damping) * timer.maxfps, so the legacy per-frame fraction is recovered exactly at the target rate AND the wall-clock convergence stays constant when the actual frame rate drifts (slow machine, throttled tab, high-refresh display). Existing damping tuning carries over with no changes.

    1.0
    
    deadzone: Rect

    the camera deadzone

    edges: Vector2d[]

    The edges here are the direction of the nth edge of the polygon, relative to the nth point. If you want to draw a given edge from the edge value, you must first translate to the position of the starting point.

    far: number

    the furthest point relative to the camera. Widened from 1000 in 19.7 — see Camera2d#near.

    1e6
    
    floating: boolean

    If true, this renderable will be rendered using screen coordinates, as opposed to world coordinates. Use this, for example, to define UI elements.

    false
    
    follow_axis: number

    default value follow

    followOffset: Vector3d

    World-space offset from the followed target. When target is set via Camera2d#follow, the camera position resolves to target.pos + followOffset. Common usage: (0, -2, -8) for a behind-and-above third-person view.

    Treated as world-space in this release — target-rotation-aware follow (where the offset rotates with the target's orientation, spring-arm style) is deferred until a showcase needs it (e.g. AfterBurner's banking jet).

    (0, 0, 0)
    
    frustum: Frustum

    the view frustum (perspective parameters + projection matrix). Mutating frustum.fov / aspect / near / far directly requires calling frustum.update() to rebuild the matrix; the proxy setters on this camera (camera.fov = ...) handle that automatically.

    GUID: string

    (G)ame (U)nique (Id)entifier"
    a GUID will be allocated for any renderable object added
    to an object container (including the app.world container)

    indices: number[]

    a list of indices for all vertices composing this polygon

    isDirty: boolean

    when true the renderable will be redrawn during the next update cycle

    true
    
    isKinematic: boolean

    If true then physic collision and input events will not impact this renderable

    true
    
    isPersistent: boolean

    make the renderable object persistent over level changes

    false
    
    lookAhead: Vector3d

    Reserved for future follow-look-ahead support — currently unused by updateTarget. The intent is: when wired in, the camera will look at target.pos + lookAhead instead of target.pos, so a follow-cam stays slightly ahead of its target (e.g. for a cinematic forward-looking shot in AfterBurner). Field is exposed now so user code can set it without waiting for the wiring.

    (0, 0, 1)
    

    A mask limits rendering elements to the shape and position of the given mask object. So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.

    undefined
    
    // apply a mask in the shape of a Star
    myNPCSprite.mask = new me.Polygon(myNPCSprite.width / 2, 0, [
    // draw a star
    {x: 0, y: 0},
    {x: 14, y: 30},
    {x: 47, y: 35},
    {x: 23, y: 57},
    {x: 44, y: 90},
    {x: 0, y: 62},
    {x: -44, y: 90},
    {x: -23, y: 57},
    {x: -47, y: 35},
    {x: -14, y: 30}
    ]);
    name: string

    The name of the renderable

    ""
    
    near: number

    the closest point relative to the camera. Widened from -1000 in 19.7 to accommodate sprites at large depth values now that aVertex.z participates in clip-space (PR A): the default Container.autoDepth = true assigns pos.z = childCount so any container with >1000 children would otherwise clip-cull, and the common Y-sort pattern sprite.depth = sprite.pos.y exceeds 1000 on tall maps. Override per-camera if you need tighter z clipping.

    -1e6
    
    offset: Vector2d

    offset for shake effect

    onVisibilityChange: Function

    an event handler that is called when the renderable leave or enter a camera viewport

    undefined
    
    this.onVisibilityChange = function(inViewport) {
    if (inViewport === true) {
    console.log("object has entered the in a camera viewport!");
    }
    };
    pitch: number

    X-axis rotation in radians (look up/down). Positive values pitch the camera up.

    0
    
    points: Vector2d[]

    Array of points defining the Polygon
    Note: If you manually change points, you must call recalcafterwards so that the changes get applied correctly.

    origin point of the Polygon

    postEffects: any[]

    the list of post-processing shader effects applied to this renderable (GPU backends — WebGL and WebGPU). Effects are applied in order. Use addPostEffect, getPostEffect, and removePostEffect to manage effects, or assign directly. On the Canvas renderer effects stay inert (the scene keeps rendering un-effected).

    []
    
    // add effects via helper methods
    mySprite.addPostEffect(new DesaturateEffect(renderer));
    mySprite.addPostEffect(new VignetteEffect(renderer));
    // assign directly
    mySprite.postEffects = [new SepiaEffect(renderer), new VignetteEffect(renderer)];
    projectionMatrix: Matrix3d

    the default camera projection matrix (2d cameras use an orthographic projection by default).

    screenProjection: Matrix3d

    the screen-space projection matrix for non-default cameras. Maps coordinates so that (0,0) aligns with the camera's screenX/screenY position. Used for rendering floating elements (e.g. background layers) in the correct screen area.

    screenX: number

    the x position on the screen where this camera viewport is rendered.

    0
    
    screenY: number

    the y position on the screen where this camera viewport is rendered.

    0
    
    smoothFollow: boolean

    enable or disable damping

    true
    
    target: Vector2d | Vector3d | null

    target to follow

    type: string = "Rectangle"

    The shape type (used internally).

    updateWhenPaused: boolean

    Whether to update this object when the game is paused.

    false
    
    visibleInAllCameras: boolean

    If true, this floating renderable will be rendered by all cameras (e.g. background image layers). If false (default), floating elements are only rendered by the default camera (e.g. UI/HUD elements). Only applies to floating renderables in multi-camera setups.

    false
    
    worldProjection: Matrix3d

    the world-space projection matrix for non-default cameras (offset/zoomed). Maps world coordinates to the camera's screen viewport.

    yaw: number

    Y-axis rotation in radians (look left/right). Positive values yaw the camera to the right.

    0
    
    defaultSortOn: "depth" | "x" | "y" | "z" = "depth"

    Override Camera2d.defaultSortOn to declare "depth" as this camera's preferred sort mode. Application / Stage apply this to world.sortOn at bootstrap, so games opting into Camera3d via cameraClass: Camera3d get camera-distance painter's sort for free — the only correct sort for alpha-blended sprites under perspective.

    • get fog(): FogOptions | null

      The fog settings as given to Camera3d#setFog, or null when fog is off. The omitted fields are not filled in here — they are resolved per frame against the clip planes and the renderer's background colour.

      Returns FogOptions | null

    • get isDefault(): boolean

      Whether this camera is using default settings (no screen offset, no zoom). Non-default cameras use custom projections for viewport positioning and scaling.

      Returns boolean

      true if this camera has no screen offset and zoom is 1

    • get zoom(): number

      the zoom level of this camera. Values less than 1 zoom out (show more of the world), values greater than 1 zoom in (show less of the world).

      Returns number

      1
      
      // zoom out to show the full level in a 180x100 minimap
      camera.zoom = Math.min(180 / levelWidth, 100 / levelHeight);
    • set zoom(value: number): void

      Parameters

      • value: number

      Returns void

    • Returns true if the polygon contains the given point.
      (Note: it is highly recommended to first do a hit test on the corresponding
      bounding rect, as the function can be highly consuming with complex shapes)

      Parameters

      • x: number

        x coordinate or a vector point to check

      • y: number

        y coordinate

      Returns boolean

      True if the polygon contain the point, otherwise false

      if (polygon.contains(10, 10)) {
      // do something
      }
      // or
      if (polygon.contains(myVector2d)) {
      // do something
      }
    • Returns true if the polygon contains the given point.
      (Note: it is highly recommended to first do a hit test on the corresponding
      bounding rect, as the function can be highly consuming with complex shapes)

      Parameters

      Returns boolean

      True if the polygon contain the point, otherwise false

      if (polygon.contains(10, 10)) {
      // do something
      }
      // or
      if (polygon.contains(myVector2d)) {
      // do something
      }
    • fadeIn effect

      fade to the specified color

      Parameters

      • color: string | Color

        a CSS color value

      • Optionalduration: number = 1000

        expressed in milliseconds

      • OptionalonComplete: () => void

        callback once effect is over

      Returns void

      // flash the camera to white for 75ms
      app.viewport.fadeIn("#FFFFFF", 75);
    • fadeOut(flash) effect

      screen is filled with the specified color and slowly goes back to normal

      Parameters

      • color: string | Color

        a CSS color value

      • Optionalduration: number = 1000

        expressed in milliseconds

      • OptionalonComplete: () => void

        callback once effect is over

      Returns void

      // fade the camera to white upon dying, reload the level, and then fade out back
      app.viewport.fadeIn("#fff", 150, function() {
      me.audio.play("die", false);
      me.level.reload();
      app.viewport.fadeOut("#fff", 150);
      });
    • set the camera to follow the specified renderable.
      (this will put the camera center around the given target)

      Parameters

      Returns void

      // set the camera to follow this renderable on both axis, and enable damping
      app.viewport.follow(this, app.viewport.AXIS.BOTH, 0.1);
    • Where this renderable IS in the game world — its own pos plus every ancestor's, as a Vector3d so the z component is summed across the chain too (important for Camera3d's frustum culling, which previously read obj.depth — local pos.z — and mis-culled children nested under a container with its own non-zero depth).

      Reach for this for anything positional: culling, distance checks, hit tests, placing one renderable relative to another. It is cheap, and it is what the engine's own culling uses.

      Reach for Renderable#getWorldTransform instead when a position is not enough — when rotation, scale or flip along the ancestor chain matters, or when you need to map an arbitrary point rather than just the origin. This method sums translations only, so under a rotated or scaled ancestor it reports where the renderable's pivot is and nothing about how its content is oriented.

      Note the two also frame the question differently. This one is "where am I"; getWorldTransform() is "what space is my content drawn in". For a Container those coincide, because a container offsets its children by its own position. For a leaf they differ by exactly that position, which a leaf applies inside its own draw().

      The returned vector is pooled and reused — copy it if you need to hold onto the value across another call.

      Returns Vector3d

      this renderable's absolute position

      Renderable#getWorldTransform

    • Write the camera's world-space orientation basis into the given vectors: right (camera local +X), up (+Y), and forward (+Z — the direction the camera looks). Derived from yaw / pitch (the inverse of the view rotation), so they update as the camera turns. Handy for orienting camera-facing geometry — e.g. Sprite3d billboards.

      Parameters

      • right: Vector3d

        receives the right axis (unit)

      • up: Vector3d

        receives the up axis (unit)

      • forward: Vector3d

        receives the forward / look axis (unit)

      Returns this

      this camera, for chaining

    • Get the first camera effect matching the given class.

      Type Parameters

      Parameters

      • effectClass: new (...args: any[]) => T

        the effect class to search for

      Returns T | undefined

      the first matching effect, or undefined

      const shake = camera.getCameraEffect(ShakeEffect);
      
    • Protected

      The transform this renderable interposes between its ancestor's frame and the frame its own content is drawn in — a mirror of what Renderable#preDraw applies to the renderer, as a matrix.

      This is not Renderable#currentTransform. A renderable's placement is split across two members: pos holds where it is, and currentTransform holds only what rotate() / scale() / translate() accumulate — it never contains the position. preDraw composes the two by conjugation, so a rotation pivots about the renderable's position rather than the origin. On a renderable you never rotated, currentTransform is therefore the identity and says nothing about where its content lands, while this method returns the translation that actually places it.

      Container extends this with the offset it applies to its children, which a leaf renderable does not have: a leaf's own draw() places itself from pos.

      Parameters

      • out: Matrix3d

        matrix to write into; nothing is stored on the renderable itself, so callers own the lifetime

      Returns Matrix3d

      out, for chaining

      Renderable#getWorldTransform

    • Get post-processing shader effects. When called with a class, returns the first effect matching the given class. When called without arguments, returns the full effects array.

      Parameters

      • OptionaleffectClass: Function

        the effect class to search for

      Returns any

      the matching effect, the effects array, or undefined

      const desat = sprite.getPostEffect(DesaturateEffect);
      const allEffects = sprite.getPostEffect();
    • The space this renderable's content is drawn IN, as a matrix — the full form of Renderable#getAbsolutePosition, which sums positions up the ancestor chain and therefore cannot represent the rotation, scale or flip accumulated along the way.

      Reach for getAbsolutePosition() instead for ordinary positional work — culling, distance checks, hit tests. It is cheaper and it is what the engine culls with. Use this when a position is not enough:

      • an ancestor is rotated or scaled, so a translation cannot describe the result
      • you need to map an arbitrary point, not just the origin — a corner, a click position, one renderable's coordinates into another's space
      • you need to compose or invert the transform (inv(A) · B converts between two frames, which is how ParticleEmitter.referenceSpace measures particles against a container that is not their parent)

      The two also frame the question differently, and it shows on a leaf. getAbsolutePosition() is "where am I"; this is "what space is my content drawn in". For a Container those coincide, because a container offsets its children by its own position. For a leaf they differ by exactly that position, which a leaf applies inside its own draw(). So with no rotation, scale or flip anywhere, a container's translation column equals its getAbsolutePosition() while a leaf's equals its PARENT's.

      The walk stops at a floating ancestor, because a floating renderable draws in screen space: Container#draw resets the transform outright for those, so the chain genuinely ends there rather than continuing to the root.

      The camera needs no special handling — Camera2d folds its view transform into the root container's currentTransform, so it is picked up like any other level.

      Parameters

      • out: Matrix3d

        matrix to write into; nothing is stored on the renderable itself, so callers own the lifetime

      Returns Matrix3d

      out, for chaining

      Renderable#getAbsolutePosition

      // map a point from one renderable's space into another's
      const from = a.getWorldTransform(new Matrix3d());
      const into = b.getWorldTransform(new Matrix3d()).invert();
      const point = new Vector2d(10, 20); // in a's space
      from.apply(point); // -> world
      into.apply(point); // -> b's space
      // just need to know where something is? use the cheaper call
      const where = renderable.getAbsolutePosition();
    • Returns true if the vertices composing this polygon form a convex shape (vertices must be in clockwise order).

      Returns boolean | null

      true if the vertices are convex, false if not, null if not computable

    • Visibility check used by Container.update (in turn driving Container.draw) to skip rendering off-screen children.

      Camera2d's implementation tests a 2D bounds-rectangle overlap against this.worldView — that test is invalid under perspective: the visible region is a frustum that widens with distance and rotates with the camera's pitch / yaw, not a fixed axis-aligned rect at the camera's x / y. Camera3d substitutes plane-based frustum culling — each non-floating renderable's bounding sphere is tested against the six frustum planes that were extracted in the most recent update() call. Floating elements (HUD / UI) still use Camera2d's 2D rect test because their bounds are screen-space and the perspective transform doesn't apply to them.

      Parameters

      • obj: Renderable

        the renderable to test

      • Optionalfloating: boolean = obj.floating

        test against screen coordinates instead of frustum

      Returns boolean

      true if the renderable's bounds overlap the frustum

    • convert the given "local" (screen) coordinates into world coordinates

      Parameters

      • x: number

        the x coordinate of the local point to be converted

      • y: number

        the y coordinate of the local point to be converted

      • Optionalv: Vector2d

        an optional vector object where to set the converted value

      Returns Vector2d

      the converted world coordinates as a Vector2d

    • Point the camera at a world-space target by deriving pitch and yaw from the direction (target − camera.pos). Roll is unaffected.

      Three call shapes:

      • lookAt(x, y, z) — raw world coordinates
      • lookAt(vector3d) — a 3D point
      • lookAt(renderable) — uses renderable.pos (matches the Renderable.lookAt(target) signature so Camera3d is a structural drop-in replacement for Camera2d / Renderable in user code).

      Last-write-wins with manual pitch / yaw assignment: if you call lookAt(...) then set camera.pitch = 0.1 directly, the next frame renders with the manual pitch.

      Parameters

      • xOrTarget: number | { pos?: ObservableVector3d; x: number; y: number; z?: number }

        target world x, or a target with pos / x,y,z

      • Optionaly: number

        target world y (only when first arg is a number)

      • Optionalz: number

        target world z (only when first arg is a number)

      Returns this

      this camera

    • move the camera upper-left position by the specified offset.

      Parameters

      • x: number

        horizontal offset

      • y: number

        vertical offset

      Returns void

      focusOn

      // Move the camera up by four pixels
      app.viewport.move(0, -4);
    • Lifecycle hook fired by Container when this renderable is added to a container that is part of the active scene graph. Override to wire up input handlers, register external listeners, or grab adapter references — this.parentApp is guaranteed to be available here. Pair with Renderable#onDeactivateEvent.

      Parameters

      • ..._args: any[]

        the rest parameter exists for subclass-signature compatibility; Container.addChild currently forwards nothing

      Returns void

    • Legacy collision callback — fires every frame this renderable body is overlapping another body. Kept for backward compatibility with code written against pre-19.5 melonJS; semantics are unchanged from the 19.4 contract.

      NOTE — onCollision is NOT equivalent to Renderable.onCollisionActive. The two handlers exist side by side and have intentionally different contracts:

      onCollision (legacy) onCollisionActive (modern)
      Cadence for dynamic-dynamic pairs 2× per frame per side 1× per frame per side
      response.a semantics Fixed per pair (first body in detector call) Always the receiver (response.a === this)
      response.b semantics Fixed per pair Always the partner (response.b === other)
      response.normal / response.depth ✓ — normal.y < -0.7 = "push me up"
      return false to skip push-out ✓ (honored by SAT) ✗ — use bodyDef.isSensor or setSensor instead

      If you're writing new code, prefer onCollisionActive. Keep onCollision only when its every-frame, return-false, fixed-a/b semantics are what you want.

      Parameters

      • response: ResponseObject

        the SAT response object; the legacy handler receives this, not the adapter's CollisionResponse, which is why normal and depth are absent from the table above

      • other: Renderable

        the other renderable touching this one (a reference to response.a or response.b)

      Returns boolean

      true if the object should respond to the collision (its position and velocity will be corrected); the return value is only honored by the builtin SAT adapter.

      // legacy collision handler — note the receiver-side check on response.a
      onCollision(response) {
      if (response.b.body.collisionType === me.collision.types.ENEMY_OBJECT) {
      this.pos.sub(response.overlapV);
      this.hurt();
      return false; // skip the SAT push-out
      }
      return true;
      }
    • OnDestroy Notification function
      Called by engine before deleting the object. Receives whatever destroy(...args) was called with — the production path (Container.removeChildNow) passes nothing. Stage has its own onDestroyEvent, which does forward the active Application.

      Parameters

      • ..._args: any[]

        forwarded by destroy(...args); normally empty

      Returns void

    • Bulk frustum cull via the world's Octree. Returns every renderable whose octant the current frustum overlaps — conservative (some renderables may still narrow-cull out via Camera3d#isVisible's per-sphere test) but O(visible + walk) instead of O(scene).

      Only applicable under cameraClass: Camera3d (or any setup where world.sortOn === "depth" and the broadphase is an Octree). Returns an empty array under a 2D broadphase — call sites can guard on the array length or branch on world.sortOn.

      For a 1000-renderable scene with ~50 visible, expect a 5-20× speedup over walking every renderable and per-item Camera3d#isVisible.

      Parameters

      • world: { broadphase: unknown; sortOn: string }

        the world to cull (its broadphase must be an Octree); typed structurally to sidestep the Camera3d → World import cycle

        • broadphase: unknown

          the world's spatial broadphase

        • sortOn: string

          guard: returns empty unless this equals "depth"

      • Optionalout: Renderable[]

        caller-supplied result array (re-entrancy-safe)

      Returns Renderable[]

      visible-renderable candidates

      const visible = camera.queryVisible(app.world);
      for (const r of visible) {
      // narrow-phase per-renderable visibility (sphere / OBB) if needed
      if (camera.isVisible(r)) r.draw(renderer);
      }
    • reset the camera position to specified coordinates

      Parameters

      • Optionalx: number = 0

        initial position of the camera on the x axis

      • Optionaly: number = 0

        initial position of the camera on the y axis

      Returns void

    • Rotate this renderable by the specified angle (in radians). When called with just an angle, rotates around the Z axis (2D rotation). When called with an angle and a Vector3d axis, rotates around that axis in 3D.

      Parameters

      • angle: number

        The angle to rotate (in radians)

      • Optionalv: any

        the axis to rotate around (defaults to Z axis for 2D)

      Returns Renderable

      Reference to this object for method chaining

    • scale the renderable around his anchor point. Scaling actually applies changes to the currentTransform member which is used by the renderer to scale the object when rendering. It does not scale the object itself. For example if the renderable is an image, the image.width and image.height properties are unaltered but the currentTransform member will be changed.

      Parameters

      • x: number

        a number representing the abscissa of the scaling vector.

      • Optionaly: number = x

        a number representing the ordinate of the scaling vector.

      • Optionalz: number = 1

        a number representing the depth of the scaling vector.

      Returns Renderable

      Reference to this object for method chaining

    • set the camera boundaries (set to the world limit by default). the camera is bound to the given coordinates and cannot move/be scrolled outside of it.

      Parameters

      • x: number

        world left limit

      • y: number

        world top limit

      • w: number

        world width limit

      • h: number

        world height limit

      Returns void

    • Update the perspective near/far clip distances and rebuild the projection matrix in one shot. Anything closer than near or farther than far is clipped by the GPU; projection math also degrades sharply just before far, so size the far plane to the deepest object in your scene with a little headroom. Defaults are near = 0.1, far = 1000 — typical AfterBurner-class scenes with enemies spawning at z = 3000+ need to push far out.

      This is the supported way to change near/far at runtime. The inherited Camera2d.near / .far are plain instance fields — direct assignment (camera.near = 5) updates the cached value but leaves the projection matrix stale until the next resize(). TypeScript's property-vs-accessor rule prevents shadowing the inherited fields with accessor pairs, so the convenience method is the public contract instead.

      Parameters

      • near: number

        near clip distance

      • far: number

        far clip distance

      Returns this

      this camera (chainable)

    • change the deadzone settings. the "deadzone" defines an area within the current camera in which the followed renderable can move without scrolling the camera.

      Parameters

      • w: number

        deadzone width

      • h: number

        deadzone height

      Returns void

      follow

    • Enable, reconfigure, or switch off distance fog for this camera.

      Fog fades mesh geometry toward a colour with distance, which is what stops a 3D scene reading as flat cut-outs and lets props appear at the far plane without a visible edge. It is off until you call this, and a scene that never does renders exactly as it did before.

      Two curves, chosen with mode:

      mode parameters character
      "linear" (default) near, far you name the two distances
      "exp2" density clear up close, closes fast at range

      Every parameter is optional, and an omitted one is resolved live each frame rather than captured here: distances track the camera's own clip planes and the colour tracks renderer.backgroundColor. That is deliberate — fog distances that silently disagreed with the clip planes after a later Camera3d#setClipPlanes call would clip geometry before it finished fading, and a fog colour that did not follow a day/night background fade would leave a band at the horizon.

      Fog is per camera, so a split-screen or minimap view fogs independently — and a Camera2d never fogs at all.

      heightFalloff adds a second falloff with altitude, so mist pools in low ground instead of hanging at every height equally. It defaults to 0, which is uniform fog — not a special case, the same integral with the dial at zero.

      Parameters

      • options: FogOptions | null

        fog settings, or null to switch fog off

      Returns this

      this camera (chainable)

      on an unknown mode, a non-finite or negative distance, far at or below near, or a density at or below zero

      // A typical outdoor scene: set the sky, size the frustum to the level,
      // then let fog take its distances and its colour from both.
      class GameStage extends Stage {
      onResetEvent(app) {
      app.renderer.backgroundColor.parseCSS("#cfe6f7");

      const camera = app.viewport; // a Camera3d
      camera.setClipPlanes(1, 9000);
      // no colour passed: it tracks `backgroundColor`, so the terrain
      // dissolves into the sky and props arrive without a hard edge
      camera.setFog({ near: 1200, far: 7000 });
      }
      }
      // A single density instead of two distances. Omit it and it resolves to
      // `2 / far`, which reads the same at any world scale.
      camera.setFog({ mode: "exp2", density: 0.0004 });
      // Fog that is deliberately NOT the sky — a green murk under a blue sky.
      // Passing a `Color` keeps it by reference, so this fog can be animated
      // by mutating the colour, without calling `setFog` again.
      const murk = new Color(90, 120, 80);
      camera.setFog({ far: 5000, color: murk });
      murk.setColor(60, 90, 55); // thickens over the next frame
      // Mist pooling in a valley: dense along the floor, thinning up the
      // walls so the tree line stays crisp. Render space is Y-down, so
      // `fogHeight` is the floor and density rises BELOW it.
      camera.setFog({
      near: 1200,
      far: 7000,
      fogHeight: 0,
      heightFalloff: 0.0015,
      });
      // Everything is optional: with nothing at all, fog spans the camera's
      // own clip planes in the backdrop's colour.
      camera.setFog({});
      camera.setFog(null); // and off again
      • Camera3d#setClipPlanes
      • Mesh#fog
    • Set the target-local follow offset. Called once when configuring a follow-cam (e.g. behind-and-above third person: setFollowOffset(0, -2, -8)).

      Parameters

      • x: number

        target-local x offset

      • y: number

        target-local y offset

      • z: number

        target-local z offset

      Returns this

      this camera

    • set new value to the Polygon

      Parameters

      • x: number

        position of the Polygon

      • y: number

        position of the Polygon

      • points: PolygonVertices | LineVertices

        array of vector or vertices defining the Polygon

      Returns Camera3d

      this instance for object chaining

    • Set the camera screen position and size in a single call.

      Parameters

      • x: number

        x position on screen

      • y: number

        y position on screen

      • Optionalw: number

        width (defaults to current width)

      • Optionalh: number

        height (defaults to current height)

      Returns this

      this camera for chaining

    • shake the camera

      Parameters

      • intensity: number

        maximum offset that the screen can be moved while shaking

      • duration: number

        expressed in milliseconds

      • Optionalaxis: number

        specify on which axis to apply the shake effect (see Camera2d.AXIS)

      • OptionalonComplete: () => void

        callback once shaking effect is over

      • Optionalforce: boolean

        if true this will override the current effect

      Returns void

      // shake it baby !
      app.viewport.shake(10, 500, app.viewport.AXIS.BOTH);
    • Shifts the Polygon to the given position vector.

      Parameters

      • x: number

        The x coordinate or a vector point to shift to.

      • Optionaly: number

        The y coordinate. This parameter is required if the first parameter is a number.

      Returns void

      polygon.shift(10, 10);
      // or
      polygon.shift(myVector2d);
    • Shifts the Polygon to the given position vector.

      Parameters

      Returns void

      polygon.shift(10, 10);
      // or
      polygon.shift(myVector2d);
    • update the bounding box for this shape.

      Parameters

      • Optionalabsolute: boolean = true

        update the bounds size and position in (world) absolute coordinates

      Returns Bounds

      this shape bounding box Rectangle object

    • Project a world-space point to 2D screen (canvas pixel) coordinates through this camera's view + perspective projection (perspective divide included). The origin is top-left with y down, matching where geometry at world rasterizes and the engine's 2D draw space — so the result can be fed straight to the 2D draw API (HUD pinned to a 3D object, picking, debug overlays such as the 3D bounding-box wireframe).

      Returns null when the point is at or behind the camera (clip w ≤ 0) — projecting it would yield a mirrored/degenerate pixel, so callers (e.g. a debug wireframe) can skip it cleanly instead of drawing garbage. Otherwise returns the screen-space pixel coordinates.

      Parameters

      • world: Vector3d

        the world-space point to project

      • Optionalout: Vector2d = ...

        optional Vector2d to receive the result (allocated if omitted)

      Returns Vector2d | null

      the screen-space pixel coordinates, or null if behind the camera