JeuWeb - Crée ton jeu par navigateur
[javascript]compte à rebours - 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 : [javascript]compte à rebours (/showthread.php?tid=337)



[javascript]compte à rebours - gtsoul - 18-10-2006

Bonjour bonjour,

encore un problème javascript.
J'utilise un système de temps réel différé mon gérer mes actions. En gros chaque action coute du temps (qques secondes). Cela me sert à brider les gros-bills de la souris et donne lieu à quelques sorts/malus bien sympas.

Cela se présente sous la forme d'un timestamp que j'augmente au fur et à mesure des actions effectuées. Si la valeur du time() actuel est inférieur au timestamp d'action, l'action est bloquée (le personnage est alors occupé à qque chose d'autre); sinon l'action s'effectue.

Lorsqu'il y a attente, j'affiche dans un coin, le nombre de secondes à patienter. Grâce à php, j'affiche un nb fixe et exact; mais surtout fixe.
Donc j'ai eu l'idée d'utiliser un chronomètre en javascript pour décompter ce temps d'attente sans avoir à recharger la page.

Ce système marchait fort bien en local et sous free.
J'ai recemment migré sous ovh, et bien que la valeur time() de php soit correcte; la valeur time() (ou Date() ) de javascript varie selon le temps. Sachant que cet écart peut parfois attendre 100 s, pour une valeur à mesurer de qques secondes, cela fout en l'air mon système.

Donc je cherche un système de compte à rebours fiable, qui ne prenne pas compte de cette fonction javascript.

merci


RE: [javascript]compte à rebours - gtsoul - 18-10-2006

ci joint mon code (pour exemple) :

date est le timestamp seuil à partir duquel une nouvelle action est possible

Code PHP :
<?php 
function counter(date)
{
now = new Date();
time_now = now.getTime();
time_next = date;
var
rebours = ''+time_next*1000-time_now+'';
n_f = rebours.length;
n_d = n_f-3;

if(
document.getElementById)
{
if(
rebours > 0)
{
document.getElementById("rebours_time").innerHTML = "<span class='alert'>"+rebours.substring(0, n_d)+"</span>";
}
else
{
document.getElementById("rebours_time").innerHTML = "<span class='bon'>ok</span>";
}
}
else if(
document.all)
{
if(
rebours > 0)
{
document.all["rebours_time"].innerHTML = "<span class='alert'>"+rebours.substring(0, n_d)+"</span>";
}
else
{
document.all["rebours_time"].innerHTML = "<span class='bon'>ok</span>";
}
}
}

Code PHP :
<?php 
<script language="JavaScript" type="">window.setInterval("counter(<?php echo($perso1->prochaine_action); ?>)",1000);</script><?php
$attente
= $perso1->prochaine_action-time();
if(
$attente<=0)
echo(
'<span id="rebours_time" class="bon">ok</span></div>');
else
echo(
'<span id="rebours_time" class="alert">'.$attente.'</span></div>');



RE: [javascript]compte à rebours - naholyr - 18-10-2006

Tu calcules un compte à rebours, d'une valeur B vers une valeur A. Ces deux valeurs sont fournies par une source S, et le compte à rebours est géré par un tiers. Ce tiers n'a probablement pas les mêmes référentiels, si tu ne lui fournis que A, il ne sera jamais certain que la source et le tiers ont bien la même valeur pour B. Donc il faut soir fournir A et B, soit fournir A-B.

C'est d'autant plus vrai quand A et B sont des dates : il n'y a qu'une chance infime que ton visiteur ait exactement la même tranche horaire que ton serveur.


RE: [javascript]compte à rebours - gtsoul - 19-10-2006

j'en suis conscient naholyr, et c'est pour cela que je souhaite m'affranchir des dates;
mais je ne maitrise pas suffisament le javascript pour appliquer cette idée.

La fonction date() était fort pratique car elle augmentait toute les secondes (logique !!), donc par soustraction l'attente décrémentait à chaque seconde; mais par quoi la remplacer ?


RE: [javascript]compte à rebours - naholyr - 19-10-2006

Allons allons, si tu as su comment faire un compte à rebours en utilisant les dates, tu sauras bien le faire en utilisant une durée en secondes Wink

Un petit exemple :
Code :
var monLayer = document.getElementById('affichageCompteARebours');

function afficherCompteARebours(dureeRestante) {
  monLayer.innerHTML = dureeRestante + " secondes...";
}

function compteARebours(dureeRestante, actionFinale) {
  afficherCompteARebours(dureeRestante)
  if (dureeRestante == 0) {
    actionFinale();
  }
  else {
    setTimeout("compteARebours(" + (dureeRestante-1) + ")", 1000);
  }
}

compteARebours(<?php echo $dureeEnSecondes; ?>, function(){ alert('fini !') });

On peut affiner le code pour palier aux éventuels retard pris par la fonction setTimeout (en notant la date de début au moment du démarrage du chrono, puis en vérifiant à chaque fois par rapport à la date actuelle au lieu de simplement se baser sur "dureeRestante", ce sera valide puisqu'on reste dans le référentiel du tiers pour les deux dates), voire utiliser setInterval (bien plus indiqué ici, mais moins bien supporté en général quoique ce n'est plus vrai aujourd'hui).
Ceci devrait fonctionner, bien sûr tu auras toujours des écarts puisque PHP va générer une durée sans tenir compte du temps que la page va mettre à parvenir jusqu'au visiteur. Bien souvent ce sera négligeable, mais en cas d'embouteillage si ta page met 4 secondes à parvenir au visiteur, il aura autant de décalage par rapport à la réalité. C'est de toute façon inévitable : tu pourrais aussi avec un peu d'Ajax aller te resynchroniser sur le serveur à intervalles réguliers, mais ça surchargerait ton serveur de requêtes et finirait probablement par avoir l'effet inverse en cas de forte affluence, donc autant accepter ces erreurs minimes en en étant conscient.

Idéalement tu devrais encapsuler ça dans une calsse CompteARebours afin d'avoir un code plus propre, et pouvoir faire des initialisations de ce genre
Code :
var chrono = new CompteARebours(duree);
chrono.layer = 'affichageCompteARebours';
chrono.start();