JeuWeb - Crée ton jeu par navigateur
cas d'utilisation javascript pour les distinctions de Magdales - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : cas d'utilisation javascript pour les distinctions de Magdales (/showthread.php?tid=4954)

Pages : 1 2 3 4


cas d'utilisation javascript pour les distinctions de Magdales - keke - 28-06-2010

Coucou Sephi ^^, la voix de la sagesse.

Je veux bien expliquer mon problème, mais l'origine de mon râlement dans ce message, c'est que, à chaque fois que je veux me remettre à Javascript, je re-rencontre systématiquement les mêmes incontournables questions. C'est le rare langage qui me fait ça ^^ (j'ai fait de l'ASP pure, de Winscript, du Shscript, etc. mais jamais je n'ai pas encore trouvé plus embêtant). Et a priori, dans le message sus-mentionné, je ne suis pas le seul à trouver cela désopilant.

Je ne dis pas que PHP n'est pas sans faille ... mais il est très facile de part sa prise en main.


Bon, assez, de blabla. L'origine du ralement ^^. J'ai déposé J-query dernière version (de mémoire 1.4.2)

Fonctionnellement : sur ma page d'accueil, je souhaite que les visiteurs voient une liste un peu comme celle ci :
http://jqueryui.com/demos/accordion/
qui se déroulerait automatiquement toute les 5 secondes. Sur la liste on aurait, le nom du joueur, sa distinction, l'heure à laquelle le joueur à eu la distinction.
Cette liste contiendrait des éléments provenant d'une requête via AJAX. (<- Ca, ça marche).
J'ai dit : (un peu comme l'accordéon, mais dans mon cas, l'information précédente serait écrasée par la nouvelle information).

Techniquement :
1°/ au chargement de la page, AJAX récupère les données et formate un tableau de valeur de 200 lignes en xml, exploitable par javascript. Le fichier est envoyé par XML, sous la forme :
Code :
<liste_distinction>
  <distinction_joueur id='2000'>
    <distinction_nom_joueur> Kéké
    </distinction_nom_joueur>
    <distinction_nom_distinction> Grand randonneur
    </distinction_nom_distinction>
    <distinction_heure> 28/06/2010 18:00:00
    </distinction_heure>
  </distinction_joueur>
  <distinction_joueur id='1999'>
    <distinction_nom_joueur> Sephi
    </distinction_nom_joueur>
    <distinction_nom_distinction> Grand Administrateur
    </distinction_nom_distinction>
    <distinction_heure> 28/06/2010 19:00:00
    </distinction_heure>
  </distinction_joueur>
  ...
</liste_distinction>

2°/ On affiche le premier élément pendant 5 secondes, puis le suivant pendant 5 secondes, etc ... pour les 200 lignes du tableau.
3°/ Lorsque l'on a affiché le dernier élément, on re-récupère une nouvelle liste via AJAX et on recommence l'affichage.


Voilà. Je pense y arriver. Avec javascript, on y arrive toujours... mais ça ne sera pas sans quelques énervements. Voulez vous que je dépose le code, lorsque je l'aurais fini ?

Kéké
PS : A ma décharge, il est vrai que j'ai eu des cours de Java, de C, de C++, de C#, d'assembleur, de PHP, de script, etc. Mais jamais je n'ai eu de cours de Javascript ... Je crois qu'il était jugée en fin de vie, et exclusivement pour des gadgets visuels horripilants.


RE: Laideur du code Javascript - Sephi-Chan - 28-06-2010

Déjà, si tu te sers de Javascript, je te conseille d'utiliser JSON plutôt que XML, d'autant que dans ton cas tu as le choix (c'est ton site ! Smile).

Au lieu de produire du code XML (tu peux nous montrer le code qui génère ce XML ?), tu produis du JSON grâce à json_encode.

Si je prends le XML que tu montres :


<liste_distinction>
<distinction_joueur id="2000">
<distinction_nom_joueur>K&#xE9;k&#xE9;</distinction_nom_joueur>
<distinction_nom_distinction>Grand randonneur</distinction_nom_distinction>
<distinction_heure>28/06/2010 18:00:00</distinction_heure>
</distinction_joueur>
<distinction_joueur id="1999">
<distinction_nom_joueur>Sephi</distinction_nom_joueur>
<distinction_nom_distinction>Grand Administrateur</distinction_nom_distinction>
<distinction_heure>28/06/2010 19:00:00</distinction_heure>
</distinction_joueur>
</liste_distinction>

Voici la transformation rigoureuse en JSON (convertie grâce à http://www.thomasfrank.se/xml_to_json.html)


{
liste_distinction:{
distinction_joueur:[
{
id:2000,
distinction_nom_joueur:'Kéké',
distinction_nom_distinction:'Grand randonneur',
distinction_heure:'28/06/2010 18:00:00'
},
{
id:1999,
distinction_nom_joueur:'Sephi',
distinction_nom_distinction:'Grand Administrateur',
distinction_heure:'28/06/2010 19:00:00'
}
]
}
}

Je te déconseille d'utiliser un tel objet, mais plutôt de renvoyer seulement le tableau qui t'intéresse :


[
{
id: 2000,
distinction_nom_joueur:'Kéké',
distinction_nom_distinction:'Grand randonneur',
distinction_heure:'28/06/2010 18:00:00'
},
{
id:1999,
distinction_nom_joueur:'Sephi',
distinction_nom_distinction:'Grand Administrateur',
distinction_heure:'28/06/2010 19:00:00'
}
]

Après, côté Javascript ça devient trivial à manipuler puisque tu as des objets directement utilisables.


$.ajax({
url: 'url de ta page qui affiche uniquement le tableau JSON',
dataType: 'json',
success: function(datas){
// datas contient ton tableau ! Directement utilisable dans une boucle Javascript !
}
});


Sephi-Chan


RE: Laideur du code Javascript - keke - 28-06-2010

Merci Sephi ^^. Je vais me mettre à Json pour voir.

kéké


RE: Laideur du code Javascript - Sephi-Chan - 28-06-2010

Tu vas voir Keke, JSON est génial ! Les seuls cas où XML est plus pertinent, c'est quand tu dois effectuer des requêtes XPath sur un objet ! Wink

(28-06-2010, 04:16 PM)Argorate a écrit : là où en php tu écris $toto = array(...);
en JS tu écris toto = new Array(...);

Tu peux utiliser le dollar dans les noms de variables en Javascript. C'est ce que je fais quand la variable contient du DOM.

Déjà, il ne faut pas oublier le mot clé var avant de déclarer une variable.
Ensuite, Javascript (et Ruby, Python, etc.) dispose des notations littérales pour les tableaux, les objets et les expressions rationnelles, contrairement à PHP qui n'a de notation littérale que pour les chaînes de caractère…


// Déclaration d'un tableau
var favouriteFoods = [ 'Pâté en croûte', 'Saucisson sec' ];

// Déclaration d'un objet
var sephiChan = {
name: "Sephi-Chan",
age: 20,
favouriteFoods: favouriteFoods
};

// Déclaration d'une expression rationnelle
var regexp = /\w+/;



RE: Laideur du code Javascript - keke - 29-06-2010

Coucou,

Bon, c'était évident, sauf que j'y ai passé encore 4h ... grumf !
Enfin, maintenant, la partie AJAX avec JSON est opérationnel. Je vous met des bouts de codes et vous renvoie vers ma page d'essai.
http://www.magdales.com/test_jquery_et_json.php

Page appelante :

<!doctype html>
<html>
<head>
<script type="text/javascript" src="./scripts/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="./scripts/jquery.timers-1.2.js"></script>

<script type="text/javascript">
$(document).ready(function() {
var compteur = -1;
var nb_distinction = 5;

// var texte_id_distinction = "";
var tableau_data = new Array();
tableau_data[0] = 'test'; // Pourquoi devons nous initier cette variable ??? En tous les cas firebug semble pas apprecier sans.


// Cette boucle tourne toutes les 5 secondes. Son but, afficher une liste de joueur avec des distinctions. Les données sont récupéré au début via de l'AJAX. Lorsque toutes les informations sont affichées, on va rechercher de la nouvelle donnée.'

$(document).everyTime(2000, function() { // 5000 = 5 secondes
if (compteur == -1 || compteur >= nb_distinction)
{
compteur = 0;
$.getJSON("ajax_liste_distinction_desc.php", {positionnement: compteur}, function(data) {
// format result
texte_id_distinction = "";

tableau_data = eval(data);

/* texte_id_distinction = tableau_data.nb ;
i = 2;
texte_id_distinction = tableau_data[i].id_distinction_joueur ;*/

nb_distinction = tableau_data.nb ;

// ce message est à titre informatif ... il disparaitra par la suite
$("#tableau_dynamique").html('<br>' + compteur + ' vs ' + nb_distinction + ' Recherche Information via AJAJSON . Nb résultat = ' + tableau_data.nb + ' test = ' + tableau_data[0].id_distinction_joueur);
}
);
}
else if (compteur < nb_distinction )
{
// ici on indique ce qui va remplacer nos cases.
// le tableau renvoyé par php est de la forme : id_distinction_joueur, nom_joueur, nom_distinction
$("#tableau_dynamique").html('<br>' + compteur + ' Le sage : ' + tableau_data[compteur].nom_joueur + ' a reçu la distinction ' + tableau_data[compteur].nom_distinction );

compteur ++ ;

}

// $("#tableau_dynamique").html($("#tableau_dynamique").html + '.');
});

});


</script>

</head>
<body>
<h1>Page de test AJAX</h1>

<div id="tableau_dynamique">Info : Les quelques premières lignes seront pré-chargée en PHP. Ce bloc sera remplacé par Javascript dans quelques secondes.</div>

</body>
</html>

Page ciblé pour l'échange de donnée :


<?php

include_once 'configBDD.php';

$erreur_connect = NULL;

$link = @mysql_connect($host,$user,$passe);
$select_base = mysql_select_db($base);

include_once 'fonctions/distinction.php';

$ajax_liste_derniere_distinction_joueur = ajax_liste_derniere_distinction_joueur ();

//header('Content-type: text/xml');
// print_r ($ajax_liste_derniere_distinction_joueur);

header('Content-Type: application/json');

echo json_encode($ajax_liste_derniere_distinction_joueur);

?>

Format des données (sortie d'un simple mysql query et mis dans un tableau):


function ajax_liste_derniere_distinction_joueur ($positionnement = 1)
{
if ($positionnement <= 0 )
{
$positionnement = 1;
}
$ord_distinction = ord_distinction ();

$i = 0;
$sql_query = "SELECT id_distinction_joueur, id_distinction, id_joueur FROM distinction_joueur order by id_distinction_joueur desc LIMIT ".$positionnement." , 50" ;
// echo '<br>'.$sql_query; '<br>';
$result = mysql_query($sql_query) or die('Erreur : $distinction_joueur : '. mysql_error());
while ( $line = mysql_fetch_array($result, MYSQL_ASSOC))
{
$distinction_joueur[$i]['id_distinction_joueur'] = $line['id_distinction_joueur'];
$distinction_joueur[$i]['id_distinction'] = $line['id_distinction'];
$distinction_joueur[$i]['id_joueur'] = $line['id_joueur'];
// on chope le login du joueur
$info_joueur = info_joueur ($line['id_joueur']);
$distinction_joueur[$i]['nom_joueur'] = $info_joueur['login'];
$distinction_joueur[$i]['nom_distinction'] = $ord_distinction[$distinction_joueur[$i]['id_distinction']]['nom'];

$i ++;
}

if ($i == 0 && $positionnement > 0)
{
return ajax_liste_derniere_distinction_joueur ($positionnement - 5);
}
$distinction_joueur['nb'] = $i;

return $distinction_joueur;
}

Ce qui donne le code JSON :


{
"0": {
"id_distinction_joueur": "2",
"id_distinction": "67",
"id_joueur": "2",
"nom_joueur": "keke_admin",
"nom_distinction": "Nerd"
}, "1": {
"id_distinction_joueur": "1",
"id_distinction": "69",
"id_joueur": "2",
"nom_joueur": "keke_admin",
"nom_distinction": "Mathusalem"
}, "nb": 2
}

Je crois que je n'oublie rien. Le formalisme de la base de donnée importe peu.

Bonne soirée ^^.

kéké qui va se coucher ... glups ! je me lève dans 4h ... bouuhhh !


RE: Laideur du code Javascript - Sephi-Chan - 29-06-2010

J'ai lu en diagonale, mais je vais m'arrêter sur quelques points.

Les deux notations suivantes sont équivalents, je te conseille d'utiliser la seconde, plus claire.


while($line = mysql_fetch_array($result, MYSQL_ASSOC))
while($line = mysql_fetch_assoc($result))


Ensuite, dans le callback de ta requête asynchrone, tu fais évalues les données retournées : il ne faut pas. Les données renvoyées par getJson() sont prêtes à l'emploi.


Enfin, j'ai pensé à un petit refactoring de ta fonction ajax_liste_derniere_distinction_joueur.


function ajax_liste_derniere_distinction_joueur($positionnement = 1){
if($positionnement <= 0 ){
$positionnement = 1;
}

$distinction_joueur = array();
$ord_distinction = ord_distinction();
$i = 0;

$query = sprintf(
"SELECT DJ.id_distinction_joueur,
DJ.id_distinction,
DJ.id_joueur,
J.nom_joueur,
D.nom_distinction
FROM distinction_joueur AS DJ
LEFT JOIN joueurs AS J ON J.id_joueur = DJ.id_joueur
LEFT JOIN distinctions AS D ON D.id_distinction = DJ.id_distinction
ORDER BY id_distinction_joueur DESC
LIMIT %d, 50;",
$positionnement
);

$result = mysql_query($query) or die('Erreur : $distinction_joueur : '. mysql_error());

while($line = mysql_fetch_assoc($result)){
$distinction_joueur[] = $line;
$i++;
}

if($i == 0 && $positionnement > 0){
return ajax_liste_derniere_distinction_joueur($positionnement - 5);
}

return $distinction_joueur;
}

J'ai essayé de deviner un peu tes noms de table pour la jointure, peut-être me suis-je planté mais je pense que tu comprendras. ^^

Ces changements dans la fonction font que tu auras un tableau plus brut puisque tes index suivent l'ordre naturel et que le nombre de distinctions est simplement donné par la taille du tableau :


[
{
"id_distinction_joueur": "2",
"id_distinction": "67",
"id_joueur": "2",
"nom_joueur": "keke_admin",
"nom_distinction": "Nerd"
},
{
"id_distinction_joueur": "1",
"id_distinction": "69",
"id_joueur": "2",
"nom_joueur": "keke_admin",
"nom_distinction": "Mathusalem"
}
]

Et dans ton callback, tu peux alors remplacer tableau_data.nb par tableau_data.length !

Voilà, voilà pour mes quelques suggestions d'avant pieutage ! Smile


Sephi-Chan


RE: Laideur du code Javascript - keke - 29-06-2010

Coucou,

Pour la jointure, tu as presque eu raison ^^. le truc, c'est que historiquement, la clé sur la table joueur est 'id_num_perso'.

par contre, pourquoi mettre des left join, au lieu de jointure classique ? C'est une habitude de programmation ?

Je n'ai pas bien compris ta remarque sur GetJson. Pourrais-tu écrire le code correspondant ? J'ai essayé à tâtons tout un tas de combinaison, mais je n'ai trouvé de bonne que celle qui est écrite.

Bon, ce soir (ou du moins, un soir de la semaine) je vais essayer de coder le javascript qui permet de faire défiler les résultats ... D'y penser, ça me donne des petits frissons ...

kéké


RE: Laideur du code Javascript - Ter Rowan - 29-06-2010

réflexion au delà de l'exercice mais plus fonctionnelle

je pne pense pas que pour des distinctions/hauts faits, il soit nécessaire de rafraichir toutes les 5 secondes :

autant pour l'exercice,y arriver c'est bien, autant pour l'intérêt des joueurs, je trouve pas cela utile

- est utile de connaître les distinctions en temps réel des autres joueurs ? ou un rafraichissement toutes les x minutes (10, 20 30 ?) ne suffiraient pas ?

- concernant les distinctions du joueur lui même, la question du temps réel ne se pose pas mais elle peut être résolue directement par le script d'action qui outre la réponse, générerait la distinction (pas sûr d'être clair là ^^)


RE: Laideur du code Javascript - Sephi-Chan - 29-06-2010

(29-06-2010, 09:45 AM)keke a écrit : par contre, pourquoi mettre des left join, au lieu de jointure classique ? C'est une habitude de programmation ?

En effet, c'est plus une habitude qu'autre chose. Le LEFT JOIN fait que tu auras ta ligne dans le jeu de résultat même si la jointure échoue (par exemple si le joueur n'existe pas pour l'ID données, la colonne nom_joueur sera NULL). Avec un INNER JOIN (ou JOIN, puisque le INNER est implicit), si l'une des jointures n'est pas satisfaite, la ligne n'est pas du tout ajoutée au jeu de résultat.

Dans ce cas précis, si ce cas arrive, c'est que tes données ont été corrompues puisqu'une table de jointure ne devrait jamais faire référence à des éléments inexistants. Tu peux donc largement utiliser INNER JOIN. Smile


(29-06-2010, 09:45 AM)keke a écrit : Je n'ai pas bien compris ta remarque sur GetJson. Pourrais-tu écrire le code correspondant ? J'ai essayé à tâtons tout un tas de combinaison, mais je n'ai trouvé de bonne que celle qui est écrite.


$.getJSON(
"ajax_liste_distinction_desc.php",
{ positionnement: compteur },
function(datas){
texte_id_distinction = "";
nb_distinction = datas.length;
$("#tableau_dynamique").html(
compteur + ' vs ' + nb_distinction + ' Recherche Information via AJAJSON.'
+ 'Nb résultat = ' + datas.nb + ' test = ' + datas[0].id_distinction_joueur
);
}
);

Ici, datas est déjà un objet JSON prêt à l'emploi, comme le montre la documentation de jQuery.getJSON().

Il n'est pas nécessaire de le réévaluer, surtout que l'évaluation par eval() est à proscrire. Le framework dispose d'outils pour faire ça : la librairie JSON2 ou le parser natif du navigateur, s'il est disponible.


Sephi-Chan


RE: Laideur du code Javascript - keke - 29-06-2010

Merci Sephi pour les explications. Je vais utiliser data tel quel tu as raison.

(29-06-2010, 09:55 AM)Ter Rowan a écrit : réflexion au delà de l'exercice mais plus fonctionnelle

je pne pense pas que pour des distinctions/hauts faits, il soit nécessaire de rafraichir toutes les 5 secondes :

autant pour l'exercice,y arriver c'est bien, autant pour l'intérêt des joueurs, je trouve pas cela utile

- est utile de connaître les distinctions en temps réel des autres joueurs ? ou un rafraichissement toutes les x minutes (10, 20 30 ?) ne suffiraient pas ?

Coucou,

Tu as totalement raison dans le raisonnement. C'est d'ailleurs ce que fais mon script ^^.
En fait, mon script va chercher un tas d'informations en base de donnée au début, puis, toutes les 5 secondes, il se contente d'afficher la donnée (sans rechercher de nouveau en base). Lorsqu'il a épuisé son tas d'information, il va en chercher à nouveau.

Dans mon exemple, il va chercher 2 distinctions (nerd et mathusalem) en base de donnée, qu'il affiche l'un après l'autre. Ensuite, il va rechercher de nouveau 2 distinctions.

J'avais prévu 50 distinctions max. Ce qui fait 50 * 5 secondes ... hum (j'ai un peu de mal) un refresh base de données toutes les 4 minutes et des brouettes.

Merci d'avoir souligné ce point. D'autres auraient pu se poser des questions ^^.

kéké