Parallax 2D

Introducción

Parallax es un efecto que se utiliza para simular profundidad haciendo que las texturas se muevan a distintas velocidades en relación con la cámara. Godot proporciona el nodo Parallax2D para lograr este efecto. Sin embargo, puede ser fácil equivocarse, por lo que esta página proporciona descripciones detalladas de algunas propiedades y cómo solucionar algunos errores comunes.

Nota

This page covers how to use Parallax2D, which is recommended to use over the ParallaxLayer and ParallaxBackground nodes.

Empezar

El nodo de paralaje permite añadir nodos que renderizan elementos como hijos, lo que permite usar uno o varios nodos para conformar cada capa. Para empezar, coloca cada nodo o nodos que quieras que se desplacen de forma independiente como hijos de su propio nodo de paralaje. Asegúrate de que la esquina superior izquierda de las texturas utilizadas esté en el cruce (0, 0), como se muestra en la imagen a continuación. Consulta la sección sobre posicionamiento para saber por qué esto es importante.

../../_images/2d_parallax_size_viewport.webp

La escena de arriba utiliza una textura preparada para las nubes más altas en un Sprite2D, pero fácilmente podrías utilizar múltiples nodos espaciados para componer la capa.

Escala de desplazamiento

La columna vertebral del efecto de paralaje es la propiedad scroll_scale. Funciona como un multiplicador de velocidad de desplazamiento, lo que permite que las capas se muevan a una velocidad diferente a la de la cámara para cada eje establecido. Un valor de 1 hace que el nodo de paralaje se desplace a la misma velocidad que la cámara. Si deseas que tu imagen se vea más lejana al desplazarse, usa un valor menor que 1, y 0 la detendrá por completo. Si deseas que algo aparezca más cerca de la cámara, usa un valor mayor que 1, lo que hará que se desplace más rápido.

La escena anterior se compone de cinco capas. Algunos valores adecuados para scroll_scale podrían ser:

  • (0.7, 1) - Bosque

  • (0.5, 1) - Colinas

  • (0.3, 1) - Nubes Bajas

  • (0.2, 1) - Nubes Altas

  • (0.1, 1) - Cielo

El vídeo de abajo, muestra como esos valores afectan el desplazamiento en el juego:

Repetición infinita

Parallax2D proporciona un efecto adicional que da a las texturas la ilusión de repetirse infinitamente. repeat_size le dice al nodo que ajuste su posición hacia adelante o hacia atrás cuando la cámara se desplaza según el valor establecido. Este efecto se logra agregando una única repetición a todos los elementos del canvas(lienzo) secundario compensados por el valor. Mientras la cámara se desplaza entre la imagen y su repetición, retrocede de manera invisible dando la apariencia de una imagen en bucle.

../../_images/2d_parallax_scroll.gif

Al ser un efecto delicado, es fácil que usuarios que no estén familiarizados con el mismo cometan errores con su configuración. Repasemos el "cómo" y el "por qué" de algunos problemas comunes que encuentran los usuarios.

Tamaño insuficiente

Es más fácil trabajar con el efecto de repetición infinita cuando tienes una imagen diseñada para repetirse sin problemas y es del mismo tamaño o más grande que tu ventana gráfica antes de configurar el repeat_size. Si no puedes obtener recursos diseñados para esta tarea, hay otras cosas que puede hacer para preparar mejor su imagen en cuestión de tamaño.

Aquí hay un ejemplo de textura que es muy pequeña para su ventana:

../../_images/2d_parallax_size_bad.webp

Podemos ver que el tamaño de la ventana gráfica es 500x300 pero la textura es 288x208. Si configuramos repeat_size al tamaño de nuestra imagen, el efecto de repetición infinita no se desplaza correctamente porque la textura original no cubre la ventana gráfica. Si configuramos repeat_size según tamaño de la ventana gráfica, tenemos un hueco grande. ¿Qué podemos hacer?

Hacer la ventana gráfica más pequeña

The simplest answer is to make the viewport the same size or smaller than your textures. In Project Settings > Display > Window, change the Viewport Width and Viewport Height settings to match your background.

../../_images/2d_parallax_size_viewport.webp

Nivela el Parallax2D

If you're not aiming for a pixel-perfect style, or don't mind a little blurriness, you may opt to scale the textures larger to fit your screen. Set the scale of the Parallax2D, and all child textures scale with it.

Escala los modos hijo

Similar to scaling the Parallax2D, you can scale your Sprite2D nodes to be large enough to cover the screen. Keep in mind that some settings like Parallax2D.repeat_size and Sprite2D.region_rect do not take scaling into account, so it's necessary to adjust these values based on the scale.

../../_images/2d_parallax_size_scale.webp

Repetir las texturas

También puedes empezar con el pie derecho preparando los nodos secundarios en una etapa anterior del proceso. Si tienes un Sprite2D que te gustaría repetir, pero es demasiado pequeño, puedes hacer lo siguiente para repetirlo:

Debajo, puedes ver que repetir la imagen dos veces las hace lo suficientemente largas para cubrir la pantalla.

../../_images/2d_parallax_size_repeat.webp

Posicionado deficiente

Es común ver a los usuarios centrar erróneamente sus texturas en (0,0):

../../_images/2d_parallax_single_centered.webp

Esto crea problemas con el efecto de repetición infinita y se debe evitar. El "lienzo de repetición infinita" comienza en (0,0) y se expande hacia abajo y hacia la derecha hasta el tamaño del valor repeat_size.

../../_images/2d_parallax_single_expand.webp

Si las texturas están centradas en (0,0), cruzando el "canvas de repetición infinita" se cubre paracialmente, por lo que solo se repite parcialmente.

¿Incrementar repeat_times arreglaría esto?

Increasing repeat_times technically would work in some scenarios, but is a brute force solution and not the problem it is designed to solve (we'll go over this in a bit). A better fix is to understand how the repeat effect works and set up the parallax textures appropriately to begin with.

First, check to see if any textures are spilling over onto the negative parts of the canvas. Make sure the textures used in the parallax nodes fit inside the "infinite repeat canvas" starting at (0,0). That way, if Parallax2D.repeat_size is set correctly, it should look something like this, with one single loop of the image the same size or larger than the viewport:

../../_images/2d_parallax_repeat_good_norect.webp

Si piensas en cómo la imagen se desplaza a través de la pantalla, empieza mostrando lo que hay dentro del rectángulo rojo (determinado por la repeat_size) y cuando alcanza lo que hay dentro del rectángulo amarillo comprime la imagen delantera para dar la ilusión de un desplazarse eternamente.

../../_images/2d_parallax_repeat_good.webp

Si tienes la imagen posicionada lejos del "canvas de repetición infinito", cuando la cámara alcance el rectángulo amarillo, la mitad de la imagen se corta antes de saltar al a siguiente como en la imagen que se muestra abajo:

../../_images/2d_parallax_repeat_bad.webp

Desplazar offset

If your parallax textures are already working correctly, but you prefer it to start at a different point, Parallax2D comes with a scroll_offset property used to offset where the infinite repeat canvas starts. As an example, if your image is 288x208, setting the scroll_offset to (-144,0) or (144,0) allows it to begin halfway across the image.

Repetir tiempos

Ideally, following this guide, your parallax textures are large enough to cover the screen even when zoomed out. Until now, we have had a perfectly fitting 288x208 texture inside of a 288x208 viewport. However, problems occur when we zoom out by setting the Camera2D.zoom to (0.5, 0.5):

../../_images/2d_parallax_zoom_single.webp

Aunque todo está configurado correctamente para la ventana gráfica en el nivel de zoom predeterminado, al alejar la imagen, esta se hace más pequeña que la ventana gráfica, lo que rompe el efecto de repetición infinita. Aquí es donde repeat_times puede ayudar. Al configurar un valor de 3 (una repetición adicional por delante y por detrás), ahora es lo suficientemente grande como para acomodar el efecto de repetición infinita.

../../_images/2d_parallax_zoom_repeat_times.webp

Si estas texturas se hubieran tenido que repetir verticalmente, habríamos especificado un valor y para repeat_size. repeat_times también agregaría automáticamente una repetición arriba y abajo. Esto es solo un paralaje horizontal, por lo que deja un bloque vacío arriba y abajo de la imagen. ¿Cómo solucionamos esto? ¡Necesitamos ser creativos! En este ejemplo, estiramos el cielo más arriba y el sprite de hierba más abajo. Las texturas ahora admiten el nivel de zoom normal y la reducción a la mitad del tamaño.

../../_images/2d_parallax_zoom_repeat_adjusted.webp

Dividir la pantalla

La mayoría de los tutoriales para crear un juego de pantalla dividida en Godot comienzan escribiendo un pequeño script para asignar el Viewport.world_2d del primer SubViewport al segundo, de modo que compartan una pantalla. A menudo surgen preguntas sobre cómo compartir un efecto de paralaje entre ambas pantallas.

El efecto parallax (paralaje) simula una perspectiva moviendo las posiciones de diferentes textura en relación a la cámara. Esto es problemático si tienes múltiples cámaras, porque nuestras texturas ¡no pueden estar en dos lugares al mismo tiempo!

This is still achievable by cloning the parallax nodes into the second (or third or fourth) SubViewport. Here's how a setup looks for a two player game:

../../_images/2d_parallax_splitscreen.webp

Por supuesto, ahora ambos fondos se muestran en ambos SubViewports. Lo que queremos es que cada paralaje se muestre solo en su viewport correspondiente. Podemos lograrlo haciendo lo siguiente:

  • Leave all parallax nodes at their default visibility_layer of 1.

  • Set the first SubViewport's canvas_cull_mask to only layers 1 and 2.

  • Haz lo mismo para el segundo SubViewport pero utiliza las capas 1 y 3.

  • Give your parallax nodes in the first SubViewport a common parent and set its visibility_layer to 2.

  • Haz lo mismo para los nodos de paralaje del segundo SubViewport, pero utiliza una capa de 3.

¿Cómo funciona esto? Si un elemento del lienzo tiene una capa de visibilidad (visibility_layer) que no coincide con la máscara de lienzo (canvas_cull_mask) del SubViewport, se ocultarán todos los elementos secundarios, incluso si coinciden. Esto nos beneficia, permitiendo que las subvistas bloqueen la representación de los nodos de paralaje cuyo elemento principal no tenga una capa de visibilidad (visibility_layer) compatible.

Vista previa en el editor

Antes de la 4.3, la recomendación era colocar cada capa en su propio ParallaxBackground, activar la propiedad follow_viewport_enabled, y escalar la capa individual. Este método siempre ha sido difícil de conseguir, pero todavía se puede lograr mediante el uso de un CanvasLayer en lugar de un ParallaxBackground.

Nota

Otra recomendación es el addon KoBeWi's "Parallax2D Preview". Provee unos cuantos modos de vista previos distintos ¡y es muy práctico!