• 24 Avril 2025, 08:49:10


Auteur Sujet: Detecter le point le plus proche d'un joueur entre plusieurs points  (Lu 1229 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne Ludow12

  • *
  • Nouveau
  • Messages: 11
    • Voir le profil
Bonjour,

Je voulais faire appel à votre aide car je suis pas un pro dans le script PAWN de SA:MP, j'ai quelques bases pour faire des choses qui restes "concrètes", mais dès que je trouve pas une fonction, et ba je suis bloqué.

En faite, je voudrais créer un système d'arrêt de bus pour un RP, et donc je voudrais créer la possibilité d'avoir une commande qui indiquera l'arrêt le plus proche selon la liste des arrêts pour la ligne choisie.

Techniquement, selon la position du player p (Xp, Yp Zp) et à la liste des points a, b et c déjà définis :  (Xa,Ya,Za) ; (Xb,Yb,Zb) ; (Xc,Yc,Zc)  ...
je voudrais qu'un checkpoint indique le point le plus proche entre ces 3 longueurs, mais ça nécessites des calcules logiques je crois bien..
 
J'ai pensé faire recourt aux mathématiques des vecteurs, avec des calculs de longueurs, mais bon, je sais pas si c'est possible et comment faire, si possible de créer une fonction, ou pas.

Le plus simple, ça serai une fonction déjà créée qui s'adapte à mes besoins, mais j'en ai pas trouver malgré mes tentatives de recherche avant de venir poster ici.

Merci d'avance de vos futures réponses :D

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #1 le: 23 Février 2010, 04:05:21 »
Salut,

tu peut utiliser un petit define pour récupérer la distance a carré (plus rapide et tu n'as besoin que de comparer le plus loin)

#define SquaredDistance(%0,%1,%2,%3,%4,%5)    ((%0 - %3) * (%0 - %3) + (%1 - %4) * (%1 - %4) + (%2 - %5) * (%2 - %5))
//UTILISATION: new Float:distance = SquaredDistance(x1, y1, z1, x2, y2, z2);

ensuite te suffit de noter le numéro correspondant à l'endroit et la distance de cet endroit détecté comme le plus proche dans des variables (une pour la distance et une pour le numéro)
ce qui donne un code de ce genre:

GetNearestPoint(playerid,  Float:X[], Float:Y[], Float:Z[], size)//X, Y et Z seront ton tableau en fait donc pas en paramètre
{
    new Float:px, Float:py, Float:pz;
    GetPlayerPos(playerid, px, py, pz);
    new Float:distance = 10000000.0, id, Float:tmpval;//grande valeur pour distance
    for(new i = 0; i < size, i++)
    {
        tmpval = SquaredDistance(X[i], Y[i], Z[i], px, py, pz);
        if(tmpval < distance)
        {
            distance = tmpval;
            id = i;
        }
    }
    return i;
    //si tu veut créer le cp tout de suite:
    //SetPlayerCheckpoint(playerid, X[i], Y[i], Z[i], 20.0);//20.0 = taille du CP
}

bonne chance

ps. le code comporte probablement des erreurs, codé sur le forum

++Sim++





Hors ligne Ludow12

  • *
  • Nouveau
  • Messages: 11
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #2 le: 23 Février 2010, 12:38:04 »
Merci beaucoup

J'ai ajouté le define, ainsi que la fonction, mais je me demande comment pouvoir ajouter une liste de point dans la fonction, et qu'il me détecte le point le plus prêt..

La define je la laisse intacte ? Elle sera appelée dans la fonction GetNearestPoint ?

GetNearestPoint(playerid,  Float:X[], Float:Y[], Float:Z[], size)  faut-il que je remplace les Float ?
Je suis pommé :/

Hors ligne chneubeul

  • *
  • Gangster
  • GTA Online Addict :)
  • Messages: 1132
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #3 le: 23 Février 2010, 19:19:49 »
Salut, avant tout, il faut que tu créé un "stock" de tes position des arrêts de bus donc bien sur par exemple :
new Float:ArretBus[26][3]={
{-2660.9,85.3,4.1},
{-2738.9,93.5,4.5},
{-2759.0,-37.5,6.9},
{-2753.7,422.2,4.3},
{-2558.3,660.6,14.4},
{-2441.9,522.2,29.9},
{-2517.7,341.7,27.7},
{-2546.0,297.4,18.3},
{-2197.7,289.2,35.3},
{-2131.9,-94.0,35.3}
};


Puis ensuite au moment ou tu va taper une commande, tu va venir comparer chacune des positions en fonction du joueur, donc par exemple ...


if(strcmp(cmd, "/arret", true) == 0)
{
new Float:PosJoueurX,Float:PosJoueurY,Float:PosJoueurZ;
GetPlayerPos(playerid, PosJoueurX, PosJoueurY, PosJoueurZ;
// On declare les positions des à arrets
new Float:PosArretX, Float:PosArretY, Float:PosArretZ;
new Float:PosArret1X, Float:PosArret1Y, Float:PosArret1Z;
new Float:PosArret2X, Float:PosArret1Y, Float:PosArret2Z;
// On ajoute aux variables déclarer avant une valeur donc ici les positions des arrets de bus 0, 1 et 2
/* Position Arret 0*/PositionArret[0][0] = PosArretX; PositionArret[0][1] = PosArretX; PositionArret[0][2] = PosArretX;
/* Position Arret 1*/PositionArret[1][0] = PosArretX; PositionArret[1][1] = PosArretX; PositionArret[1][2] = PosArretX;
/* Position Arret 1*/PositionArret[2][0] = PosArretX; PositionArret[2][1] = PosArretX; PositionArret[2][2] = PosArretX;
// On calcul la position du joueur par rapport aux arrets de bus
new arret = floatadd(floatadd(floatsqroot(floatpower(floatsub(PosArretX,PosJoueurX),2)),floatsqroot(floatpower(floatsub(PosArretY,PosJoueurY),2))),floatsqroot(floatpower(floatsub(PosArretZ,PosJoueurZ),2)));
new arret1 = floatadd(floatadd(floatsqroot(floatpower(floatsub(PosArret1X,PosJoueurX),2)),floatsqroot(floatpower(floatsub(PosArret1Y,PosJoueurY),2))),floatsqroot(floatpower(floatsub(PosArret1Z,PosJoueurZ),2)));
new arret2 = floatadd(floatadd(floatsqroot(floatpower(floatsub(PosArret2X,PosJoueurX),2)),floatsqroot(floatpower(floatsub(PosArret2Y,PosJoueurY),2))),floatsqroot(floatpower(floatsub(PosArret2Z,PosJoueurZ),2)));
// On ecrase une valeur qui va servir de comparaison
PlayerInfo[playerid][ArretProche] = arret;
if(arret < arret1 && arret2)
{
    // Donc si l'arret 0 à une valeur plus faible que les autres et donc moins loin on affiche son checkpoint
    SetPlayerCheckpoint(playerid, PositionArret[0][0], PositionArret[0][1], PositionArret[0][2],5);
SendClientMessage(playerid, COLOR_GREEN, " L'arrêt le plus proche à été signalez sur votre carte !");
return 1;
}
else if(arret1 < arret && arret2)
{
    // Donc si l'arrêt 1 à une valeur plus faible que les autres et donc moins loin on affiche son checkpoint
    SetPlayerCheckpoint(playerid, PPositionArret[1][0], PositionArret[1][1], PositionArret[1][2],5);
SendClientMessage(playerid, COLOR_GREEN, " L'arrêt le plus proche à été signalez sur votre carte !");
return 1;
}
else if(arret2 < arret1 && arret)
{
    // Donc si l'arret 2 à une valeur plus faible que les autres et donc moins loin on affiche son checkpoint
    SetPlayerCheckpoint(playerid, PositionArret[2][0], PositionArret[2][1], PositionArret[2][2],5);
SendClientMessage(playerid, COLOR_GREEN, " L'arrêt le plus proche à été signalez sur votre carte !");
return 1;
}

}

N'oublie pas de déclarer au script l'info [ArretProche] ^^


Voila en espérant t'avoir éclairer, A+
Sam.  :cheers

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #4 le: 23 Février 2010, 20:39:45 »
Sim ma dit de te dire que le code que tu as fait n' est pas bon ^^



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Salut,

Sim ma dit de te dire que le code que tu as fait n' est pas bon ^^

bon je vais m'expliquer maintenant que je suis à la maison:

- ton tableau est correct
- la commande de base est correcte

- le calcul supposé donné la distance n'est pas bon
- le test afin de savoir quelle distance est la plus courte n'est pas bon

donc, si je reprend ma fonction légèrement modifiée et ta commande afin de faire un code fonctionnel:

new Float:ArretBus[][3]={
{-2660.9, 85.3, 4.1},
{-2738.9, 93.5, 4.5},
{-2759.0, -37.5, 6.9},
{-2753.7, 422.2, 4.3},
{-2558.3, 660.6, 14.4},
{-2441.9, 522.2, 29.9},
{-2517.7, 341.7, 27.7},
{-2546.0, 297.4, 18.3},
{-2197.7, 289.2, 35.3},
{-2131.9, -94.0, 35.3}
};

#define SquaredDistance(%0,%1,%2,%3,%4,%5)    ((%0 - %3) * (%0 - %3) + (%1 - %4) * (%1 - %4) + (%2 - %5) * (%2 - %5))

GetNearestPoint(playerid,  Float:pos[][3], size)//X, Y et Z seront ton tableau en fait donc pas en paramètre
{
new Float:px, Float:py, Float:pz;
GetPlayerPos(playerid, px, py, pz);
new Float:distance = 10000000.0, id, Float:tmpval;//grande valeur pour distance
for(new i = 0; i < size, i++)
{
tmpval = SquaredDistance(pos[i][0], pos[i][1], pos[i][2], px, py, pz);
if(tmpval < distance)
{
distance = tmpval;
id = i;
}
}
return id;
}

//dans OnPlayerCommandText
if(strcmp(cmd, "/arret", true) == 0)
{
new Arret = GetNearestPoint(playerid, ArretBus, sizeof(ArretBus));
    SetPlayerCheckpoint(playerid, ArretBus[Arret][0], ArretBus[Arret][1], ArretBus[Arret][2], 20);
SendClientMessage(playerid, COLOR_GREEN, " L'arrêt le plus proche à été signalez sur votre carte !");
return 1;
}

n'est-ce pas plus simple?

ps. peu contenir de petites erreurs de frappe

++Sim++





Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #6 le: 23 Février 2010, 23:52:41 »
Désolée Sim j' aurais bien voulut expliquer pourquoi mais mon PC rammer à cause d' une grosse installation dessus ^^



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Ludow12

  • *
  • Nouveau
  • Messages: 11
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #7 le: 24 Février 2010, 00:09:03 »
Merci, merci et merci

je demande de l'aide, on me donne le bout de script, que demandez de mieux :D
Tout marche nikel, j'ai plus qu'a appliqué ça pour differentes listes de points, BRAVO à vous!

Je n'hésiterai pas à redemandez de l'aide ici, sans abusez sur vos qualités de scripteurs GG

Hors ligne chneubeul

  • *
  • Gangster
  • GTA Online Addict :)
  • Messages: 1132
    • Voir le profil
Re : Detecter le point le plus proche d'un joueur entre plusieurs points
« Réponse #8 le: 24 Février 2010, 20:24:02 »
Yop', j'ai fais sa à la rache ^^ Et mon calcul est bon, je l'utilise pour un compteur kilométrique qui marche bien ^^

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Yop', j'ai fais sa à la rache ^^ Et mon calcul est bon, je l'utilise pour un compteur kilométrique qui marche bien ^^

un calcul de distance ne consiste pas en une addition de racine carrée d'expressions au carré,
il s'agit plutôt de la racine carrée d'additions d'expressions au carrées

en gros, de ça:

racine(X²) + racine(Y²) + racine(Z²)
à ça:

racine(X² + Y² + Z²)
++Sim++