JeuWeb - Crée ton jeu par navigateur
Setinverval sur fonctions dynamiques - 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 : Setinverval sur fonctions dynamiques (/showthread.php?tid=7191)



Setinverval sur fonctions dynamiques - Soleo - 09-07-2014

Bonjour !

Me voici face à un problème qui selon moi est censé être résolu mais étrangement ne l'est pas, je pense donc manquer de connaissance sur le fonctionnement exact de ce que je vais vous exposer.

Problème : Afficher une liste de constructions en cours avec pour chacune leurs compteur de temps restant respectif.

Interprétation : Faire un nombre indéfini de fois un setInterval sur ce même nombre de fonction décrémentant le temps restant pour chaque construction (Le nombre de constructions en cours étant donc ce nombre indéfini).

Code (Du moins les parties utiles) :

Code PHP :
<?php 
print("Construction en cours : </br>");
while(
$listeconstruction = $result->fetch_assoc())
{
$tempsPasse = microtime(true) - $listeconstruction['depart'];
$tempsRestant = (int)($listeconstruction['duree'] - $tempsPasse);
print(
$listeconstruction['nom']."
Temps Restant : <span id=\"duree"
.$listeconstruction['id']."\"></span>");
}

Jusqu'à là j'affiche donc la liste de mes construction sans rien, pas de soucis.
Voici le javascript

Code :
<script type="text/javascript">
var tempsRestant = parseFloat('<?php echo $tempsRestant; ?>');
var i = ('<?php echo $listeconstruction["id"]; ?>');
window["tempsConstruction"+i] = tempsRestant;
//alert("La fonction crée va être celle de l'id"+i);
window['temps'+i] = function(o)
{
    alert("Le temps décrémenté est celui de l'id :"+o);
    window["tempsConstruction"+o]--;
    if(window["tempsConstruction"+o]<=0)
    {                        
            document.getElementById('duree'+o).innerHTML = "Terminé";
        document.location.href="batiment.php?finish=true";
    }
    else
            document.getElementById('duree'+o).innerHTML =
            secondsToTime(parseInt(window["tempsConstruction"+o]));    
}
alert("La fonction intervalée va etre l'id :"+i);
setInterval(function() { window['temps'+i](i); }, 1000);
</script>

Voilà, en gros j'essaye de faire en sorte que si j'ai 3 constructions, ce soit 3 fonctions
temps1, temps2 et temps3 qui s'activent et qui agissent chacune sur respectivement tempsConstruction1, tempsConstruction2, tempsConstruction3.

Pourquoi ne pas tout simplement avoir fait une seule fonction qui en fonction du paramètre changerai ce span là ? Eh bien j'ai commencé par ça, mais comme le résultat n'était pas celui attendu, j'ai "supposé" que des setInterval sur des fonctions du même nom s'annulaient, d'où cette méthode.

Résultats :

Avec une seule construction, tout marche bien.
Avec plus d'une, seulement la dernière de la liste est décrémentée (du nombre de constructions en cours) Mes alert m'indiquent effectivement que c'est le dernier id qui est pris en compte, alors que pourtant chaque fonction est censée agir sur un id propre (l'utilisation des window[variable])

Y a t'il un quelconque mécanisme obscur dont je ne connaîtrais pas l'existence provoquant cela ? Ai-je loupé quelque chose de très simple ? Je suis presque sûr d'avoir bien vérifié la portée de chaque variable incriminée, d'où mon incompréhension, et qui plus est, mon post sur ce forum.

Cordialement !


RE: Setinverval sur fonctions dynamiques - niahoo - 09-07-2014

ton var i est global. il est écrasé par tes blocks scripts successifs.

Pourquoi ne fais-tu pas une seule fonction que tu appelles une seule fois ?

tu écris tes span dans le genre

Construction 1 - Temps Restant : <span id="decompte-123" data-reste="10">10</span>
Construction 2 - Temps Restant : <span id="decompte-456" data-reste="50">50</span>
<script>
var constructionsIDs = [123,456]; // à remplir en PHP
setInterval(function(){
constructionsIDs.each(function(id) {
var span = document.getElementById('decompte-'+id);
var duree = parseInt(span.getAttribute('data-reste'));
if (duree === 1) {
// ici la construction était à 1 donc on est maintenant à 0
// ici tu peux lancer ton autre page
} else {
span.setAttribute('data-reste',duree - 1);
span.innerHTML = duree - 1;
}
}
},1000);
</script>



RE: Setinverval sur fonctions dynamiques - Ter Rowan - 09-07-2014

à noter je ne suis pas sûr que le data-reste soit utile : tu as déjà la donnée dans le span

avec un span.innerHTML = parseInt(span.innerHTML) -1;


RE: Setinverval sur fonctions dynamiques - niahoo - 09-07-2014

Oui tout à fait mais je me suis dit que dans le span tu veux pouvoir mettre "x secondes restantes".

Bien sûr tu peux mettre "secondes restantes" en dehors du span, mais là encore tu veux pouvoir mettre "x secondes", "x minutes, "00:12:26", etc. Je sépare les données de leur représentation.


RE: Setinverval sur fonctions dynamiques - Soleo - 09-07-2014

Mon nombre de secondes est ensuite formaté grâce à une méthode JS,

Dans tous les cas, j'ai réussi grâce à ta méthode !
Le problème est donc résolu, merci beaucoup !