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
O componente de proxy de coleção é usado para carregar e descarregar dinamicamente novos “mundos” de jogo com base no conteúdo de um arquivo de coleção. Eles podem ser usados para implementar alternância entre fases do jogo, telas de GUI, carregamento e descarregamento de “cenas” narrativas ao longo de uma fase, carregamento/descarregamento de minijogos e mais.
O Defold organiza todos os objetos de jogo em coleções. Uma coleção pode conter objetos de jogo e outras coleções (isto é, subcoleções). Proxies de coleção permitem dividir seu conteúdo em coleções separadas e então gerenciar dinamicamente o carregamento e descarregamento dessas coleções por script.
Proxies de coleção diferem de componentes de fábrica de coleção. Uma fábrica de coleção instancia o conteúdo de uma coleção no mundo de jogo atual. Proxies de coleção criam um novo mundo de jogo em runtime e, portanto, têm casos de uso diferentes.
Adicione um componente de proxy de coleção a um objeto de jogo usando right-click em um objeto de jogo e selecionando Add Component ▸ Collection Proxy no menu de contexto.
Defina a propriedade Collection para referenciar uma coleção que você deseja carregar dinamicamente no runtime em um momento posterior. A referência é estática e garante que todo o conteúdo da coleção referenciada acabe no jogo final.

(Você pode excluir o conteúdo do build e baixá-lo com código em vez disso marcando a caixa Exclude e usando o recurso Live Update.)
Quando a engine Defold inicia, ela carrega e instancia todos os objetos de jogo de uma coleção bootstrap no runtime. Em seguida, inicializa e ativa os objetos de jogo e seus componentes. Qual coleção bootstrap a engine deve usar é definido nas configurações do projeto. Por convenção, esse arquivo de coleção normalmente se chama “main.collection”.

Para acomodar os objetos de jogo e seus componentes, a engine aloca a memória necessária para todo o “mundo de jogo” no qual o conteúdo da coleção bootstrap é instanciado. Um mundo de física separado também é criado para quaisquer objetos de colisão e simulação de física.
Como componentes de script precisam poder endereçar todos os objetos do jogo, mesmo de fora do mundo bootstrap, ele recebe um nome único: a propriedade Name que você define no arquivo de coleção:

Se a coleção carregada contiver componentes de proxy de coleção, as coleções às quais eles se referem não são carregadas automaticamente. Você precisa controlar o carregamento desses recursos por scripts.
O carregamento dinâmico de uma coleção por proxy é feito enviando uma mensagem chamada "load" ao componente proxy a partir de um script:
-- Diz ao proxy "myproxy" para iniciar o carregamento.
msg.post("#myproxy", "load")

O componente proxy instruirá a engine a alocar espaço para um novo mundo. Um mundo de física de runtime separado também é criado, e todos os objetos de jogo na coleção “mylevel.collection” são instanciados.
O novo mundo recebe seu nome da propriedade Name no arquivo de coleção; neste exemplo, ela está definida como “mylevel”. O nome precisa ser único. Se o Name definido no arquivo de coleção já estiver em uso por um mundo carregado, a engine sinalizará um erro de colisão de nomes:
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.
Quando a engine terminar de carregar a coleção, o componente de proxy de coleção enviará uma mensagem chamada "proxy_loaded" de volta ao script que enviou a mensagem "load". O script pode então inicializar e ativar a coleção em reação à mensagem:
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_loaded") then
-- Novo mundo carregado. Inicialize e ative-o.
msg.post(sender, "init")
msg.post(sender, "enable")
...
end
end
"load""proxy_loaded" quando terminar."async_load""proxy_loaded" quando terminar."init"init() de script são chamadas nesta etapa."enable"O Name definido nas propriedades do arquivo de coleção é usado para endereçar objetos de jogo e componentes no mundo carregado. Se, por exemplo, você criar um objeto loader na coleção bootstrap, talvez precise se comunicar com ele a partir de qualquer coleção carregada:
-- diz ao loader para carregar a próxima fase:
msg.post("main:/loader#script", "load_level", { level_id = 2 })

E, se você precisar se comunicar com um objeto de jogo na coleção carregada a partir do loader, pode enviar uma mensagem usando a URL completa para o objeto:
msg.post("mylevel:/myobject", "hello")
Não é possível acessar diretamente objetos de jogo em uma coleção carregada a partir de fora da coleção:
local position = go.get_position("mylevel:/myobject")
-- loader.script:42: function called can only access instances within the same collection.
Para descarregar uma coleção carregada, envie mensagens correspondentes às etapas inversas do carregamento:
-- descarrega a fase
msg.post("#myproxy", "disable")
msg.post("#myproxy", "final")
msg.post("#myproxy", "unload")
"disable""final"final() dos scripts são chamadas nesta etapa."unload"Se você não precisa desse controle mais granular, pode enviar a mensagem "unload" diretamente, sem antes desativar e finalizar a coleção. O proxy então desativará e finalizará automaticamente a coleção antes de descarregá-la.
Quando o proxy de coleção terminar de descarregar a coleção, ele enviará uma mensagem "proxy_unloaded" de volta ao script que enviou a mensagem "unload":
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_unloaded") then
-- Ok, o mundo foi descarregado...
...
end
end
Atualizações de proxy de coleção podem ser escaladas alterando o passo de tempo. Isso significa que, embora o jogo atualize em um ritmo constante de 60 FPS, um proxy pode atualizar em um ritmo maior ou menor, afetando coisas como:
dt passado para update()Você também pode definir o modo de atualização, que permite controlar se a escala deve ser realizada discretamente (o que só faz sentido com um fator de escala abaixo de 1.0) ou continuamente.
Você controla o fator de escala e o modo de escala enviando ao proxy uma mensagem set_time_step:
-- atualiza o mundo carregado a um quinto da velocidade.
msg.post("#myproxy", "set_time_step", {factor = 0.2, mode = 1}
Para ver o que acontece ao mudar o passo de tempo, podemos criar um objeto com o seguinte código em um componente de script e colocá-lo na coleção cujo timestep estamos alterando:
function update(self, dt)
print("update() with timestep (dt) " .. dt)
end
Com um passo de tempo de 0.2, obtemos o seguinte resultado no console:
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() ainda é chamado 60 vezes por segundo, mas o valor de dt muda. Vemos que apenas 1/5 (0.2) das chamadas a update() terão um dt de 1/60 (correspondente a 60 FPS)—o restante é zero. Todas as simulações de física também serão atualizadas de acordo com esse dt e avançarão apenas em um quinto dos frames.
Você pode usar a funcionalidade de passo de tempo da coleção para pausar seu jogo, por exemplo enquanto mostra um popup ou quando a janela perdeu o foco. Use msg.post("#myproxy", "set_time_step", {factor = 0, mode = 0}) para pausar e msg.post("#myproxy", "set_time_step", {factor = 1, mode = 1}) para retomar.
Veja set_time_step para mais detalhes.