🤔 Para Refletir :
"Mais vale um jogo publicado que um jogo perfeito que não sai do projeto."
- HenriqueGibi

Fluxo e Tempo de Execução

DadoCWB Masculino

Duque
Membro
Membro
"Esto no me gusta"
Juntou-se
02 de Setembro de 2018
Postagens
724
Bravecoins
1.826
Tenho o seguinte problema:

Meu herói está no mapa 1.
Por meio de script, eu com duas linhas de códigos (1) teleporto o herói para o mapa 2 e desejo que a primeira $gameVariable receba o valor do mapa para o qual o herói foi teleportado:

$gamePlayer.reserveTransfer (2, 5, 5, 2, 1);
$gameVariables.setValue(1,$gameMap.mapId());

O que acontece é que quando eu vou olhar a $gameVariable, ela apresenta como valor, a ID do PRIMEIRO mapa (mapId=1);


Ao que andei lendo o javascript realiza um tipo de execução simultânea ao invés do tradicional "linha por linha". Mas como eu posso transferir o herói e pegar o mapId do novo mapa? 
 
DadoCWB comentou:
Tenho o seguinte problema:

Meu herói está no mapa 1.
Por meio de script, eu com duas linhas de códigos (1) teleporto o herói para o mapa 2 e desejo que a primeira $gameVariable receba o valor do mapa para o qual o herói foi teleportado:

$gamePlayer.reserveTransfer (2, 5, 5, 2, 1);
$gameVariables.setValue(1,$gameMap.mapId());

O que acontece é que quando eu vou olhar a $gameVariable, ela apresenta como valor, a ID do PRIMEIRO mapa (mapId=1);


Ao que andei lendo o javascript realiza um tipo de execução simultânea ao invés do tradicional "linha por linha". Mas como eu posso transferir o herói e pegar o mapId do novo mapa?
Tudo bom? o que acontece é que o jogador não é teleportado assim de imediato, pois existe algumas condições a serem analisadas primeiro, logo o id do mapa não muda de imediato. O código abaixo resolve o seu problema  :Okay_fix:
Código:
const _game_map_setup = Game_Map.prototype.setup;
Game_Map.prototype.setup = function(mapId) {
_game_map_setup.apply(this, arguments);
$gameVariables.setValue(1, mapId);
};
 
^^

Mais uma vez obrigado. Tu realmente manja desse negócio sr. Xamã.
No entanto eu gostaria de uma solução que não precisasse alterar as funções padrões. Eu gostaria de algo mais assim:

após transferir o heroi
  atribua o valor a $gameVariable


Tomando por exemplo seus scripts....

Imagine que o herói está no MAPA 1;
Ele é teleportado para o MAPA 2 (numa tag especifica);
Eu quero copiar um evento do MAPA 1 para o Mapa 2 também.

Se eu faço isso usando seus scripts não funciona porque o programa entende que eu pedi para o evento ser copiado no MAPA 1.
 
DadoCWB comentou:
^^

Mais uma vez obrigado. Tu realmente manja desse negócio sr. Xamã.
No entanto eu gostaria de uma solução que não precisasse alterar as funções padrões. Eu gostaria de algo mais assim:

após transferir o heroi
  atribua o valor a $gameVariable


Tomando por exemplo seus scripts....

Imagine que o herói está no MAPA 1;
Ele é teleportado para o MAPA 2 (numa tag especifica);
Eu quero copiar um evento do MAPA 1 para o Mapa 2 também.

Se eu faço isso usando seus scripts não funciona porque o programa entende que eu pedi para o evento ser copiado no MAPA 1.
Código:
// Cria um alias ou uma copia da função original
const _game_map_setup = Game_Map.prototype.setup;
// Cria a versão editada da função
Game_Map.prototype.setup = function(mapId) {
// Chama a função original passando os parâmetros e o this.
_game_map_setup.apply(this, arguments);
// Conteúdo da função editada
$gameVariables.setValue(1, mapId);
};
O script acima cria uma copia da função, dessa maneira posso chama-la sem reescrever a mesma, ou seja, editei a função, mas chamei a versão original, então tenho as duas versões rodando normal, não mudei a original de fato. Sobre o script, realmente ele não está preparado para copiar eventos para outros mapas, isso deveria ser corrigido em uma atualização, mas eu não estou mais dando suporte aos plugins.
http://www.condadobraveheart.com/forum/index.php?topic=4624.0
 
Nesse exemplo que o senhor deu, poderia usar o newMapId() do Game_Player, que grava o valor setado no reserveTransfer até a transição do mapa concluir, onde ele é zerado:

Código:
$gamePlayer.reserveTransfer(2, 5, 5, 2, 1);
$gameVariables.setValue(1, $gamePlayer.newMapId());
 
^^ Essa solução funciona sim. Só fico na dúvida se a$gamePlayer.newMapId() não vai zerar antes de ser chamada.
Mas acho que essas duas soluções já me dão um norte ...

Obrigado gente.
 
Se chamar o newMapId() logo após o reserveTransfer() ele não irá zerar, já que o processo que zera roda no updateScene() da Scene_Map num fluxo de execução (desnecessário) até a chamada do performTransfer() do Game_Player.
 
Entendi. Nesse caso então eu vou optar pelo newMapId() do $gamePlayer.

No caso de ter duas funções: A e B;
Chamo a função A;
Chamo a Função B;

Como eu posso garantir que a função B seja executada somente após a função B ter sido completada?

Esse é um conhecimento que eu não tenho e do qual me desviar tem gerado muito trabalho (e muitas linhas de códigos).

 
O JavaScript, assim como quase todas as outras linguagens, é síncrono na execução. Nada é executado em paralelo ao que está sendo executado, a não ser que force isso de alguma maneira (como Threads no Ruby). Então se chamou a função A e logo após a função B, o senhor pode ter certeza que elas executarão nessa ordem e nada executará em paralelo.
 
Se você fala eu acredito mas, então me explica o porquê isso não funciona:

$gamePlayer.reserveTransfer (2, 5, 5, 2, 1);
$gameVariables.setValue(1,$gameMap.mapId())

Em minha modesta opinião, (opinião de um leigo) é que as coisas nesse exemplo acontecem em paralelo. Há outros casos também:

Se eu encadear a chamada a essas duas funções:

$gameTemp.teleportToRegion(2, 5); // teleporta o herói para o mapa 2

$gameMap.copyEventRegion(1, 1, 5, 1); //copia o evento para do mapa 1 para o mapa atual (que o herói foi teleportado)

Tenho 2 mapas. No mapa 1 além do heroi eu tenho 1 evento (id 1);
No mapa 2 tenho uma posição do mapa com a  regionId=5;

Se tudo acontecesse de forma linear o herói seria teleportado e somente após isso o evento seria copiado. Mas o que acontece é que o evento é copiado antes do herói ser teleportado e quando o mapa 2 é mostrado na tela, o evento copiado não está lá (pois ele ficou no mapa 1).
 
O $gamePlayer.reserveTransfer() não define o $gameMap.mapId(), ele define o $gamePlayer.newMapId(), sendo este verificado no próximo update() da Scene_Map e, por ser diferente do $gameMap.mapId(), inicia a rotina de transição de mapa do personagem. Note que essa verificação só rodará no próximo update, por isso ela não é diferente.

O fluxo é:

$gamePlayer.reserverTransfer() define o $gamePlayer.newMapId();
Seu comando do $gameVariables.setValue() é executado;
Scene_Map.update() verifica que o $gamePlayer.newMapId() é diferente do $gameMap.mapId();
Scene_Map.updateTransferPlayer() é executado;
$gameMap.mapId() é definido para o novo ID;
$gamePlayer.newMapId() é zerado;

Como o senhor chama a função logo após o reserveTransfer(), ele executa antes do processo todo de definição do mapId() rodar.
 
Depende de como está executando o seu script. Se for via eventos, colocar o comando de copiar o evento em um evento com inicio automático no mapa 2 já solucionaria o evento. :thinking:
 
Essa solução é que está implementada. Mas estamos falando de 108 mapas, e cerca de 12 eventos que devem ser programados individualmente. Se eu optar por continuar com esse modelo os 2 scripts do Dr. Xamã são dispensáveis. Mas a cada vez que eu implementar um evento novo terei que atualizar em todos os mapas.

Além disso eu tenho que setar a selfswitch toda vez que o jogador mudar de mapa (o que acontece pelo menos umas 3 vezes a cada minuto). Mas se não tiver jeito vai ser assim mesmo.

Agradeço mais uma vez pela disposição em ajudar. E nossa conversa já me acendeu a luz pra uma outra funcionalidade. Obrigado! ^^
 
Kyo Panda comentou:
O JavaScript, assim como quase todas as outras linguagens, é síncrono na execução. Nada é executado em paralelo ao que está sendo executado, a não ser que force isso de alguma maneira (como Threads no Ruby). Então se chamou a função A e logo após a função B, o senhor pode ter certeza que elas executarão nessa ordem e nada executará em paralelo.
Hoje em dia após atualizações no ECMASCRIPT, o mesmo suporta funções assíncronas ou seja as famosas Promises.
Ler mais na MDN
 
Hoje em dia após atualizações no ECMASCRIPT, o mesmo suporta funções assíncronas ou seja as famosas Promises.

Apenas uma nota que Promises permitem a simultaneidade (concurrency) na execução, e não o paralelismo (parallelism):

con_and_par.jpg

Paralelismo no JS se obtem com o require('child_process') no Node.js ou com Web Workers no navegador.

No que se refere ao MV, infelizmente nada disso é usado, pois o Ojima (o chefe dos códigos dos RM) é um safado.
feelsbatman.png


 
A conversa ficou complicada demais pro meu nível... ^^
Vou estudar um pouco mais e retornar a esse tópico no futuro. Por enquanto vou parar meu projeto pois não sei como avançar além deste ponto. Obrigado gente.
 
Kyo Panda comentou:
Paralelismo no JS se obtêm com o require('child_process') no Node.js ou com Web Workers no navegador.
Falando em "require('child_process')" o MV suporta o método, tanto que uso o "require('fs')", que faz uma requisição do modulo "File System" do Node.js, então temos o tal "parallelism", sendo usado no código. No que se refere a criar códigos com "module.exports" para então usar o "require" no MV, funciona perfeitamente, e irei utilizar em meu projeto. Dá para fazer coisas incriveis com ECMASCRIPT, NODE.JS, NW.JS, PIXI.JS e bibliotecas por ai...
 
Um problema do script DrXama_copyEvents.js para usuários não avançados de programação é que ele não retorna o NOVO INDICE do evento copiado. Pode ser trivial quando se copia 1 unico vento pegar a id do mesmo por $game.events().length; Mas quando estamos falando de 30 eventos ou mais sei lá quantos e você não sabe na tela a ordem dos eventos que foram copiados, isso é muito problemático.

Outra coisa é o usso de callback ... Fica dificil saber quando algumas respostas vão acontecer já que alguns processos são executados em "segundo plano"; 
 
Voltar
Topo Inferior