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

 Delphi Discussion :

Objet Balle dans un form


Sujet :

Delphi

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Objet Balle dans un form
    Salut à tous,

    je dois faire un objet balle pour les cours et la faire rebondir dans un form.
    Je m'esquinte la dessus de puis hier soir, et ca bug, mais je ne comprend spas pq...
    voici mon code:
    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
     
    unit balls;
     
    interface
     
      uses sysutils, forms, graphics;
     
      TYPE TBall = CLASS (TOBJECT)
        x1, x2, y1, y2, step_x, step_y : integer;
     
     
      END;
     
      Procedure Create_Ball(dest:TForm; ball:TBall);
      Procedure Move_Ball(dest:TForm; ball:TBall);
     
    implementation
     
      var dest:TForm;
     
      procedure Create_Ball (dest:TForm;ball:TBall);
        begin
          dest.Canvas.Pen.Color:=clblack;
          dest.Canvas.Ellipse(ball.x1, ball.y1, ball.x2, ball.y2);
        end;
     
      procedure bounce(var ball:TBall);
        begin
          if (ball.x1<=0) or (ball.x2>=dest.clientwidth) then
            ball.step_x:=-ball.step_x
            else
              if (ball.y1<=0) or (ball.y2>=dest.clientheight) then
            ball.step_y:=-ball.step_y;
        end;
     
      procedure Move_Ball(dest:TForm; ball:TBall);
        begin
          dest.Canvas.Pen.Color:=clbtnface;
          dest.Canvas.Ellipse(ball.x1, ball.y1, ball.x2, ball.y2);
          ball.x1:=ball.x1+ball.step_x;
          ball.x2:=ball.x2+ball.step_x;
          ball.y1:=ball.y1+ball.step_y;
          ball.y1:=ball.y1+ball.step_y;
          bounce(ball);
        end;
    end.

    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
     
    unit form;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, balls, ExtCtrls, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
     
    implementation
    var ball1:TBall;
     
     
    {$R *.dfm}
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      doublebuffered:=True;
      ball1.x1:=0;
      ball1.x2:=0;
      ball1.y1:=10;
      ball1.y2:=10;
      ball1.step_x:=5;
      ball1.step_y:=5;
      Create_Ball(Form1, ball1);
    end;
     
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      Move_Ball(Form1, Ball1);
      Create_Ball(Form1, Ball1);
    end;
     
    end.
    Si quelqu'un a une petite piste pour moi, n'hésitez pas...
    Merciii !!

  2. #2
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut et bienvenue

    Tu peux peut-être t'inspirer des propositions faites dans cette discussion: Comment simuler la chute du curseur ? , notamment celle de Waskol (et puis la mienne aussi).

    A adapter, mais c'est une bonne base de départ.

    @+ Claudius.

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    alors le truc, c'est que j'arrive à le faire correctement
    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
    63
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;
     
    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        procedure Button1Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
        procedure FormShow(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
      x1, y1, x2, y2, px, py : integer;
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      //canvas.ellipse((self.ClientWidth div 2) - 15, (self.ClientHeight div 2) - 15 ,(self.ClientWidth div 2) + 15, (self.ClientHeight div 2) + 15 );
      //canvas.Pixels[self.clientWidth div 2,self.ClientHeight div 2]:=clRed;
     
    end;
     
    procedure TForm1.FormShow(Sender: TObject);
    begin
      x1:=0;
      y1:=0;
      x2:=10;
      y2:=10;
      py:=1;
      px:=1;
    end;
     
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    canvas.Pen.Color:=clred;
    //canvas.Brush.Color:=clblue;
    x1:=x1+px;
    y1:=y1+py;
    x2:=x2+px;
    y2:=y2+py;
    canvas.Ellipse(x1, y1, x2, y2);
    if (x2>=clientwidth) or (x1<= 0) then
      px:=-px
      else
      if (y2>=clientheight) or (y1<=0) then
      py:=-py;
     
    end;
     
    end.
    mais pas en mettant la balle dans une classe, de sorte à pouvoir en générer autant que je veux.

    Any idea en mettant la balle dans une classe ?

  4. #4
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    hehehe, l'exercice de base pour l'animation avec delphi...

    et bien regarde en piece jointe, ce n'est pas 1 mais 2 demos
    l'une est commenté l'autre est une recopie de mon jeux BuBulle un peu modifié.

    tu y verras deux méthode différente pour faire bouger les sprites.
    dans Baballs1, j'utilise des sinus et cosinus
    dans Baballs2, j'utilise de simple additions et soustraction (comme dans ton exercice).

    l'exemple avec Sin/Cos montre bien comment on peut obtenir des trajectoires beaucoup plus fluides et différentes.
    Fichiers attachés Fichiers attachés
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Les Gars, vos sources, c'est gentil, cela ne va pas l'aider pour comprendre l'objet, son problème ce n'est pas l'algo mais l'architecture du code ... il apprend à développer, c'est pas en lui donnant du code que cela lui servira, tient ça me rappelle une histoire de pêcheur ...

    @intheair, relit ton cours sur l'objet, tu verras une notion d'encapsulation des Traitements et des données au sein d'une même classe
    Ensuite, tu verras aussi la notion d'instanciation (et de libération) des objets

    Bon je tape le code directement sur le forum, j'espère qu'il n'y aura pas d'erreur ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type
      TBall = class(TObject)
      private
        FDestination: TForm;
        procedure Bounce();
      public
        x1, x2, y1, y2, step_x, step_y : integer;
     
        constructor Create(ADestination: TForm);
        procedure Draw();
        procedure Move();
      end;
    Tu encapsule le traitement et la donnée dans le Même Objet, il est là pour cela

    Trois Méthodes
    le constructeur, c'est surtout pour affecter la Destination une bonne fois pour toute ... et c'est plein de concept interessant ... comme inherited ... je te laisse regarder l'aide pour comprendre
    Ton Create_Ball effectivement, il "créait" la Balle d'un point Visuel, mais pas d'un point de vue objet, sa vrai fonction, c'est de dessiner, donc Draw...
    le Move_Ball, était bien nommé, on simplifie ...
    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
    constructor TBall.Create(ADestination: TForm);
    begin
      inherited Create();
     
      FDestination := ADestination;   	
    end;
     
    procedure TBall.Draw();
    begin
      FDestination.Canvas.Pen.Color := clblack;
      FDestination.Canvas.Ellipse(Self.x1, Self.y1, Self.x2, Self.y2); // Self c'est l'instance de TBall, c'est le receveur de la Méthode
    end;
     
    procedure TBall.Move();
    begin
      FDestination.Canvas.Pen.Color:=clbtnface;
      FDestination.Canvas.Ellipse(x1, y1, x2, y2); // Self est implicite !
     
      x1: = x1 + step_x;
      x2 := x2 + step_x;
      y1 := y1 + step_y;
      y1 := y1 + step_y;
     
      Bounce();
    end;
    procedure TBall.Bounce();
    begin
      if (x1 <= 0) or (x2 >= FDestination.ClientWidth) then
         step_ x:= -step_x
      else 
        if (y1  <= 0) or (y2 >= FDestination.ClientHeight) then
           step_y := -step_y;
    end;
    LA Fenêtre qui utilise la Balle ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
        TheBall: TBall; // Ici c'est mieux !
      public
        { Public declarations }
        destructor Destroy; override;
      end;
    Tu notes juste que TheBall fait parti maintenant de la Fenêtre, c'est moche les globales que tu l'avais fait ... normal, on commence tous comme ça ...

    Alors, je commente un peu le code ...
    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
     
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      DoubleBuffered :=True;
     
      TheBall := TBall.Create(Self); // Ben, l'objet, il faut lui donner vie, donc la méthode Create c'est son boulot, cela va allouer  la mémoire nécessaire à l'instance
      // Note que l'on utilise Self qui cette fois si l'instace de TForm1 receveuse de la méthode Button1Click ...
      TheBall.x1:=0;
      TheBall.x2:=0;
      TheBall.y1:=10;
      TheBall.y2:=10;
      TheBall.step_x:=5;
      TheBall.step_y:=5;
      TheBall.Draw(); // Je Dessine, Donc j'appele Draw, TheBall est le receveur de la Méthode ... pas besoin de paramètre 
    end;
     
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      TheBall.Move(); 
      TheBall.Draw();
    end;
     
    destructor TForm1.Destroy; 
    begin
      TheBall.Free(); // Chaque Create doit être accompagné d'un Free ... sinon la mémoire reste occupée ...	
    end;

    Ah, sinon, si j'étais un prof, si je donnais un devoir à mes élèves, je pense que je trouverais très vite ceux qui ont eux la réponse sur le web (surtout sur un site aussi populaire) ... lorsque j'étais à l'école, je n'ai jamais eu besoin de forum pour faire ce genre d'exercice (à l'époque en C et Java), tu devrais plutôt relire tes cours ou demander à ton prof, il est payé pour cela ... pas nous ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    @ShaiLeTroll: C'est pas vraiment un devoir, juste un exercice parmis d'autres...
    Et comme tu le dis, je ne cherche pas le code tout fait mais plus une explication sur mes erreurs... Ce que tu fais très bien et je t'en remercie

    @others...: merci ...

    @+

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 694
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Petite modif'.

    Le Timer calcule le Move et doit rafraîchir la fiche par Invalidate.
    Le Draw devrait être déplacé dans OnPaint .

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Pour les Performances et la réduction des clignotements, AndNotOr, je suis assez d'accord avec toi, mais je pense qu'utiliser les évènements Delphi et l'indirection Invalidate\OnPaint, c'est très intéressant à connaître pour plus tard mais cela risque de l'éloigner de son exercice surement lié à l'utilisation d'objet ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Je commence à y voir un peu plus clair...
    Juste que ma procédure bounce() semble ne pas fonctionner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Procedure TBall.Bounce();
      begin
        if (x1 <= 0) or (x2 >= FDestination.ClientWidth) then
          stepx:=-stepx
        else
        if (y1 <= 0) or (y2 >= FDestination.ClientHeight) then
          stepy:=-stepy;
      end;
    Problème avec ClientWith ? ClientHeight ?
    Quand je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (x1 <= 0) or (x2 >= 100) then
          stepx:=-stepx
        else
        if (y1 <= 0) or (y2 >= FDestination.ClientHeight) then
          stepy:=-stepy;
      end;
    ma balle fait bien demi-tour à 100. Par contre,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    begin
        if (x1 <= 0) or (x2 >= 100) then
          stepx:=-stepx
        else
        if (y1 <= 0) or (y2 >= 50) then
          stepy:=-stepy;
      end;
    ne fonctionne pas pour y mais fait bien demi-tour quand x=100...

  10. #10
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    lorsque j'étais à l'école, je n'ai jamais eu besoin de forum pour faire ce genre d'exercice (à l'époque en C et Java), tu devrais plutôt relire tes cours ou demander à ton prof, il est payé pour cela ... pas nous ...
    T'as du bol, du Java c'est déjà pas mal, t'as pas eu des cours de CICS (et des TP en Eiffel...) toi au moins...

  11. #11
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    as tu regarder ma demo n°2, tu y verra la méthode que tu cherche dans l'unité Balls.


    sinon :


    un objet qui se déplace à donc une coordonné X,Y
    une taille Size
    et deux vitesse X,Y


    ce qui donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    TBall = class
    protected
      function GetSpeed: LongInt;
    public
      positionX, positionY : LongInt;
      Size : LongInt;
      SpeedX, SpeedY : LongInt;
      procedure Move;
    end;
    ce genre de code, necessite une fluidité parfaite, et pour ce faire, il faut eviter d'avoir trop d'appel a des fonctions.
    l'idéal etant de se retrouver avec le minimum possible.

    la procedure GetSpeed et Move donc :

    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
     
    procedure TBall.GetSpeed: LongInt;
    begin
      result := round((random(45)+20)*0.1); (2.0 à 6.5)
    end;
     
    procedure TBall.Move;
    var
      PmX, PmY, PpX, PpY : LongInt;
    begin
      // Move
      PositionX := PositionX + SpeedX;
      PositionY := PositionY + SpeedY;
     
      // Precalculs
      PmX := PositionX - Size;
      PmY := PositionY - Size;
      PpX := PositionX + Size;
      PpY := PositionY + Size;
     
      // Bounce
      if PmX <= { LEFT } then
        SpeedX := GetSpeed
      else
      if PpX >= { RIGHT } then
        SpeedX := -GetSpeed;
     
      if PmY <= { TOP } then
        SpeedY := GetSpeed
      else
      if PpY >= { BOTTOM } then
        SpeedY := GetSpeed;
     
      // BackBuffer Draw 
      BackBuffer.Canvas.Ellipse(PmX, PmY, PpX, PpY);
    end;

    le backbuffer est un bitmap (regarde sa gestion dans la demo baballs2)
    cela permet de gagner des performance d'affichage, dans la demo baballs2 tu peux pousser à 1000 balles avant descendre en dessous de 20FPS.

    je t'explique le principe ?

    en animation, dessiner directement sur le contexte affiché, n'est pas performant du tout et provoque souvent des scintillement, des effets d'escalier ou des saccades.
    les ingenieurs de l'epoque ont vite trouver une solution à ce probleme,
    quand nos petit PC avait moins d'1Ko de memoire video...
    ils ont donc inventé le principe de Double buffer, puis de Triple buffer avec l'apparition des premières carte 3D.
    (voir wikipedia qui explique trés bien le double et triple buffering).
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Euh, j'ai pas testé, le "else" est en trop non, retire le "else" entre les deux if ... il faut toujours tester les DEUX bornes, tu peux les atteindre en même temps ...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Procedure TBall.Bounce();
    begin
      if (x1 <= 0) or (x2 >= FDestination.ClientWidth) then
        stepx:=-stepx;
     
      if (y1 <= 0) or (y2 >= FDestination.ClientHeight) then
        stepy:=-stepy;
    end;
    J'ai copié collé ton Move_Ball sans vérifier, je pense que tu as corrigé toi-même, le doublon de y1 et l'oubli de y2 ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TBall.Move();
    begin
      FDestination.Canvas.Pen.Color := FDestination.Color; // Effacement de l'ancinne position ... même si tu une TForm, cela ne sert pas ... cela ne mémorise pas ...
      FDestination.Canvas.Ellipse(x1, y1, x2, y2); // Self est implicite !
     
      x1: = x1 + step_x;
      x2 := x2 + step_x;
      y1 := y1 + step_y;
      y2 := y2 + step_y;
     
      Bounce();
    end;
    Ou l'init incorrect

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      TheBall.x1:=0;
      TheBall.x2:=10;
      TheBall.y1:=0;
      TheBall.y2:=10;
    Tu nous as glissé plein d'erreur !!!


    Citation Envoyé par peter27x Voir le message
    T'as du bol, du Java c'est déjà pas mal, t'as pas eu des cours de CICS (et des TP en Eiffel...) toi au moins...
    J'ai fait du COBOL aussi ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Euh, j'ai pas testé, le "else" est en trop non, retire le "else" entre les deux if ... il faut toujours tester les DEUX bornes, tu peux les atteindre en même temps ...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Procedure TBall.Bounce();
    begin
      if (x1 <= 0) or (x2 >= FDestination.ClientWidth) then
        stepx:=-stepx;
     
      if (y1 <= 0) or (y2 >= FDestination.ClientHeight) then
        stepy:=-stepy;
    end;
    NON! mauvaise méthode et Shay à raison, le else est en trop.

    pourquoi :

    ne pas modifier SpeedX/Y au rebond fait que la balle à une trajectoire toujours identique (45° en N ou Z) et donc moche (symptome du screen saver Windows XP).
    il faut inverser Speed de façon explicite, car une inversion par :
    S := -S
    ou
    S := -1 * S
    peut ne pas fonctionner correctement (et pour l'avoir fait plusieurs fois je sais de quoi je parle).
    il faut donc faire l'inversion selon la collision (comme j'ai mis dans mon precedent message).

    eviter de travailler avec ClientWidth et ClientHeight et valeur 0,
    cela rend la Ball dépendante de la fiche, hors, on devrait travailler avec le Canvas d'un composant graphique qu'il soit TForm, TPanel, TPaintBox, TBitmap, TImage, bref tout ce qui est TWinControl et TGraphicControl.

    Canvas possède une propriété ClipRect, qui definit ces dimensions Min/Max.
    c'est avec elle qu'il faut travailler via ClipRect.Left/Top/Right/Bottom.

    il ne faut pas definir la balle par quatre valeur X,Y (coins LT et RB) mais comme je l'ai expliqué dans mon precedent message :
    par une coordonné au centre (X,Y) et Size (qui peut etre aussi SizeX et SizeY).
    le jours ou on voudra remplacer la balle, par un objet non rectangulable (qui peut etre definit dans un rectangle) on ne pourra tout simplement pas.
    de plus cela evite de s'emeler dans le test de collision coin LT avec Left/Top et coin RB avec Right/Bottom d'un ClipRect.

    d'ailleur si un jours on veux modifier le déplacement (déplacement par sin/cos, ou algorithme CatchPos etc) on ne pourra pas reprendre simplement la source de TBall mais il faudra tout modifier.
    il sera egalement plus simple de partir de X,Y et Size pour calculer des collisions circulaire, hexagonale etc.
    ce qui est plus pratique quand on introduit d'autre collisioneurs autre que les bord de la zone de déplacement (obstacles) ou que l'on veux calculer les approches inter-objets (calculs des distances par hypoténuse).
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  14. #14
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Tout le monde s'est déjà essayé à ce genre de truc...
    J'avais fait ça il y a plusieurs années pour mon gamin pour m'amuser...
    pas terminé...
    Si ça peut aider...

    je n'ai pas regardé le code...je le ferais sans doute autrement maintenant lol.

    a+
    Fichiers attachés Fichiers attachés

  15. #15
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963

  16. #16
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Ce qui serait intéressant, Dr Who, c'est que les boules rebondissent à chaque contact avec les autres pour un nombre de boules très grand et modifiable à souhait.
    J'avais fait la même chose que toi mais pour illustrer le mouvement brownien, il me fallait ce fameux rebond avec de multiples boules... J'avais abandonné faute d'inspiration... Sur peu de boules, c'est facile... en revanche, gérer ça quelque soit e nombre, ça devient l'usine à gaz.

    Si vous avez des idées lol, je suis preneur...

    a+

  17. #17
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 694
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Travailler avec des régions .

    Les boules sont créées par CreateEllipticRgn et déplacées par OffsetRgn. Le remplissage par FillRgn.
    Créer aussi une région pour la zone cliente de la fiche: CreateRectRgn.

    Ensuite, détecter les collisions par CombineRgn (RGN_AND):

    Détection des bords de la fiche par la combinaison de la boule et de la zone cliente: si la région résultante est égale (EqualRgn) à celle de la boule, elle ne sort pas de l'écran !
    Détection du contact entre boules: si CombineRgn des deux boules renvoi NULLREGION, elle ne se touche pas !

    Plus besoin de tester des coordonnées ou de calculer des points de contact et la possibilité d'utiliser des formes complexes .

  18. #18
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Merci Andnotor, c'est vrai que l'utilisation des régions est la voie à prendre pour ce genre de chose...
    C'est plus puissant que de tester les coordonnées ou faire des IntersectRect...

    Je vais regarder ça....

    merci encore à toi

Discussions similaires

  1. [2.x] Retrouver l'objet User dans un form de FosUserBundle
    Par DanaKil dans le forum Symfony
    Réponses: 0
    Dernier message: 18/05/2015, 13h30
  2. [Débutant] un objet bouge dans une forme avec c++builder 6
    Par Imene MI dans le forum C++Builder
    Réponses: 7
    Dernier message: 14/05/2015, 17h02
  3. Intégrer un objet select dans une form
    Par jpwitz dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 06/02/2013, 10h07
  4. Pb pour changer la taille d'un Objet TImage dans une Form
    Par Gouyon dans le forum C++Builder
    Réponses: 10
    Dernier message: 06/06/2006, 18h01
  5. Comment faire pour faire glisser un objet dans une form ?
    Par Olun dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 05/09/2005, 17h49

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