This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
El componente proxy de colección (collection proxy) se usa para cargar y descargar dinámicamente nuevos “mundos” de juego basados en el contenido de un archivo de colección. Se puede usar para implementar el cambio entre niveles del juego, pantallas GUI, carga y descarga de “escenas” narrativas durante un nivel, carga/descarga de mini-juegos y más.
Defold organiza todos los objetos de juego en colecciones. Una colección puede contener objetos de juego y otras colecciones (es decir, sub-colecciones). Los proxies de colección te permiten dividir tu contenido en colecciones separadas y luego gestionar dinámicamente la carga y descarga de esas colecciones mediante scripts.
Los proxies de colección son distintos de los componentes factory de colección. Una factory de colección instancia el contenido de una colección en el mundo de juego actual. Los proxies de colección crean un nuevo mundo de juego en runtime y, por lo tanto, tienen casos de uso distintos.
Agrega un componente proxy de colección a un objeto de juego haciendo click derecho en un objeto de juego y seleccionando Add Component ▸ Collection Proxy en el menú contextual.
Define la propiedad Collection para que referencie una colección que quieras cargar dinámicamente en el runtime más adelante. La referencia es estática y asegura que todo el contenido de la colección referenciada termine en el juego final.

(Puedes excluir el contenido de la build y descargarlo con código en su lugar marcando la casilla Exclude y usando la funcionalidad Live update.)
Cuando el motor Defold se inicia, carga e instancia en el runtime todos los objetos de juego de una colección bootstrap. Luego inicializa y habilita los objetos de juego y sus componentes. La colección bootstrap que debe usar el motor se configura en la configuración del proyecto. Por convención, este archivo de colección suele llamarse “main.collection”.

Para alojar los objetos de juego y sus componentes, el motor asigna la memoria necesaria para todo el “mundo de juego” en el que se instancia el contenido de la colección bootstrap. También se crea un mundo físico separado para cualquier objeto de colisión y simulación física.
Como los componentes script deben poder direccionar todos los objetos del juego, incluso desde fuera del mundo bootstrap, a ese mundo se le asigna un nombre único: la propiedad Name que defines en el archivo de colección:

Si la colección que se carga contiene componentes proxy de colección, las colecciones a las que hacen referencia no se cargan automáticamente. Debes controlar la carga de estos recursos mediante scripts.
Para cargar dinámicamente una colección mediante un proxy, envía un mensaje llamado "load" al componente proxy desde un script:
-- Indica al proxy "myproxy" que empiece a cargar.
msg.post("#myproxy", "load")

El componente proxy le indicará al motor que asigne espacio para un nuevo mundo. También se crea un mundo físico de runtime separado y se instancian todos los objetos de juego de la colección “mylevel.collection”.
El nuevo mundo obtiene su nombre de la propiedad Name en el archivo de colección; en este ejemplo está definida como “mylevel”. El nombre debe ser único. Si el Name definido en el archivo de colección ya se usa para un mundo cargado, el motor señalará un error de colisión de nombres:
ERROR:GAMEOBJECT: The collection 'default' could not be created since there is already a socket with the same name.
WARNING:RESOURCE: Unable to create resource: build/default/mylevel.collectionc
ERROR:GAMESYS: The collection /mylevel.collectionc could not be loaded.
Cuando el motor termina de cargar la colección, el componente proxy de colección envía un mensaje llamado "proxy_loaded" al script que envió el mensaje "load". Entonces el script puede inicializar y habilitar la colección como reacción al mensaje:
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_loaded") then
-- El nuevo mundo está cargado. Inicialízalo y habilítalo.
msg.post(sender, "init")
msg.post(sender, "enable")
...
end
end
"load""proxy_loaded" cuando termine."async_load""proxy_loaded" cuando termine."init"init() de los scripts."enable"La propiedad Name definida en las propiedades del archivo de colección se usa para direccionar objetos de juego y componentes en el mundo cargado. Por ejemplo, si creas un objeto cargador en la colección bootstrap, puede que necesites comunicarte con él desde cualquier colección cargada:
-- indica al cargador que cargue el siguiente nivel:
msg.post("main:/loader#script", "load_level", { level_id = 2 })

Y si necesitas comunicarte con un objeto de juego de la colección cargada desde el cargador, puedes enviar un mensaje usando la URL completa al objeto:
msg.post("mylevel:/myobject", "hello")
No es posible acceder directamente a objetos de juego de una colección cargada desde fuera de esa colección:
local position = go.get_position("mylevel:/myobject")
-- loader.script:42: function called can only access instances within the same collection.
Para descargar una colección cargada, envía mensajes correspondientes a los pasos inversos de la carga:
-- descarga el nivel
msg.post("#myproxy", "disable")
msg.post("#myproxy", "final")
msg.post("#myproxy", "unload")
"disable""final"final() de los scripts."unload"Si no necesitas un control más granular, puedes enviar el mensaje "unload" directamente, sin deshabilitar ni finalizar primero la colección. Entonces el proxy deshabilitará y finalizará automáticamente la colección antes de descargarla.
Cuando el proxy de colección haya terminado de descargar la colección, enviará un mensaje "proxy_unloaded" al script que envió el mensaje "unload":
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_unloaded") then
-- Ok, el mundo está descargado...
...
end
end
Las actualizaciones de un proxy de colección pueden escalarse alterando el time step (paso de tiempo). Esto significa que, aunque el juego avance a 60 FPS constantes, un proxy puede actualizarse a un ritmo mayor o menor, lo que afecta a cosas como:
dt pasado a update()También puedes establecer el modo de actualización, que te permite controlar si el escalado debe realizarse de forma discreta (lo que solo tiene sentido con un factor de escala por debajo de 1.0) o continua.
Controlas el factor de escala y el modo de escalado enviando al proxy un mensaje set_time_step:
-- actualiza el mundo cargado a un quinto de la velocidad.
msg.post("#myproxy", "set_time_step", {factor = 0.2, mode = 1}
Para ver qué ocurre al cambiar el paso de tiempo, podemos crear un objeto con el siguiente código en un componente script y ponerlo en la colección cuyo paso de tiempo estamos modificando:
function update(self, dt)
print("update() with timestep (dt) " .. dt)
end
Con un paso de tiempo de 0.2, obtenemos el siguiente resultado en la consola:
INFO:DLIB: SSDP started (ssdp://192.168.0.102:54967, http://0.0.0.0:62162)
INFO:ENGINE: Defold Engine 1.2.37 (6b3ae27)
INFO:ENGINE: Loading data from: build/default
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0.016666667535901
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0
DEBUG:SCRIPT: update() with timestep (dt) 0.016666667535901
update() se sigue llamando 60 veces por segundo, pero el valor de dt cambia. Vemos que solo 1/5 (0.2) de las llamadas a update() tendrán un dt de 1/60 (correspondiente a 60 FPS); el resto es cero. Todas las simulaciones de física también se actualizarán de acuerdo con ese dt y avanzarán solo en uno de cada cinco frames.
Puedes usar la funcionalidad de paso de tiempo de colecciones para pausar tu juego, por ejemplo mientras muestras un popup o cuando la ventana ha perdido el foco. Usa msg.post("#myproxy", "set_time_step", {factor = 0, mode = 0}) para pausar y msg.post("#myproxy", "set_time_step", {factor = 1, mode = 1}) para reanudar.
Consulta set_time_step para más detalles.