IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Canvas et affichage de formes


Sujet :

JavaScript

  1. #1
    Membre éclairé
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Par défaut Canvas et affichage de formes
    Bonsoir,

    Dans un canvas, je suis censé créer des formes qui se déplacent aléatoirement.

    J'ai le code suivant, la fonction go() se lance au chargement de ma page :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    var
            gr,
            ctx,        
            vmax = 20,
            w = "650",
            h = "500",
            nbformes = 0,
            tabObjets= new Array(),
            tabTimers= new Array();
     
    function initObjet(objet) {
        objet.x = Math.round(Math.random() * (gr.width - 2 * objet.rayon) + objet.rayon);
        objet.y = Math.round(Math.random() * (gr.height - 2 * objet.rayon) + objet.rayon);
        objet.vx = Math.round((Math.random() - 0.5) * vmax);
        objet.vy = Math.round((Math.random() - 0.5) * vmax);
    }
     
    function getRandomIntegerBorne(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    function affichage(objet) {
        ctx.beginPath();
        ctx.fillStyle = "rgba(255,255,255,0.6)";
        ctx.fillRect(0, 0, gr.width, gr.height);
        ctx.strokeStyle = objet.color;
        ctx.arc(objet.x, objet.y, objet.rayon, 0, 2 * Math.PI);
        ctx.stroke();
        if ((objet.x + objet.vx) <= objet.rayon) {
            objet.vx *= -1;
        } else {
            objet.x += objet.vx
        }
        if ((objet.y + objet.vy) <= objet.rayon) {
            objet.vy *= -1;
        } else {
            objet.y += objet.vy
        }
        if ((objet.x + objet.vx) >= (gr.width - objet.rayon)) {
            objet.vx *= -1;
        } else {
            objet.x += objet.vx
        }
        if ((objet.y + objet.vy) >= (gr.height - objet.rayon)) {
            objet.vy *= -1;
        } else {
            objet.y += objet.vy
        }
    }
     
    function go() {
        document.body.innerHTML += "<canvas id='canvas' width=" + w + " height=" + h + " ></canvas>";
        gr = document.getElementById("canvas");
        ctx = gr.getContext("2d");   
        nbformes = getRandomIntegerBorne(2, 10);
        nbformes=5;    
        for (i = 0; i < nbformes; i++) {
            tabObjets[i] = {x: 0, y: 0, vx: 0, vy: 0, rayon: 15, couleur: "red"},
            initObjet(tabObjets[i]);
            z=50+(10*i);
            tabTimers[i] = setInterval(function(){ affichage(tabObjets[i]); }, z);        
        }
    }
    Le problème est que je passe bien dans la boucle, dans la fonction affichage, mais que rien ne se passe.
    Si je fais qq chose comme ça en dur, ça marche ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    tabTimers[0] = setInterval(function() { affichage(tabObjets[0]); }, 50);
        tabTimers[1] = setInterval(function() { affichage(tabObjets[1]); }, 60);
        tabTimers[2] = setInterval(function() { affichage(tabObjets[2]); }, 70);
        tabTimers[3] = setInterval(function() { affichage(tabObjets[3]); }, 80);
    :
    Help, je ne vois pas mon erreur !!!

    De plus, y a-t-il une fonction capable de détecter la superposition des objets.

    Merci beaucoup

  2. #2
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2016
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2016
    Messages : 225
    Par défaut
    Bonjour,

    As tu effectué l'appel de la fonction go ?

    Peux tu mettre à jour ton code ainsi et nous dire si tout est bon pour toi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
     
    function go() {
        document.body.innerHTML += "<canvas id='canvas' width=" + w + " height=" + h + " ></canvas>";
        gr = document.getElementById("canvas");
        ctx = gr.getContext("2d");
        nbformes = getRandomIntegerBorne(2, 10);
        nbformes=5;
        for (i = 0; i < nbformes; i++) {
            tabObjets[i] = {x: 0, y: 0, vx: 0, vy: 0, rayon: 15, couleur: "red"},
            initObjet(tabObjets[i]);
            z=950+(10*i);
    // changement ici
            tabTimers[i] = setInterval(function(){
            console.log(i);
            affichage(tabObjets[i]); }, z);
    // changement ici
        }
    }
    http://stackoverflow.com/questions/1...ous-loop-issue

  3. #3
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2016
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2016
    Messages : 225
    Par défaut
    > De plus, y a-t-il une fonction capable de détecter la superposition des objets.

    Non. Il faut que tu fasses des calculs de colllisions à chaque itération de la boucle d'affichage pour savoir si tel objet en surperpose un autre.

    Du coup, ca vaut le coup d'utiliser des frameworks dédiés pour ce genre de tâche.

  4. #4
    Membre éclairé
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Par défaut
    Merci pour les réponses, effectivement dans la console j'ai ceci :

    Nom : CaptureJS.JPG
Affichages : 109
Taille : 70,3 Ko

    En fait, il n'accède pas aux propriétés de l'objet objet dans affichage quand je suis dans la boucle !
    Y a-t-il un mécanisme de mappage ? ça pourrait venir de là ! (object)objet ?

    Merci pour votre aide

  5. #5
    Membre éclairé
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Par défaut
    effectivement je pense qu'un framework ferait ça très bien !
    Merci

  6. #6
    Membre éclairé
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Par défaut
    J'ai rogressé, mais je ne comprends pas ce qui se passe
    Voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for (i = 0; i < nbformes; i++) {
            z = 50 + 10 * i;
            unObj=tabObjets[i];
            tabTimers[i] = setInterval(function() { affichage(unObj); }, 50);
            unObj=null;
        }
        i=0;
        unObj=tabObjets[i];
        tabTimers[i] = setInterval(function() { affichage(unObj); }, 50);
    En fait quand je suis dans la boucle, il n'appelle pas la fonction affiche, qund je suis sorti de la boucle, sur la partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    i=0;
        unObj=tabObjets[i];
        tabTimers[i] = setInterval(function() { affichage(unObj); }, 50);
    Il rentre dans la boucle !
    Et pourtant copier/coller de l'instruction setInterval !!!
    Merci pour les explications je ne comprends pas ce qu'il se passe !!!

  7. #7
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2016
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2016
    Messages : 225
    Par défaut
    Alors, deux trois petits trucs, depuis ton code initial,

    lit bien le message d'erreur de la console, il te dit que objet.color n'existe pas. Car objet est indéfinit.

    Pourquoi ?

    Encore une fois bien lire la sortie de la console, pour le nouveau contexte déclaré via setInterval dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setInterval(function() { affichage(tabObjets[i]); }, 50);
    La console indique
    Hors, si tu as bien 5 éléments dans ton tableau, l'index maximum est 4.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var tableau = [0, 1, 2, 3, 4]
    contient bien 5 éléments, mais n'a pas d'index 5.

    Maintenant, il faut comprendre pourquoi dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setInterval(function() { affichage(tabObjets[i]); }, 50);
    Et là c'est pas simple à expliquer

    Ce qu'il faut tout d'abord comprendre,

    En JS les variables sont attachées aux scope de la fonction dans lesquelles elles sont déclarées,
    que dans ce cas elles ce comportent comme des membres d'objets

    Ici i est attaché aux contexte de go,
    La boucle for s'execute et change a valeur de go.i (grossièrement) de 0 à 5.

    Hors setInterval s'exécute après que l'intégralité de la boucle for ait était executée, et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setInterval(function (){ console.log(i); });
    référence go.i

    Donc quand la fonction de setInterval s'execute go.i=5.

    Hors il n'y à pas d'index 5 dans tabOjets, donc pas d'objet avec une propriété color.

    Bref, reste plus qu'à résoudre le problème.

    On va séparer la partie procédurale de la partie asynchrone, et uitliser une fonction pour scoper nos variable le cas échéant.

    On va repartir de ce bout de code,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for (i = 0; i < nbformes; i++) {
      tabObjets[i] = {x: 0, y: 0, vx: 0, vy: 0, rayon: 15, couleur: "red"},
      initObjet(tabObjets[i]);
      z=50+(10*i);
      tabTimers[i] = setInterval(function(){ affichage(tabObjets[i]); }, z);        
    }
    Faire le tri entre procédural et asynchrone :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // procédural
    for (i = 0; i < nbformes; i++) {
      tabObjets[i] = {x: 0, y: 0, vx: 0, vy: 0, rayon: 15, couleur: "red"},
      initObjet(tabObjets[i]);
      z=50+(10*i);
      // procédural
      // asynchrone
      tabTimers[i] = setInterval(function(){ affichage(tabObjets[i]); }, z);
      // asynchrone
      // procédural
    }
    // procédural
    Donc,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (i = 0; i < nbformes; i++) {
      tabObjets[i] = {x: 0, y: 0, vx: 0, vy: 0, rayon: 15, couleur: "red"},
      initObjet(tabObjets[i]);
    }
    Maintenant pour gérer la partie asynchrone, on va introduire une nouvelle méthode de Array: Array.forEach(fn)

    L'avantage de cette notation est qu'elle te force à déclarer une fonction, et à travailler en son sein, te permettant de t'aider à éviter ce piège asseez commun,

    On va utiliser tabObjets et itérer dessus,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    tabObjets.forEach(function(obj, i){
      var z = 50 + (10 * i);
      setInterval(function(){ affichage(obj); }, z); 
    })
    Finalement, j'ai volontairement évité ton dernier code car il ne résout pas le problème initial, il le repète, et qu'il complexifie mon explication déjà laborieuse.

    hth

  8. #8
    Membre éclairé
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Par défaut
    Merci beaucoup pour cette leçon JS, je vais voir ça demain matin tranquillement. En tous cas ça marche.
    J'avais oublié d'enlever nbFormes=5;

    En tous cas un grand merci. Beaucoup de pédagogie et de temps passé à me répondre.
    Bonne fin de soirée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage sous forme de colonnes
    Par harris_macken dans le forum MATLAB
    Réponses: 4
    Dernier message: 02/04/2007, 15h02
  2. Webcam, affichage dans Form
    Par swissbaboon dans le forum C++Builder
    Réponses: 4
    Dernier message: 19/11/2006, 23h16
  3. Affichage bizarre (forme de carré)
    Par Houssem dans le forum WinDev
    Réponses: 1
    Dernier message: 02/08/2006, 13h14
  4. Evenement affichage de form
    Par chourmo dans le forum Delphi
    Réponses: 4
    Dernier message: 11/07/2006, 16h42
  5. [MySQL] Problème d'affichage sous forme de tableau
    Par mogway95 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 01/03/2006, 16h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo