Saltar al contenido principal

Objetos

Los objetos son lo que colocas a mano en una capa de objetos:

  • Sprites del proyecto (.spr): el jugador, los enemigos, las monedas.
  • Imágenes: en el juego son sprites de un solo fotograma.
  • Formas: rectángulos, elipses y líneas que el juego pinta.
  • Zonas: rectángulos que no se ven y que vigilan las reglas.
  • Rutas: caminos para el comportamiento Follow route.

Cada objeto se ajusta en la sección INSTANCE de la pestaña Object. Lo que hace en el juego sin escribir código lo cuentan Comportamientos y Reglas y estados.

El inspector del objeto hero: su cuerpo Dynamic y su collider

Colocar objetos​

Los sprites y las imágenes se colocan desde la paleta ASSETS, debajo del lienzo, con una capa de objetos activa:

  1. Haz clic en un sprite o una imagen de la paleta.
  2. Elige Place (2) y haz clic en el lienzo. Antes del clic, un fantasma enseña dónde va a caer.

También puedes arrastrarlo de la paleta al lienzo, o hacer doble clic en él: entonces va al centro de lo que estás viendo. Lo que colocas queda elegido.

Con View › Snap to the grid encendido, el objeto se ajusta a la celda: su recuadro queda alineado con la rejilla de Room › Snap (px), y su pivote, dentro de la celda donde has hecho clic. Al arrastrar un objeto pasa lo mismo, y Alt suelta el ajuste mientras arrastras.

Con Place, un clic sobre un objeto del mismo recurso lo elige, en vez de poner otro encima. Para apilar dos iguales, arrastra el segundo desde la paleta.

Lo que colocas hereda del último objeto del mismo recurso su etiqueta, su cuerpo, su física (salvo Velocity y Spin / Ang. vel.), Keep in room y sus comportamientos. El nombre, el sitio, los estados y el código son de cada uno. El nombre sale del recurso: Hero.spr da hero, y los siguientes, hero2, hero3…

Para mover lo elegido, arrástralo con Select (1) o usa las flechas: un paso de la rejilla, o un píxel con Shift. Con Ctrl pulsado mientras arrastras, mueves una copia. Elegir varios, copiar, alinear y lo demás del lienzo lo cuenta Editor de escenas; el orden de dibujo, Capas.

El inspector (INSTANCE)​

Con un objeto elegido, INSTANCE enseña sus campos. Arriba dice qué es y de qué recurso: sprite - Hero.spr, image - Rock.bmp, shape, marker (una zona) o route - 4 nodes, 380 px.

  • Las casillas de texto se aplican al pulsar Intro o al salir de ellas. Lo que no es un número deja el valor como estaba, y lo que se pasa de sus límites se recorta: una masa de 0 vuelve a 1, un rozamiento de 3 se queda en 1. Los decimales, con punto o con coma.
  • Con varios objetos elegidos, la ficha enseña el principal: el último que elegiste. Tag, Body, Group, Passes y Use sprite collider se aplican a todos, y Position los mueve a todos lo mismo. Lo demás va solo al principal. Name se apaga, porque tiene que ser único.
  • Lo que un tipo de objeto no tiene sale apagado o no sale. Una forma, una zona o una ruta no tienen las filas del cuerpo, del giro ni del volteo.

Nombre, etiqueta y posición​

  • Name: el nombre con el que el juego lo encuentra (room.named["hero"]) y al que apuntan otros objetos y las reglas. Tiene que ser único en la sala. Si lo cambias, lo que lo nombraba pasa al nombre nuevo. Un objeto sin nombre no está en room.named, y en el árbol sale como (unnamed).
  • Tag: su clase: enemy, coin, bullet. Las reglas trabajan con etiquetas. Las mayúsculas cuentan: Enemy y enemy son dos etiquetas distintas. Si cambias una etiqueta y ya no la lleva nadie, las reglas que la nombraban pasan a la nueva.
  • Position: en píxeles de la sala.
    • En un sprite es su pivote, el centro salvo que su .spr diga otro: lo mismo que valdrán sprite.x y sprite.y en el juego. La casilla se llama entonces Position (pivot).
    • En lo demás es la esquina de arriba a la izquierda: Position (corner). Una imagen entra en el juego como un sprite con el pivote en el centro, así que allí su x es esa esquina más medio ancho.
  • Size (px): solo en formas y zonas. Los sprites y las imágenes salen a su tamaño, porque la VM no los escala.
  • Angle / Frame: la primera casilla es el giro, en grados, de 0 a 360 y en el sentido de las agujas del reloj. Solo en sprites e imágenes. En el lienzo se gira con su tirador; con Shift, de 15 en 15 grados.

Flip y fotograma de inicio​

  • Flip X y Flip Y, o las teclas H y V, voltean el sprite o la imagen en horizontal y en vertical.
  • La segunda casilla de Angle / Frame es el fotograma de la hoja con el que empieza el sprite. Con 0, se anima como diga su .spr. Con otro, se queda quieto en ese fotograma: la sala le pone frameRate a 0. Para animarlo desde ahí, usa el comportamiento Animation.

El cuerpo​

Body dice cómo trata la física al objeto. Es el bodyType del sprite (módulo Sprite).

BodyEn el juego
VisualSin cuerpo: no cae ni choca con nada.
DynamicCae con la gravedad de la sala y choca con los demás cuerpos. <Sala>Resolve lo saca de las celdas sólidas del mapa de colisión.
StaticNo se mueve nunca, y los demás cuerpos chocan con él: un suelo o una pared hechos con sprites.
KinematicNo cae. Se mueve con su velocidad, la de Velocity o la que le den un comportamiento o tu código, y los dinámicos chocan con él. El mapa de colisión no lo para.
  • Los cuerpos necesitan la física de la sala (Room › PHYSICS › Enabled). Sin ella, nada cae y la velocidad no mueve nada.
  • En una sala con física, un comportamiento que mueve por velocidad solo mueve cuerpos Dynamic o Kinematic. Con Visual o Static el objeto se queda quieto, y el panel de problemas lo avisa (Comportamientos).
  • Las reglas que miran si dos objetos se tocan funcionan con cualquier cuerpo: miran si se solapan.

La física del cuerpo​

Debajo de Body van los números del cuerpo. Cada uno sale encendido solo con los cuerpos que lo usan: con otro cuerpo se guarda, pero no llega al juego.

CampoCuerposQué hace
Fixed rotationDynamicLos choques no lo inclinan (sprite.rotates a false). Apagado, puede volcar y rodar.
Continuous collisionDynamicBarre cada paso entero, para que un cuerpo rápido no atraviese a otro (sprite.bullet). Las reglas de contacto no ven sus choques: el panel de problemas lo avisa.
MassDynamicLo que pesa en un choque (sprite.mass). De serie, 1.
Fric. / BounceDynamic, Static, KinematicRozamiento y rebote, de 0 a 1 (sprite.friction y sprite.elasticity). Un contacto usa la media de los dos cuerpos. De serie, 0 (resbala sin parar) y 0.5 (devuelve la mitad de la velocidad).
Gravity scaleDynamicCuánta gravedad de la sala recibe (sprite.gravityScale): 1 toda, 0 nada (flota) y, negativa, hacia arriba.
Damp. / Ang.DynamicLo frenan solos, al avanzar y al girar (sprite.damping y sprite.angularDamping). Con 0 no frenan; con 2, se para en un segundo, más o menos.
Group / PassesDynamic, Static, KinematicSu grupo de colisión, de 1 a 16, y los grupos que atraviesa, como 2,5 o all. Passes vacío choca con todos.
Velocity (px/s)Dynamic, KinematicLa velocidad con la que empieza, en píxeles por segundo (sprite.vx y sprite.vy). Un Kinematic la mantiene; un Dynamic sale con ella.
Spin / Ang. vel.Spin: todos. Ang. vel.: Dynamic, KinematicEn grados por segundo. Spin (sprite.spin) gira el dibujo. Ang. vel. (sprite.angularVel) gira el cuerpo: un Kinematic la mantiene y un Dynamic sale con ella. Como mucho, ±720.
Keep in roomTodos<Sala>Resolve no deja que el sprite salga de la sala por ninguno de sus cuatro lados.
  • Gravity scale y Velocity no hacen nada con Linear motion, Patrol, Follow / flee o Top-down control: esos comportamientos ponen la velocidad ellos.
  • Group / Passes solo filtra los choques entre cuerpos. Dos cuerpos chocan si cada uno acepta el grupo del otro. Las reglas y el mapa de colisión no lo miran. En el código van en bits (sprite.category y sprite.collideWith): el grupo 1 vale 1; el 2, 2; el 3, 4, y así.

Todo esto lo explica el módulo Sprite.

El collider​

El collider es la caja, o el círculo, con la que choca el objeto. Es del sprite: se dibuja en el editor de sprites, y la sala usa ese. Solo cuenta en los objetos con cuerpo, o con hits().

La fila Collider dice cuál lleva, en píxeles del fotograma (Rect 2, 2 12 x 14 o Circle 12, 12 r 10), y debajo, de dónde sale:

  • From the sprite. Change it in the Sprite editor: es el que dibujaste en el sprite.
  • Whole frame: the sprite does not set one: el sprite no tiene collider, y la caja es el fotograma entero.
  • The whole image. Make it a sprite to fit it: una imagen choca con la imagen entera. Para ajustarlo, haz un sprite con ella.

Las salas hechas con una versión anterior del editor pueden tener objetos con su propia caja: la fila dice Own rect …, y el juego la usa. Use sprite collider la quita, y el objeto pasa a usar la de su sprite.

View › Colliders pinta los colliders en el lienzo.

Formas y zonas​

Shape (3) y Zone (4) dibujan un rectángulo en la capa de objetos activa: arrastra de una esquina a la otra. Un clic sin arrastrar hace uno del tamaño de un tile (Room › Tile size). Con View › Snap to the grid, las esquinas van a la rejilla. Nacen con los nombres shape, zone, zone2…

Se estiran con sus tiradores, y Size (px) les da el tamaño exacto. No giran, no se voltean y no tienen cuerpo: no chocan con nada.

Una zona elegida en el lienzo, con sus tiradores y sus datos en INSTANCE

Formas​

  • Shape elige la forma: Rect, Ellipse (la elipse que cabe en la caja; con una caja cuadrada, un círculo) o Line (de la esquina de arriba a la izquierda a la de abajo a la derecha).
  • El cuadrado de color le cambia el color, y Filled la rellena.
  • En el juego, <Sala>Draw las pinta con Draw.rect, Draw.ellipse y Draw.line, en el sitio de su capa en la pila (el orden de dibujo). Una forma oculta con su ojo no se pinta.

Zonas​

Una zona no se ve en el juego. Marca un sitio de la sala, como la salida o un foso, para que lo vigilen:

  • la regla When it enters a zone (Reglas y estados);
  • el campo Inside zone del comportamiento Spawner y de la acción Create from a template: las copias salen dentro de la zona.

En esos campos valen también las formas. La ficha llama marker a las zonas.

Show in game hace que el juego pinte la zona como un rectángulo de su color, para que el jugador vea dónde está la salida. Con ella encendida, el cuadrado de color y Filled se encienden.

Formas y zonas en el código​

La sala deja sus formas y sus zonas en una tabla, <SALA>_ZONES, con una fila por cada una: [name, tag, kind, shape, x, y, w, h, color, filled]. <Sala>Zone(nombre) busca una por su nombre y devuelve su fila, o nil. Las dos solo se escriben si tu código las nombra: al compilar después de nombrarlas, aparecen.

// La zona "salida" de la sala Level1, desde el código del juego
var salida = Level1Zone("salida")
if (salida != nil) then
// [name, tag, kind, shape, x, y, w, h, color, filled]
println(salida[4]) // su x
end

Rutas​

Path (6) dibuja una ruta: una línea quebrada, nodo a nodo, que recorre el comportamiento Follow route (Comportamientos).

  • Cada clic añade un nodo. Un clic sobre un tramo mete uno en medio, y arrastrar mueve un nodo.
  • Supr quita el nodo que tiene el ratón encima, o el último. Esc, Intro o un doble clic terminan la ruta.
  • Con Select, los nodos de la ruta elegida se mueven igual. El clic derecho trae Delete this route node y Reverse the route, y las teclas H y V la reflejan.
  • Nacen con los nombres route, route2…

Una ruta es un dato: no se ve en el juego, ni lleva cuerpo ni comportamientos. Follow route la busca por su etiqueta, así que dale una en Tag. Una ruta oculta con su ojo no cuenta. La ficha dice cuántos nodos tiene y cuánto mide, para calcular lo que tarda con su velocidad.

Si no hay ninguna ruta con esa etiqueta, valen como ruta las zonas y las formas que la llevan: se recorren por su centro, en el orden de sus nombres (zona2 antes que zona10).

Propiedades​

PROPERTIES guarda datos tuyos en el objeto: pares de nombre y valor, como vida = 3 o llave = roja. El editor no las usa: son para tu código.

  • Add pide el nombre de la propiedad y la crea con el valor 0. El valor se cambia en la columna Value.
  • Remove quita la propiedad elegida.
  • El nombre no se cambia en la rejilla: quita la propiedad y créala otra vez.

Cada valor llega al juego con su tipo:

Si el valor es…Llega como
true o falseun booleano
nilnil
un número, con punto decimal: 3, 0.5un número
cualquier otra cosa: roja, 0,5un texto

Las propiedades llegan al juego por tres sitios:

  • Al código del objeto, como props (ver «El código de cada objeto»).
  • A la función spawn(e) que puedes pasar a <Sala>Load, como e.props.
  • A la tabla de la sala, <SALA>_ENTITIES, en el campo props de la fila de cada objeto. La fila de un objeto con nombre la da la constante <SALA>_I_<NOMBRE>, que se escribe si tu código la nombra.

Un objeto sin propiedades tiene props a nil.

// La propiedad "llave" del objeto "puerta" de la sala Level1
var fila = LEVEL1_ENTITIES[LEVEL1_I_PUERTA]
if (fila.props != nil) then
if (fila.props.contains("llave")) then
println(fila.props["llave"]) // roja
end
end

Plantillas​

Una plantilla es un objeto guardado sin posición. El juego hace copias de ella mientras se juega:

Se manejan en el bloque TEMPLATES, al final de INSTANCE:

  • Make template (From object) hace una plantilla con el objeto elegido. Solo un sprite puede ser plantilla. Se llama como el objeto; si no tiene nombre, como su etiqueta, y si tampoco, Template.
  • Template elige una de las plantillas de la sala, y Remove la borra.
  • Name la renombra. Los spawners y las acciones que la usaban la siguen.
  • Debajo dice qué lleva, como sprite, 2 component(s), tag "coin", with code.

Las plantillas también salen en el árbol, en el grupo TEMPLATES. Viven dentro de la sala: para usar una en otra sala, copia allí el objeto y haz la plantilla otra vez.

Cada copia lleva todo lo de la plantilla: su sprite, su cuerpo y su física, su etiqueta, sus comportamientos, sus estados y su código. Sale donde diga quien la crea, y sin nombre: no está en room.named. Sus propiedades solo le llegan a su código, como props: si la plantilla tiene propiedades pero no código, el panel de problemas lo avisa.

Poner al día una plantilla

La plantilla es una foto del objeto en ese momento: si después cambias el objeto, la plantilla no cambia. Para ponerla al día, bórrala con Remove y vuelve a hacerla desde el objeto. Si se llama igual, los spawners y las acciones que la usaban la vuelven a encontrar.

El código de cada objeto​

CODE › Edit code... abre la ventana Object code, con el código JARU del objeto elegido. Solo lo llevan los sprites y las imágenes, y no los de una capa de decorado.

Lo que escribes ahí es el cuerpo de una función: líneas de JARU que pueden usar tres nombres.

  • spr: el sprite del objeto.
  • room: la sala, con los demás objetos en room.named.
  • props: sus PROPERTIES, o nil si no tiene.

Se ejecuta una vez, al cargar la sala: cuando ya están creados todos sus objetos y puestos sus comportamientos, y antes de que el objeto entre en su primer estado. También en cada copia de una plantilla hecha con el objeto. Va antes que el código de creación de la sala (La sala y el juego). Los objetos con el mismo código comparten una sola función en el .gen.aru.

// El mismo código en tres enemigos Kinematic, en una sala con física.
// Cada uno lleva en PROPERTIES su "velocidad": 40, 60, 80
var velocidad = 40
if (props != nil) then
if (props.contains("velocidad")) then
velocidad = props["velocidad"]
end
end
// Hacia el jugador, si está en la sala
if (room.named.contains("heroe")) then
var heroe = room.named["heroe"]
if (heroe.x < spr.x) then
velocidad = 0 - velocidad
spr.flipX = true
end
end
spr.vx = velocidad

La ventana se edita como el editor de código del IDE: colores, autocompletado, la firma de lo que llamas, Ctrl + clic para ir a una definición y los errores subrayados. La línea de abajo dice el error de donde está el cursor. room. propone los campos de la sala tal como estaban la última vez que se generó: si no se ha generado nunca, no propone nada.

La ventana sigue al objeto que elijas. Lo escrito pasa a la sala al salir de la ventana o al cerrarla con Close, y entra en el deshacer. Debajo de Edit code..., la ficha dice cuántas líneas tiene el código del objeto.

En estas salas, active = false es destruir

En una sala con comportamientos, estados, reglas, plantillas, variables o código, <Sala>Update saca de la escena, al final de cada fotograma, los sprites que tienen active a false. Volver a ponerlo a true no los devuelve. Si un objeto tiene que volver a salir, haz una plantilla con él y crea una copia cuando haga falta.

Problemas conocidos​

  • Position no admite negativos. Un objeto arrastrado a la izquierda o arriba de la sala enseña 0 en Position, y si cambias el otro eje en la casilla, el objeto salta al 0. Muévelo con el ratón o con las flechas.
  • PROPERTIES no entra bien en el deshacer. Cambiar un valor en la rejilla no deja un paso: Ctrl+Z deshace lo de antes. Y Add con el nombre de una propiedad que ya existe la pone a 0 sin avisar. Para cambiar un valor, edítalo en la columna Value.
  • Body no cambia en una imagen. En una imagen colocada, Body vuelve a Visual al elegir otro cuerpo, así que una imagen no puede ser una plataforma. Haz un sprite con la imagen y coloca el sprite.
  • Las comillas dobles llegan con una barra. Una " en el nombre de un objeto, en una propiedad o en un texto llega al juego con una barra delante: Jefe "malo" llega como Jefe \"malo\". No uses comillas dobles ahí.
  • Las plantillas solo se manejan con un objeto elegido. Sin nada elegido, el bloque TEMPLATES está apagado, y sus filas del árbol no hacen nada. Para ver, renombrar o borrar una plantilla, elige antes cualquier objeto.
  • Los nombres de las copias. Al duplicar o pegar enemy2, la copia se llama enemy22, no enemy3. Si numeras los objetos, renombra la copia.
  • El rótulo de varios elegidos se queda corto. Con varios objetos elegidos, la ficha dice tag, body, group go to all, pero Position y Use sprite collider también se aplican a todos.