[Tutorial] Temporizaзгo.
#1

Temporizaзгo.
Por rjjj ou Ken




Temporizaзгo й a programaзгo da execuзгo de determinado cуdigo para um momento situado apуs um certo intervalo de tempo .



Em Pawn, hб vбrias tйcnicas que podem ser usadas para a aplicaзгo da temporizaзгo, dentre elas, a mais conhecida й a do SetTimer .





1 - A funзгo sleep.



O sleep foi produzido para ser capaz de fazer com que o servidor, antes de ler qualquer outro cуdigo do GM, tenha que aguardar um certo tempo, que й especificado em seu ъnico parвmetro .



pawn Код:
sleep(/*Tempo em milissegundo.*/);  //Obs: 1 segundo (s) й equivalente a 1000 milissegundos (ms).


Essa funзгo sу deve ser usada no main() do GameMode .


Exemplo de uso:



pawn Код:
main()
{
    print("Aguarde 2 segundos...");  //Mostra uma mensagem no console do samp-server.exe.
    sleep(2000); //Faz o GameMode esperar 2 segundos.
    print("GameMode carregado :D !"); //Passados 2 segundos, й mostrada uma nova mensagem.
}



Em alguns GameModes cheguei a presenciar execuзхes infinitas de funзхes e erros do tipo Run Time causados pela utilizaзгo do sleep, por isso recomendo que apуs a inserзгo dele em um cуdigo, um teste seja feito para que se tenha certeza de que tudo funciona sem problemas.






2 - Loops demorados.



Й possнvel gerar o mesmo efeito do sleep usando loops demorados, veja um exemplo :



pawn Код:
main()
{
    print("Aguarde 2 segundos...");  //Mostra uma mensagem no console do samp-server.exe.
    for(new x; x != 100000000;) x++; //Faz o GameMode esperar aproximadamente 2 segundos.
    print("GameMode carregado :D !"); //Passados 2 segundos, й mostrada uma nova mensagem.
}


Contudo, esse mйtodo pode ser utilizado em qualquer callback, inclusive de Filterscripts.


Ele tambйm, ao contrбrio do sleep, funciona no jogo propriamente dito, parando para os players coisas como o chat, como se fosse um tipo de "Lag" passageiro .


Para tornar esse cуdigo mais prбtico, montei a seguinte macro:



pawn Код:
#define sleep2(%0);  for(new _@%0; _@%0 != (%0*50000000);) (_@%0++);



Exemplo de como usб-la:



pawn Код:
SendClientMessageToAll(0x33CCFFAA, "O servidor ficarб travado durante 3 segundos por motivos tйcnicos.");
sleep2(3);  //O tempo direcionado ao parвmetro deve estar em segundos.
SendClientMessageToAll(0xFFFFFFAA, "Concluнdo.");




3 - SetTimer.



A funзгo SetTimer serve para adiar a leitura de um cуdigo, mas sem fazer com que outros parem .


Й obrigatуrio que esse cуdigo seja uma callback, isto й, seja criado com as estruturas public e forward .


A callback por sua vez nгo pode ter parвmetros, devendo ser criada com os parкnteses () que seguem seu nome, vazios:


Exemplo de callback:



pawn Код:
forward GenkiDama();      //Escolhe-se o nome da callback e escreve-se  "forward NomedaCallback();" ou apenas "NomedaCallback();".  Veja que os parкnteses () estгo vazios, o que й correto.
public GenkiDama()        //Em seguida escreve-se "public NomedaCallback" (sem o ponto e vнrgula) e chaves {}, com o cуdigo a ser executado dentro delas.   Veja que os parкnteses () estгo novamente vazios, o que й correto.
{  
    SendClientMessageToAll(0x33CCFFAA, "Deem um pouco de sua energia !");  //Cуdigo interno.
    return true;
}


Bem, estes sгo os parвmetros da funзгo SetTimer:



pawn Код:
SetTimer("NomeDaCallback", /*Tempo em milissegundos.*/, /*Repetir sempre.*/);


No ъltimo parвmetro (onde estб "Repetir sempre", acima) coloca-se true para que a callback seja executada sempre que se passar um tempo equivalente aos milissegundos especificados, e false para que ela seja lida apenas 1 vez .



Exemplo 1:



pawn Код:
//Dentro de algum comando ou funзгo:

SetTimer("IniciarCorrida", 5000, false);   //Programa a exibiзгo de uma mensagem para daqui a 5 segundos. Como no terceiro parвmetro estб o sнmbolo "false", a callback IniciarCorrida serб executada apenas 1 vez, consequentemente, a mensagem serб mandada apenas 1 vez tambйm.



//No Final do GM, fora de qualquer outro cуdigo:

forward IniciarCorrida();
public IniciarCorrida()    //Passados 5 segundos, a mensagem й enviada.
{
    SendClientMessageToAll(0xFFFFFFAA, "A corrida comeзou !");  //Mensagem.
    return true;
}


Exemplo 2:



pawn Код:
//No OnGameModeInit:

SetTimer("SkinWoozie", 1000, true);   //Programa uma verificaзгo de todos os jogadores, a fim de saber quem estб com com a skin do Woozie, para daqui a 1 segundo. Como no terceiro parвmetro estб o sнmbolo "true", sempre que 1 segundo se passar a callback "SkinWoozie" serб executada, consequentemente, a verificaзгo serб efetuada.



//No Final do GM, fora de qualquer outro cуdigo:

forward SkinWoozie();
public SkinWoozie()    //Passado 1 segundo, os jogadores sгo checados.
{
    for(new x = 0; x != MAX_PLAYERS; x++)  //Este loop permite que a verificaзгo analise todos os jogadores.
    {
        if(GetPlayerSkin(x) == 294)  //Se a skin for detectada em um jogador.
        {
            SendClientMessage(x, 0x33CCFFAA, "Vocк estб com a skin do Woozie !");//...Uma mensagem й enviada ao mesmo.
        }
    }
    return true;
}



Vale ressaltar que o perнodo do Temporizador (ou Timer), a entidade criada pelo SetTimer para cuidar de determinada callback, serб sempre relativo ao momento no qual ele foi gerado.






4 - SetTimerEx.



A diferenзa entre o SetTimer e o SetTimerEx й que este ъltimo funciona sem problemas com callbacks que possuem parвmetros, isto й, que sгo criadas com variбveis/constantes dentro de seus parкnteses () .


Exemplo de callback com parвmetros:



pawn Код:
forward lol(playerid);
public lol(playerid);   //Essa callback tem 1 parвmetro, a variбvel "playerid".
{
    SendClientMessage(playerid, 0xFFFFFFAA, "Oi !");
    return true;
}



Mas como se usaria esse cуdigo de modo que playerid fosse igual a 4 e assim a mensagem fosse enviada ao jogador de ID 4 apуs um certo tempo ?


Bem, vejamos os parвmetros da funзгo SetTimerEx:



pawn Код:
SetTimerEx("NomeDaCallback", /*Tempo em milissegundos.*/, /*Repetir sempre*/, /*Caracteres para a identificaзгo dos tipos de valores nos parвmetros da callback.*/, /*Valores passados aos parвmetros.*/);


Os 3 primeiros parвmetros trabalham de maneira idкntica aos correspondentes a eles no SetTimer .


Quanto aos 2 ъltimos:


O quarto (onde estб escrito "Caracteres para a identificaзгo dos tipos valores nos parвmetros da callback.", acima) deve conter, entre aspas e um ao lado do outro, sнmbolos que identifiquem a natureza dos elementos que serгo colocados nos parвmetros da callback (string, nъmero inteiro, entre outros).


Os principais sгo:



pawn Код:
"d" ou "i" para nъmeiros inteiros (integers).
"f" para nъmeros floating-point (floats, nъmeros racionais com um ponto ".").
"s" para strings (textos).



Jб o quinto (onde estб escrito "Valores passados aos parвmetros", acima) deve conter, entre vнrgulas, os prуprios elementos que serгo direcionados aos parвmetros da callback .



Por exemplo, se eu quisesse fazer com que, passados 9 segundos, a callback lol que citei anteriormente (lembra dela ? ) fosse executada a fim de que a mensagem "Oi !" fosse enviada ao jogador de ID 4 :



pawn Код:
SetTimerEx("lol", 9000, false, "i", 4);  // 4 por que queremos que o "playerid" da callback seja igual a esse nъmero e "i" por que 4 й um nъmero inteiro.



Outro exemplo, mais complexo:



pawn Код:
//Dentro de algum comando ou funзгo:
new id_jogador= 12;
SetTimerEx("AvisoRegras", 4000, false, "ds", id_jogador, "Cuidado com as regras !");  //  "ds" por que a variбvel "id_jogador" e o texto "Cuidado com as regras" podem ser considerados, respectivamente, um nъmero inteiro e uma string.  O motivo de "d" (vendo da esquerda para a direita) vir primeiro que "s" em "ds" й o fato de "id_jogador" vir primeiro que o texto "Cuidado com as regras !" na linha do SetTimerEx.



//No Final do GM, fora de qualquer outro cуdigo:


forward AvisoRegras(playerid, texto[]);
public AvisoRegras(playerid, texto[]);   //Como o SetTimerEx enviou os seguintes valores, nesta ordem:  a variбvel "id_jogador" e a string "Cuidado com as regras !", nesse cуdigo de callback, as variбveis "playerid" e "texto" serгo, respectivamente, iguais a eles.
{
    SendClientMessage(playerid, 0xFFFFFFAA, texto);  //Mandarб a mensagem "Cuidado com as regras !" ao jogador de ID 12.
    return true;
}




5 - KillTimer.



Uma vez criado um Timer, й possнvel parб-lo por meio da funзгo KillTimer .


Os parвmetros dela sгo:



pawn Код:
KillTimer(/*ID do Temporizador*/);


Mas como saber o ID de um Timer responsбvel por certa callback a fim de bloquear sua execuзгo ? .


Basta criar uma variбvel e, na hora de usar o SetTimer/SetTimerEx, igualб-la a ele.


Assim essa variбvel irб armazenar o ID do Timer e serб possнvel usб-la para chegar atй ele.


Exemplo:



pawn Код:
//Dentro de algum comando ou funзгo:

new TimerID;
TimerID = SetTimer("ServerGMX", 5000, false); //Programa um GMX para daqui a 5 segundos.
KillTimer(TimerID); //Destrуi o Timer da callback ServerGMX, com isso, o GMX que seria feito й cancelado.


//No Final do GM, fora de qualquer outro cуdigo:

forward ServerGMX();
public ServerGMX()
{
    SendRconCommand("gmx");
    return true;
}





6 - Outros.



Hб tambйm as funзхes gettime, getdate, GetTickCount e tickcount, que capturam dados de um momento especнfico no tempo, e por isso, podem ser usadas para gerar uma temporizaзгo por meio da criaзгo de sistemas de referкncia entre dados antigos e dados recentes .


Exemplo:



pawn Код:
//No Topo do GM:

new ComandoBloqueado;


//Em um comando:

if((gettime() - ComandoBloqueado) < 30) return SendClientMessage(playerid, 0xFFFFFFAA, "Comando bloqueado !");
ComandoBloqueado = gettime();


No caso acima, o comando em questгo seria bloqueado se o nъmero de segundos (essa unidade de medida devido ao gettime) passados desde a ъltima vez que ele foi usado fosse menor que 30.



E й isso .



Espero ter ajudado .
Reply


Messages In This Thread
Temporizaзгo. - by rjjj - 07.01.2012, 17:27
Re: Temporizaзгo. - by [O.z]Caroline - 07.01.2012, 17:34
Re: Temporizaзгo. - by Adrian Fahrenheit Tepes - 07.01.2012, 17:39
Re: Temporizaзгo. - by Bolinha_ProJogos - 07.01.2012, 17:51
Re: Temporizaзгo. - by [O.z]Caroline - 07.01.2012, 17:51
Re: Temporizaзгo. - by Adrian Fahrenheit Tepes - 07.01.2012, 17:53
Re: Temporizaзгo. - by rjjj - 07.01.2012, 17:57
Re: Temporizaзгo. - by [O.z]Caroline - 07.01.2012, 18:00
Re: Temporizaзгo. - by rjjj - 07.01.2012, 18:07
Re: Temporizaзгo. - by JonathanFeitosa - 07.01.2012, 18:19

Forum Jump:


Users browsing this thread: 1 Guest(s)