[Ajuda] Timer Verificaзгo
#1

Olб,

Estou criando a verificaзгo para colocaзгo do meu sistema de race. Eu fiz um timer para quando o player pegar um CP executa o timer, e esse timer n repete, sу й executado novamente quando o player pega outro CP.

O problema:

Quero que verifica quantos CPs o player tem e assim comparar com quantos CPs os outros tem para assim setar a colocaзгo dele na corrida para 1є, 2є, 3є e assim sucessivamente... Sу que eu fiz o codigo abaixo e ele seta o jogador para 1є caso a quantidade de CPs conquistados seja maior que a dos demais, agora nгo consigo criar para o player em 2є, em 3є e etc... E quando o player em 2є ultrapassa o 1є a posiзгo dele sobe pra 1є, aн quero q o que estava em 1є vб para 2є e etc.

Se alguйm puder me ajudar a fazer um timer melhor, por favor, estou aguardando respostas.

Quando ele pega CP:

Код:
SetTimerEx("VerificarPosicao", 100, false, "i", playerid);
Callback do timer:

Код:
public VerificarPosicao(playerid){

	for(new i = 0; i < MAX_PLAYERS; i++){
	    if(!IsPlayerConnected(i)) continue;
	    if(Evento[i] == false) continue;
		if(i == playerid) continue; // Se o i for igual ao playerid
		if(AddCP[playerid] > AddCP[i] && AlguemGanhou[Colocado[0]] == false){ // Se a quantidade de CP's do jogador for maior que de todos players ele й o primeiro
			Posicao[Colocado[0]] = 1;
			Posicao[playerid] = 0;
		    Colocado[0] = playerid;
		    format(Str, sizeof(Str), "~b~~h~1|: ~w~%s", GetName(Colocado[0]));
		    PlayerTextDrawSetString(playerid, Textdraw2[i], Str);
			PlayerTextDrawSetString(i, Textdraw2[i], Str);
			
		    format(Str, sizeof(Str), "~b~~h~2|: ~w~%s", GetName(Colocado[1]));
		    PlayerTextDrawSetString(playerid, Textdraw6[i], Str);
			PlayerTextDrawSetString(i, Textdraw6[i], Str);
		}
		format(Str, sizeof(Str), "** {FFFFFF}ID de todos os jogadores exceto playerid: {AA0000}%d", i);
		SendClientMessage(playerid, Red, Str);
	}

	return 1;
}
Reply
#2

PHP код:
new pos;
for(new 
0MAX_PLAYERSi++) 
{
   if(
AddCP[playerid] < AddCP[i] && AlguemGanhou[Colocado[0]] == false// Acrescenta mais 1 a posicao do       jogador por cada player a frente dele
   
{
      
pos++;
   }
   if(
AddCP[playerid] == AddCP[i]) // Caso alguem esteja empatado com o player
   
{
      new 
JogadorCheckPoint //O proximo checkpoint do player
      
new EmpatadoCheckPoint // Proximo checkpoint com quem estб empatado                    
      
if(GetPlayerDistanceFromPoint(playeridXCheckPoint,YCheckPointZCheckPoint) > GetPlayerDistanceFromPoint(j,XCheckPointYCheckPointZCheckPoint)) // Se a posiзгo do jogador em relaзгo ao checkpoint for maior do que com aquele que estб empatado acrescenta mais 1 a posiзгo 
      
{
          
pos++;
      }
   }
}
Posicao[playerid] = pos+1
Reply
#3

Quote:
Originally Posted by Cheleber_Pausini
Посмотреть сообщение
PHP код:
new pos;
for(new 
0MAX_PLAYERSi++) 
{
   if(
AddCP[playerid] < AddCP[i] && AlguemGanhou[Colocado[0]] == false// Acrescenta mais 1 a posicao do       jogador por cada player a frente dele
   
{
      
pos++;
   }
   if(
AddCP[playerid] == AddCP[i]) // Caso alguem esteja empatado com o player
   
{
      new 
JogadorCheckPoint //O proximo checkpoint do player
      
new EmpatadoCheckPoint // Proximo checkpoint com quem estб empatado                    
      
if(GetPlayerDistanceFromPoint(playeridXCheckPoint,YCheckPointZCheckPoint) > GetPlayerDistanceFromPoint(j,XCheckPointYCheckPointZCheckPoint)) // Se a posiзгo do jogador em relaзгo ao checkpoint for maior do que com aquele que estб empatado acrescenta mais 1 a posiзгo 
      
{
          
pos++;
      }
   }
}
Posicao[playerid] = pos+1
Mano me explica melhor seu cуdigo... Porque pos й uma variбvel = para todos... Entгo sempre que AddCP[playerid] for menor que o AddCP de todos os outros esse variavel vai ganhar +1 no seu valor, o que nгo faz sentido, pois se tiver 4 player correndo e ele estiver em 2є lugar e alguem passar ele, nada vai acontecer porque o AddCP[playerid] nгo vai ser menor do que TODOS, vai ser menor somente de quem passou ele e de quem estб na frente dele na corrida
Reply
#4

Sua lуgica ta meio ruim:
Timers sгo utilizados para executar funзхes a cada X intervalo de tempo ou em certo intervalo de tempo. Vocк sу chama a funзгo "VerificarPosicao" uma vez e o intervalo nгo importa, entгo nгo й necessбrio o uso de timer.

Pra fazer esse sistema de colocaзгo vocк precisa entender como se faz "sorting", jб mandei um link no outro tуpico com uma cacetada de algorнtimos sobre isso, sу escolher o que melhor se encaixa na situaзгo.
O jeito mais fбcil й criar uma variбvel global pra salvar as posiзхes e, quando comeзar a corrida, colocar o id de todos os jogadores que estгo no evento dentro dela, sem pular nenhuma posiзгo. Assim vocк terб uma array com todos os corredores (por enquanto a ordem nгo importa porque ninguйm pegou checkpoint).
A partir disto, quando alguйm pegar um CP vocк vai dar um loop nessa array com as posiзхes e verificar se ele passou alguйm, se sim faz a troca (swap). Talvez nгo seja o modo mais otimizado, mas й o mais fбcil
Reply
#5

Cara, pode me dar um exemplo de sorting ou algum link de tutorial menos complexo de como fazer? Vou comeзar a estudar isso ґ-ґ
Reply
#6

Quote:
Originally Posted by Tuznn
Посмотреть сообщение
Mano me explica melhor seu cуdigo... Porque pos й uma variбvel = para todos... Entгo sempre que AddCP[playerid] for menor que o AddCP de todos os outros esse variavel vai ganhar +1 no seu valor, o que nгo faz sentido, pois se tiver 4 player correndo e ele estiver em 2є lugar e alguem passar ele, nada vai acontecer porque o AddCP[playerid] nгo vai ser menor do que TODOS, vai ser menor somente de quem passou ele e de quem estб na frente dele na corrida
Repare bem no meu cуdigo entгo

Isso й uma boa maneira de achar a posiзгo...
Repare:
A posiзгo serб sempre 0 no inicio do cуdigo.
PHP код:
new pos 0
Para todos os players com mais CHECKPOINTS que ele acrescenta +1 a posiзгo.
PHP код:
if(AddCP[playerid] < AddCP[i] && AlguemGanhou[Colocado[0]] == false// Acrescenta mais 1 a posicao do       jogador por cada player a frente dele 
   

      
pos++; 
   } 
Caso aconteca isso que vocк falou de por exemplo eu estar em 2є e passar o 1є mas mesmo assim tenho os mesmo CP's que o 2є sу que estou mais perto do proximo checkpoint portanto:
PHP код:
if(AddCP[playerid] == AddCP[i]) // Caso alguem esteja empatado com o player 
   

      new 
JogadorCheckPoint //O proximo checkpoint do player 
      
new EmpatadoCheckPoint // Proximo checkpoint com quem estб empatado                     
      
if(GetPlayerDistanceFromPoint(playeridXCheckPoint,YCheckPointZCheckPoint) > GetPlayerDistanceFromPoint(j,XCheckPointYCheckPointZCheckPoint)) // Se a posiзгo do jogador em relaзгo ao checkpoint for maior do que com aquele que estб empatado acrescenta mais 1 a posiзгo  
      

          
pos++; 
      } 
   } 
E caso ele seja o primeiro, e porque tambйm a variбvel pos й zero portanto temos sempre de acrescentar 1.
Depois do fim do loop:
PHP код:
Posicao[playerid] = pos+1
@EDIT1
Ah e faзa um timer repetitivo para sempre checar as posiзхes:
PHP код:
new TimerPosicao[MAX_PLAYERS
PHP код:
TimerPosicao[playerid] = SetTimerEx("VerificarPosicao"500true"i"playerid); 
E mate quando acabar a corrida:
PHP код:
KillTimer(TimerPosicao[playerid]); 
Reply
#7

Quote:
Originally Posted by renatog
Посмотреть сообщение
Sua lуgica ta meio ruim:
Timers sгo utilizados para executar funзхes a cada X intervalo de tempo ou em certo intervalo de tempo. Vocк sу chama a funзгo "VerificarPosicao" uma vez e o intervalo nгo importa, entгo nгo й necessбrio o uso de timer.

Pra fazer esse sistema de colocaзгo vocк precisa entender como se faz "sorting", jб mandei um link no outro tуpico com uma cacetada de algorнtimos sobre isso, sу escolher o que melhor se encaixa na situaзгo.
O jeito mais fбcil й criar uma variбvel global pra salvar as posiзхes e, quando comeзar a corrida, colocar o id de todos os jogadores que estгo no evento dentro dela, sem pular nenhuma posiзгo. Assim vocк terб uma array com todos os corredores (por enquanto a ordem nгo importa porque ninguйm pegou checkpoint).
A partir disto, quando alguйm pegar um CP vocк vai dar um loop nessa array com as posiзхes e verificar se ele passou alguйm, se sim faz a troca (swap). Talvez nгo seja o modo mais otimizado, mas й o mais fбcil
Mano fiz esse cуdigo, mas nгo faзo a mнnima ideia se estou indo pelo caminho certo -.-

Код:
	new Y, X, CPAtual, J;
	for(Y = 0; Y < MAX_PLAYERS; Y++)
	{
		if(!IsPlayerConnected(Y)) continue; // Se o ID nгo tiver conectado, ignora e continua a funзгo
		Posicao[Y] = AddCP[Y]; // Posicao = Quantidade de CPs conquistados
		printf("%d %d", Posicao[Y], AddCP[Y]);
	}

	for(X = 1; X < 5; X++) // 10 seria a quant de jogadores no evento
	{
 		CPAtual = Posicao[X];
   		J = X - 1; // J = antecessor de CPAtual
		while( (J >= 0) && (CPAtual < Posicao[J]) )
		{
  			Posicao[J+1] = Posicao[J];
	    	J--; // J diminui
		}
  		Posicao[J+1] = CPAtual;
		}
Ele funciona assim: A loop vai pegar os jogadores online e vai igualar a Array "Posicao" a quantidade de cps que o player tem.
Exemplo:

Код:
Posicao[0] = AddCP[Y]
(Sendo Y o id do jogador)

-
Depois que a variбvel Y aumentar no loop:
Код:
Posicao[1] = AddCP[Y]
E assim sucessivamente atй o ъltimo jogador conectado.
-

Depois ela vai ordenar por ordem crescente as quantidades de CPs conquistados pelos jogadores.
Exemplo:
Код:
Posicao[0] = 5;
Код:
Posicao[1] = 10;
Код:
Posicao[2] = 15;
(Sendo 5, 10 e 15 a quantidade de cps adquiridas por um certo jogador)
-
Entгo na lуgica, o 1є colocado da corrida seria o jogador em que a quantidade de cps estб na array "Posicao[2]"
Reply
#8

@removed
Reply
#9

Quote:
Originally Posted by BarBePie
Посмотреть сообщение
Acho que nгo em...

PHP код:
if(!IsPlayerConnected(Y)) continue; 
Isso ignora se o jogador nгo estiver conectado e continua a funзгo normalmente cara. Nгo interfere em nada alйm disso.
Reply
#10

Olha, eu nгo gosto de dar cуdigo porque eu perco tempo fazendo e testando. Eu fiz um aqui rapidгo, mas nгo testei, nгo sei se compila, nгo sei se funciona, nгo fiz otimizaзхes. Mas deixei uns comentбrios pra vocк se encontrar e tentar entender a lуgica por trбs (que por sinal nгo sei se estб certa).
PHP код:
new colocados[MAX_PLAYERS] = {-1, -1, -1, ...}; //array global
//dentro da funзгo que inicia o evento (depois que o evento fecha e antes de um jogador pegar checkpoint)
//Salvar todos os jogadores do evento na array colocados[], sem pular posiзхes
for (new 0MAX_PLAYERSi++)
{
    if (!
IsPlayerConnected(i) continue;
    if (!
Evento[i]) continue;
    
    for (new 
j=0MAX_PLAYERSj++)
    {
        if (
colocados[j]) == -1//Verifica se a posiзгo "j" estб disponнvel
            
colocados[j] = i//Salva o id do jogador na posiзгo "j" de colocados
    
}
}
//Opзгo 1
VerificarPosicao() // Passa por todos os jogadores
{
    new 
tmpj;
    for (new 
1MAX_PLAYERSi++) //loop todos os jogadores comeзando pelo id 1
    
{
        
i-1//j й a posiзгo anterior ao player que estamos (i)
        
while (> -&& AddCP[colocados[i]] > AddCP[colocados[j]] //enquando j for um id vбlido e AddCP do jogador atual (i) for maior que o anterior, ele faz a troca entre eles
        
{
            
tmp colocados[i];
            
colocados[i] = colocados[j];
            
colocados[j] = tmp;
            
j--;
        }
    }
}
//Opзгo 2
VerificarPosicao(playerid// Tem base no playerid
{
    new 
tmpj;
    for (new 
0MAX_PLAYERSi++) //loop todos os jogadores
    
{
        if(
colocados[i] == playerid//encontra a posiзгo do playerid na array colocados
        
{
            
i-1//salva a posiзгo de seu antecessor
            
break;
        }
    }
    while (
> -&& AddCP[playerid] > AddCP[colocados[j]] //enquando j for um id vбlido e AddCP do jogador atual (playerid || colocados[j+1]) for maior que o anterior (colocados[j]), ele faz a troca entre eles
    
{
        
tmp colocados[j+1];
        
colocados[j+1] = colocados[j];
        
colocados[j] = tmp;
        
j--;
    }

Como eu disse, nгo sei se isso funciona, mas tб quase lб. Isso й o mбximo que posso te ajudar, daqui por diante й por sua conta.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)