Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 14 sur 14
  1. #1
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut Animation produite par une procédure récursive

    Bonjour !

    Dans le cadre du défi Pascal j'ai écrit un petit programme qui génère un labyrinthe et cherche un chemin d'un point à un autre. La recherche progresse par récursion. A l'entrée de la procédure je dessine un petit carré à la position courante, et à la sortie je l'efface, sauf si le point d'arrivée est atteint, auquel cas le programme s'arrête et laisse voir le chemin parcouru.

    Code :
    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
    procedure tDemo.ChercheCentre(aL: tLabyr; aX, aY: integer);
    var
      i, dX, dY, lX, lY: integer;
      arret: boolean;
    begin
      if (aX<1) or (aX>19) or (aY<1) or (aY>19) then
        Exit;
      Carre(aX, aY, c1, c2);
      fil[aX, aY] := TRUE;
      if aX * aY = 100 then
        trouve := TRUE;
      for i := 0 to 3 do
      begin
        lX := aX + croix[i,0];
        lY := aY + croix[i,1];
        arret := fil[lX, lY]
          or (aL[lX div 3, lY div 3][lX mod 3, lY mod 3] = 1)
          or trouve;
        if not arret then
          ChercheCentre(aL, lX, lY);
      end;
      if not(trouve or (aX*aY = 1)) then
        Carre(aX, aY, Asparagus, Asparagus);
      if not trouve then
        fil[aX, aY] := FALSE;
    end;
    Mais de cette façon on ne voit pas les évolutions du chemin.

    J'ai écrit le même programme pour FreePascal avec l'unité WinGraph : il m'a suffi de mettre un Sleep() après le dessin du petit carré pour obtenir l'effet désiré (voir pièce jointe).

    Mais pour une animation Flash ça ne peut pas convenir, n'est-ce pas ? Comment vous y prendriez-vous pour faire une chose de ce genre avec FlashPascal ?
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  2. #2
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    Un exemple simple pour faciliter la discussion. Le programme dessine dix traits bleus en entrant dans la procédure, et il les redessine en vert en sortant ; mais on ne le voit pas.

    J'ai déclaré une horloge mais pour le moment je ne sais pas quoi en faire.

    Code :
    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
    program Etude2;
     
    {$FRAME_WIDTH 330}
    {$FRAME_HEIGHT 200}
    {$FRAME_RATE 12}
    {$BACKGROUND $d0d0d0}
     
    uses
      Flash8;
     
    type
      tHorloge = class(MovieClip)
        procedure onEnterFrame; override;
      end;
     
    procedure tHorloge.onEnterFrame;
    begin
    end;
     
    procedure Trait(n: integer);
    begin
      _root.lineStyle(10, $0000FF);
      _root.MoveTo(30*n,30);
      _root.LineTo(30*n,170);
     
      if n < 10 then Trait(n+1);
     
      _root.lineStyle(10, $00FF00);
      _root.MoveTo(30*n,30);
      _root.LineTo(30*n,170);
    end;
     
    begin
      tHorloge.Create;
      _root.LineTo(330, 200);
      _root.opaqueBackground := $f0f0f0;
      stage.scaleMode := 'noScale';
      Trait(1);
    end.
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  3. #3
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro Paul TOTH
    Freelance
    Inscrit en
    novembre 2002
    Messages
    5 565
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul TOTH
    Âge : 45
    Localisation : Réunion

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 5 565
    Points : 15 892
    Points
    15 892

    Par défaut

    Salut,

    voici ce qu'il est possible de faire
    Code :
    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
     
    program Etude2;
     
    {$FRAME_WIDTH 330}
    {$FRAME_HEIGHT 200}
    {$FRAME_RATE 12}
    {$BACKGROUND $d0d0d0}
     
    uses
      Flash8;
     
    type
      tHorloge = class(MovieClip)
        line : Integer;
        procedure onEnterFrame; override;
      end;
     
    procedure tHorloge.onEnterFrame;
    begin
      if line < 10 then
      begin
        Inc(line);
        _root.lineStyle(10, $00FF00);
        _root.MoveTo(30*line,30);
        _root.LineTo(30*line,170);
      end;
    end;
     
    procedure Trait(n: integer);
    begin
      _root.lineStyle(10, $0000FF);
      _root.MoveTo(30*n,30);
      _root.LineTo(30*n,170);
     
      if n < 10 then Trait(n+1);
    {
      _root.lineStyle(10, $00FF00);
      _root.MoveTo(30*n,30);
      _root.LineTo(30*n,170);
    }
    end;
     
    begin
      tHorloge.Create(nil, '', 1);
      _root.LineTo(330, 200);
      _root.opaqueBackground := $f0f0f0;
      stage.scaleMode := 'noScale';
      Trait(1);
    end.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal
    Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%

  4. #4
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    Merci Paul pour cet exemple.

    Donc, si je comprends bien, il faut que je repense ma procédure de recherche, qui au lieu de s'appeler elle-même serait appelée à répétition par la procédure onEnterFrame.

    C'est un exercice intéressant. Je ne vois pas encore trop comment faire mais je vais y réfléchir.
    L'Art est long et le Temps est court.

  5. #5
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro Paul TOTH
    Freelance
    Inscrit en
    novembre 2002
    Messages
    5 565
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul TOTH
    Âge : 45
    Localisation : Réunion

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 5 565
    Points : 15 892
    Points
    15 892

    Par défaut

    oui c'est ça en gros

    je suppose que tu utilises une procédure récursive qui garde trace du dernier déplacement, le retour l'annule automatiquement.

    et bien tu dois garder cette information dans une variable d'état globale...probablement un tableau qui garde la trace des directions prises à la profondeur "n". C'est un array of de Record reprenant les variables locales de ta procédure et au lieu de faire un appel récursif tu passes à l'indexe suivant dans le tableau.

    dans un premier temps tu peux remplacer ton appel récursif par une boucle While, ensuite tu remplacera la boucle While par les appels successifs de onEnterFrame. Sous Delphi ça revient à OnIdle quand tu veux faire une tâche par étapes sans passer par un Thread secondaire...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal
    Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%

  6. #6
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    J'ai réussi !

    Code :
    1
    2
    3
    4
    procedure tMovieClip.onEnterFrame;
    begin
      Marche(g_X, g_Y, labyr);
    end;
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  7. #7
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    Une version améliorée, qui se réinitialise automatiquement tant que le centre du labyrinthe n'a pas été atteint.

    C'est curieux, l'animation ralentit au fur et à mesure.
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  8. #8
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro Paul TOTH
    Freelance
    Inscrit en
    novembre 2002
    Messages
    5 565
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul TOTH
    Âge : 45
    Localisation : Réunion

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 5 565
    Points : 15 892
    Points
    15 892

    Par défaut

    Citation Envoyé par Roland Chastain Voir le message
    Une version améliorée, qui se réinitialise automatiquement tant que le centre du labyrinthe n'a pas été atteint.

    C'est curieux, l'animation ralentit au fur et à mesure.
    je ne le constate pas, mais la charge CPU monte en flèche

    ce doit être lié à la façon dont tu gère les carrés. je vois au moins deux façon de faire
    1) créer un nouveau carré rouge à chaque étape
    2) pour le retour, cacher les carrés en trop
    3) réutiliser les carrés cachés en les déplaçant avant d'en créer de nouveau pour le chemin suivant

    ou encore
    créer des carrés dans toutes les cases, par défaut cacher les rouges et ne les afficher que quand c'est nécessaire.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal
    Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%

  9. #9
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    Citation Envoyé par Paul TOTH Voir le message
    créer des carrés dans toutes les cases, par défaut cacher les rouges et ne les afficher que quand c'est nécessaire.
    C'est cette solution que j'ai retenue. Dans la boucle principale, après avoir initialisé le labyrinthe, je "crée" des carrés bleus ou rouges et je rends les rouges invisibles.

    Code :
    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
    { --- Programme principal ---------------------------------------------------- }
     
    var
      i: integer;
     
    begin
      _root.opaqueBackground := WhiteSmoke;
      _root.MoveTo(0, 0);
      _root.LineTo(421, 421);
     
      stage.scaleMode := 'noScale';
     
      labyr := RandomLabyr;
     
      for i := 0 to 440 do
        if labyr[(i mod 21) div 3, (i div 21) div 3][(i mod 21) mod 3, (i div 21) mod 3] = 1 then
          a[i] := tCarre.Create(i + 1, 20 * (i mod 21) + 10, 20 * (i div 21) + 10, SteelBlue, LightSteelBlue)
    	else
    	begin
    	  a[i] := tCarre.Create(i + 1, 20 * (i mod 21) + 10, 20 * (i div 21) + 10, DarkRed, Red);
    	  a[i]._visible := FALSE;
    	 end;
     
      tHorloge.Create;
    end.
     
    { --- Fin du programme principal --------------------------------------------- }
    Merci pour l'idée.

    Par contre je ne sais comment réinitialiser tout. Est-ce que je peux "écraser" mes carrés en appelant de nouveau la méthode Create ?
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  10. #10
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro Paul TOTH
    Freelance
    Inscrit en
    novembre 2002
    Messages
    5 565
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul TOTH
    Âge : 45
    Localisation : Réunion

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 5 565
    Points : 15 892
    Points
    15 892

    Par défaut

    regarde FlashMine, les cellules sont crées une fois pour toute et j'ai des fonctions de dessin pour en changer l'aspect.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    procedure TCell.IsDown(color: Integer);
    begin
      State := -1;
      clear;
      beginFill(color);
      lineStyle(1,$808080);
      moveTo(-7, 7);
      lineTo(-7,-7);
      lineTo( 7,-7);
      lineStyle(1,$c0c0c0);
      lineTo( 7, 7);
      lineTo(-7, 7);
      endFill;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal
    Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%

  11. #11
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    Effectivement, il y a tout dans cet exemple.
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  12. #12
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro Paul TOTH
    Freelance
    Inscrit en
    novembre 2002
    Messages
    5 565
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul TOTH
    Âge : 45
    Localisation : Réunion

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 5 565
    Points : 15 892
    Points
    15 892

    Par défaut

    Pas facile de mesurer l'impact sur la CPU car tu ne cherches qu'un seul chemin (Etude3d bouclait)

    Et je ne comprend pas pourquoi tu interdis le ScaleMode...ton dernier exemple est relativement petit sur mon écran, alors j'ai naturellement tendance à passer le player en plein écran et je me retrouve avec la même chose au milieu d'une grande fenêtre vide sauf à change l'option par défaut "Afficher/100%" en "Afficher/Tout afficher".
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal
    Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%

  13. #13
    Rédacteur/Modérateur
    Avatar de Roland Chastain
    Homme Profil pro Roland Chastain
    Inscrit en
    décembre 2011
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Nom : Homme Roland Chastain
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : décembre 2011
    Messages : 1 389
    Points : 3 820
    Points
    3 820

    Par défaut

    Citation Envoyé par Paul TOTH Voir le message
    Pas facile de mesurer l'impact sur la CPU car tu ne cherches qu'un seul chemin (Etude3d bouclait).
    C'est parce que je n'avais pas eu le temps de finir. Voici la version complète, qui a l'air de tourner plutôt bien.

    Citation Envoyé par Paul TOTH Voir le message
    Et je ne comprend pas pourquoi tu interdis le ScaleMode...ton dernier exemple est relativement petit sur mon écran, alors j'ai naturellement tendance à passer le player en plein écran et je me retrouve avec la même chose au milieu d'une grande fenêtre vide sauf à change l'option par défaut "Afficher/100%" en "Afficher/Tout afficher".
    Disons que je trouve plus simple d'avoir une fenêtre de taille fixe : de cette façon je ne m'inquiète pas du résultat qu'une autre option donnerait. Mais c'est vrai que c'est dommage. Là j'ai supprimé la ligne.

    Pour mon labyrinthe en particulier, j'ai utilisé jusque ici des cases de 20 sur 20 (c'était tout ce qui pouvait tenir dans mon écran, en laissant la place pour la pièce mobile). Au départ je pensais mettre des choses dessus : il fallait de la place pour les dessins. Mais finalement je n'ai que des carrés : du coup les cases de 20 me paraissent grandes. Là ce sont des cases de 10.

    Pour la question que j'ai posée dans le titre, je crois qu'elle est résolue. La procédure récursive a été remplacée et l'animation est fluide (le code est tiré de FlashMine.fpr). Je posterai le code complet après le défi.

    Code :
    1
    2
    3
    4
    5
    6
    procedure tHorloge.onEnterFrame;
    begin
      if Centre then
        Exit;
      if Recul and (g_X * g_Y = 1) then NewGame else Marche;
    end;
    Fichiers attachés Fichiers attachés
    L'Art est long et le Temps est court.

  14. #14
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro Paul TOTH
    Freelance
    Inscrit en
    novembre 2002
    Messages
    5 565
    Détails du profil
    Informations personnelles :
    Nom : Homme Paul TOTH
    Âge : 45
    Localisation : Réunion

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 5 565
    Points : 15 892
    Points
    15 892

    Par défaut

    Super

    je reste persuadé que les gens qui critiquent les performances de Flash qui bouffe toute la CPU font face à des applications développées de la mauvaise façon
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal
    Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •