Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/OmarMtya/enginejs-module/llms.txt

Use this file to discover all available pages before exploring further.

motor.js is the heart of Engine.js’s runtime. It contains the animation loop, the rendering pipeline, the physics tick, and the click-detection binder. Most of its exports are attached to the $g global by index.js, so in a plain HTML project you call them as $g.Animar(), $g.DetenerAnimacion(), and so on. See also: Guides: Animation Loop, Concepts: Physics, and the Environment API for the shared state these functions read and write.

Exported Functions

IniciarAnimacion

Starts the engine’s animation loop. Exposed on the global as $g.Animar.
$g.Animar();
Parameters: none Returns: void Behaviour (in order):
  1. Calls the internal Inicializar function, which resolves initial overlaps between figures and plays sounds whose activacion is 'inicial'.
  2. Snapshots Environment.figuras into Environment.backup by calling Environment.Copy on every figure, so the scene can be fully restored later.
  3. Calls window.requestAnimationFrame(Step) to begin the loop, storing the returned request ID in the module-private requestId variable.
Call $g.Animar() only after you have initialised the canvas ($g.InitCanvas or $g.InitCanvasStatic) and added all your figures with $g.AgregarFigura. Figures added after $g.Animar() is called will not be included in Environment.backup and cannot be restored by $g.DetenerAnimacion().
Example:
$g.InitCanvas(document.getElementById('c'), document.getElementById('wrap'));

const floor = new $g.Figura({
  tipo: 'cuadrado',
  transform: new $g.Transform({ x: 0, y: 550, anchura: 800, altura: 50, relleno: '#333' })
});
const ball = new $g.Figura({
  tipo: 'circulo',
  transform: new $g.Transform({ x: 400, y: 50, radio: 25, relleno: '#e63' }),
  rigido: new $g.Rigido()
});

$g.AgregarFigura(floor);
$g.AgregarFigura(ball);
$g.Animar();

DetenerAnimacion

Stops the animation loop and restores the scene to the snapshot taken when IniciarAnimacion was called. Exposed on the global as $g.DetenerAnimacion.
$g.DetenerAnimacion();
Parameters: none Returns: void Behaviour (in order):
  1. Guards against a no-op call: does nothing if requestId is undefined (i.e. the loop was never started or is already stopped).
  2. Calls window.cancelAnimationFrame(requestId) and sets requestId = undefined.
  3. Replaces Environment.figuras with a fresh deep-clone of every figure in Environment.backup (via Environment.Copy), reverting all positions, velocities, and physics state to their initial values.
  4. Sets the module-private animando flag to false.
  5. Pauses every figure whose transform.sonido.activacion === 'inicial'.
After DetenerAnimacion returns, the canvas is not automatically cleared or redrawn. Call $g.Dibujar(true) immediately afterwards if you want to render the reset state to the screen.
Example:
document.getElementById('stopBtn').addEventListener('click', () => {
  $g.DetenerAnimacion();
  $g.Dibujar(true); // show the restored initial frame
});

Dibujar

Renders the current frame to the canvas. Optionally advances the physics simulation one tick before drawing. Exposed on the global as $g.Dibujar.
$g.Dibujar(sinAvance);
sinAvance
boolean
default:"true"
When true (the default), the function draws the current state of all figures without advancing physics — useful for a static preview or for rendering the initial/restored frame. When false, physics is advanced via calcularSiguientePaso() after the draw pass.
Returns: void Rendering pipeline (executed every call):
  1. If sinAvance is false and the animando flag is not yet set, calls Inicializar() to resolve overlaps before the first frame.
  2. Increments Environment.contador by 1.
  3. Calls c.clearRect(0, 0, Environment.anchura, Environment.altura) to wipe the previous frame.
  4. Calls c.beginPath() to reset the path buffer.
  5. Iterates Environment.figuras and draws each figure according to its tipo:
tipoDraw call
'circulo'Sets fillStyle, calls arc(x, y, radio, 0, 2π), then fill()
'cuadrado'Sets fillStyle, calls fillRect(x, y, anchura, altura), then stroke()
'imagen' (static)Calls drawImage(src, 0, 0, src.width, src.height, x, y, anchura, altura)
'imagen' (sprite)Delegates to the internal DibujarSprite function
  1. If sinAvance is false, calls the internal calcularSiguientePaso function to update positions and physics state.
For a figure of tipo === 'imagen', transform.imagen must be a valid Imagen object. If it is null or undefined, Dibujar logs console.error("Objeto tipo imagen no contiene una imagen") and skips that figure. If transform.imagen.src is not a proper HTMLImageElement, a second console.error is emitted.
Example — static preview before starting the loop:
$g.InitCanvasStatic(canvas, 800, 600);
$g.AgregarFigura(myFigure);
$g.Dibujar(true); // render once, no physics

detectarClick

Attaches or detaches a click handler on the canvas element. On each click, it iterates all figures in Environment.figuras and calls Environment.clickListener with every Figura whose bounds contain the click coordinates. Exposed on the global as $g.DetectarClick.
$g.DetectarClick(bindear);
bindear
boolean
default:"true"
When true, sets Environment.canvasHTML.onclick to a function that iterates all entries in Environment.figuras, tests each one with the internal detectarClickFigura utility using event.offsetX / event.offsetY, and calls Environment.clickListener(figura) for every figure whose bounds contain the click point. When false, replaces Environment.canvasHTML.onclick with an empty function, effectively disabling click detection without removing the property.
Returns: void
detectarClick reads Environment.canvasHTML to attach the handler. If you initialised the canvas with InitCanvasStatic (which does not set canvasHTML), you must assign Environment.canvasHTML manually before calling $g.DetectarClick(true).
Example:
$g.clickListener = function(figura) {
  figura.transform.relleno = '#00ff00'; // highlight on click
};
$g.DetectarClick(true);

// Later, disable click detection:
$g.DetectarClick(false);
See Guides: Click Events for a full walkthrough.

Step (internal — not on $g)

Step is the requestAnimationFrame callback that drives the loop. It is exported from motor.js but is not attached to $g by index.js.
function Step(timestamp) {
  if (!start) start = timestamp;
  Dibujar(false);
  requestId = window.requestAnimationFrame(Step);
}
Parameters:
timestamp
DOMHighResTimeStamp
The high-resolution timestamp provided by the browser’s requestAnimationFrame API. The first call captures it in the module-private start variable for potential elapsed-time calculations.
Returns: void Behaviour: Calls Dibujar(false) (draw + advance physics), then schedules itself again with requestAnimationFrame. The loop continues until DetenerAnimacion cancels the pending frame ID.
You should not need to call Step directly. Use $g.Animar to start the loop and $g.DetenerAnimacion to stop it.


Error (exported — not on $g)

motor.js exports a function named Error that simply throws the string "EXISTE UN ERROR". It is not attached to $g by index.js and is not part of the public Engine.js API. It exists in the module exports but has no practical use for consumers of the library.
function Error() {
  throw "EXISTE UN ERROR";
}

Internal Functions

These functions are defined inside motor.js but are not exported and are not accessible through $g. They are documented here to make the rendering and physics pipeline fully transparent.

Inicializar

Called once by IniciarAnimacion (and defensively by Dibujar on the first sinAvance = false call) to prepare the scene for simulation. Behaviour:
  1. Runs a forward-scan overlap-resolution pass over Environment.figuras. For each pair of figures that are already touching at rest, the outer figure is pushed to the right along the X axis to eliminate the initial overlap:
    • Against a 'circulo': pushed to figura.transform.x - (figura.transform.radio * 3).
    • Against a 'cuadrado' (outer is circle): pushed to (pivote.transform.x + pivote.transform.radio) + figura.transform.anchura.
    • Against a 'cuadrado' (outer is square): pushed to pivote.transform.x + figura.transform.anchura.
  2. Plays the HTMLAudioElement (src.play()) for every figure whose transform.sonido.activacion === 'inicial'.
The overlap resolution is a single forward pass (similar to one iteration of bubble sort on the X axis). It is not a full constraint solver; complex initial pile-ups may still require manual positioning.

calcularSiguientePaso

Advances the physics simulation by one tick. Called by Dibujar(false) after the draw pass. Behaviour:
  1. Clones Environment.figuras (via spread [...Environment.figuras]) and sorts the clone in descending Y order (highest Y value first). This ensures that figures lower on the canvas process collision responses before figures higher up, preventing tunnelling artefacts.
  2. For each figure in the sorted order:
    • Skips figures without a rigido component.
    • If rigido.sinColision is false (collision-enabled): calls figura.tocandoRigidos(). If no collision was detected (rigido.colision === false), calls figura.afectarGravedad() and figura.tocandoFondo().
    • If rigido.sinColision is true: calls only figura.afectarGravedad() (gravity without collision detection).
See Concepts: Physics and API: Rigido for details on how gravity and collision state are stored per figure.

DibujarSprite

Renders the current frame of an animated sprite sheet and advances the frame index based on elapsed wall-clock time. Called by: Dibujar, when figura.tipo === 'imagen' and figura.transform.imagen.sprite is set. Behaviour:
  1. Reads src (the HTMLImageElement) and sprite (the Sprite config object) from transform.imagen.
  2. Calculates the source X offset as sprite.anchura * sprite.frame.valor — each frame is sprite.anchura pixels wide on the sheet.
  3. Calls c.drawImage(src, frameX, sprite.altura * sprite.row, sprite.anchura, sprite.altura, transform.x, transform.y, sprite.anchura, sprite.altura) to blit the current frame onto the canvas.
  4. Checks whether sprite.velocidad * 1000 milliseconds have elapsed since sprite.frame.ultimo. If so, advances sprite.frame.valor by 1 modulo sprite.cols (looping back to frame 0 after the last column) and records the new timestamp in sprite.frame.ultimo.
See API: Sprite for the full shape of the sprite configuration object and Multimedia: Sprites for usage examples.

Build docs developers (and LLMs) love