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

Lazarus Pascal Discussion :

Faire glisser une pièce sur un échiquier en l'attrapant


Sujet :

Lazarus Pascal

  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut Faire glisser une pièce sur un échiquier en l'attrapant
    Bonjour !

    Dans la version actuelle de mon jeu d'échecs, il faut cliquer sur la case de départ puis sur la case d'arrivée d'une pièce pour la déplacer. C'est le programme qui fait ensuite glisser l'image.

    J'ai commencé à étudier la possibilité d'un autre mode de déplacement, où l'utilisateur attraperait la pièce et la relâcherait à l'endroit souhaité. Je voudrais vous présenter ce que j'ai réussi à faire, pour savoir si je suis sur la bonne voie. Pour obtenir cet effet, j'ai repris une partie du code du Petit puzzle de ThWilliam. Le résultat est plutôt encourageant mais j'avoue que je ne sais pas trop comment ça fonctionne.

    J'ai aussi fait une petite démo séparée (à partir de cet exemple) utilisant les curseurs grab.cur et grabbing.cur (que j'ai chipés dans les sources de Firefox). Je n'ai pas encore essayé d'utiliser ces curseurs avec le programme précédent.

    Les deux programmes ont été compilés avec Lazarus 1.6 sous Windows 10.

    Que pensez-vous de ce premier essai ? Auriez-vous des suggestions ?
    Fichiers attachés Fichiers attachés

  2. #2
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour Roland,

    Pour la représentation des pièces, quelques suggestions :
    1) Utiliser des images png au lieu de bmp : cela te laisse plus de liberté dans le dessin (possibilité d'avoir des zones plus ou moins transparentes, ce qui donne de l'anti-aliasing). Plus besoin du remplacement de la couleur de transparence dans le code.
    2) pas besoin de la variable "dame" : inutile de charger un bitmap dans "dame" pour ensuite en faire une copie dans la variable de type TPiece. Celle-ci peut avoir directement comme paramètre de création le nom du fichier. Tu vas me dire que les bitmaps ne font que 5 ko et donc no memory problem.
    3) Comment vas-tu stocker tes images ? En fichiers dans un sous-dossier du programme ? Dans un fichier ressources ? Dans un TImageList ? Dans ce dernier cas, il suffit de donner à TPiece l'index de l'image.
    4) La bibliothèque bgrabitmap ne me parait pas indispensable dans ton cas. La variable FBitmap d'un TPiece peut être de type TPicture qui gère aussi bien la transparence d'un png.

    Cordialement
    Thierry

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Merci Thierry pour ces remarques, dont j'ai pris bonne note et auxquelles je vais penser.

    Effectivement dans le code que j'ai posté la nécessité d'utiliser BGRABitmap n'apparaît pas, mais j'en ai besoin par ailleurs (ne serait-ce que pour pouvoir continuer d'utiliser un échiquier en marbre qui est généré à l'exécution).

    L'une des questions que je me pose au sujet de la méthode utilisée ci-dessus, c'est de savoir comment je pourrai gérer un jeu de pièces complet. Pour le moment, l'échiquier se redessine comme par magie lorsque je déplace la pièce, mais qu'en sera-t-il des autres pièces lorsqu'elles seront survolées ?

    Il n'y a rien d'urgent. C'est juste un problème que je voudrais commencer à étudier, en vue d'une future réécriture de mon programme (qui utilise d'ailleurs fpGUI et non pas la LCL).

  4. #4
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour Roland.

    qu'en sera-t-il des autres pièces lorsqu'elles seront survolées ?
    Pas de problèmes.
    Dans le code de l'événement OnMouseDown de TPiece, tu as la ligne "BringToFront" qui ramène la pièce jouée au premier plan (sinon, elle pourrait se glisser en dessous d'une autre selon l'ordre de création).
    Pour le redessin de tout, aucun tracas : les différents événements OnPaint (damier, pièces) vont au besoin être appelés par l'OS. Rien à gérer.

    Cordialement
    Thierry

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Merci Thierry pour ta réponse. Je n'ai pas eu beaucoup de temps pour travailler ces derniers jours.

    Suivant ta suggestion, j'ai converti mes images au format PNG. Par contre, je n'ai pas vu comment passer directement le nom du fichier au constructeur de l'objet TPiece. Peut-être as-tu amélioré entre temps ton unité upieces ?
    Fichiers attachés Fichiers attachés

  6. #6
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour Roland.

    je n'ai pas vu comment passer directement le nom du fichier au constructeur de l'objet TPiece
    Il faut modifier les paramètres du constructeur : constructor Create(AOwner: TComponent; AFileName: string); reintroduce;

    Mais est-ce la bonne solution ?

    Je vois que tu préfères charger tes images à partir de fichiers (au lieu de les compiler dans un fichier ressources).
    Avantage : possibilité de modifier les dessins sans devoir recompiler le programme. Donc un utilisateur peut très bien modifier lui-même sans problème.
    Inconvénient (?) : obligation de fournir les fichiers png. Ce n'en est pas un, beaucoup de programmes ne se contentent plus d'un seul fichier (l'exécutable).

    Lorsque j'ai une série d'images à mettre en mémoire, perso, j'utilise une liste, en l'occurence un TObjectList, dans laquelle chaque objet contient un bitmap.
    Un composant (une pièce dans ton cas) n'a donc plus besoin d'avoir son propre bitmap. Il suffit de lui renseigner la variable liste et l'index de l'image dans cette liste.
    Dans le code ci-dessous, le Roi blanc a l'index image 0, la dame l'index 1, les deux tours l'index 2... les huit pions ont l'index 5...
    En cas de promotion d'un pion en dame (p.ex), il suffit de modifier l'index de l'image dans le composant. Je parle uniquement de l'image, pcq il faut évidemment modifier le type de la pièce (mais là je ne sais pas comment tu souhaites le faire).

    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    unit Unit2;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, Controls, Graphics, Forms, contnrs, Fileutil, BGRABitmap;
     
    type
      TBGRABitmapItem = class(TObject)
       private
          FBitmap: TBGRABitmap;
       public
           constructor Create(ABitmapName: string);
           destructor Destroy; override;
           property Bitmap: TBGRABitmap read FBitmap write FBitmap;
       end;
     
      TBGRABitmapCollection = class(TObjectList)
       private
          function GetItem(Index: Integer): TBGRABitmapItem;
       public
          property Item[AIndex: integer]: TBGRABitmapItem read GetItem; default;
          function NewBGRABitmap(AFileName: string): integer;
       end;
     
      {variables globales}
      var
         BGRACollection : TBGRABitmapCollection;
     
      procedure LoadImages;
     
     
    implementation
     
     
    constructor TBGRABitmapItem.Create(ABitmapName: string);
    begin
       inherited Create;
       FBitmap:= TBGRABitmap.Create(UTF8ToSys(ABitmapName));
    end;
     
    destructor TBGRABitmapItem.Destroy;
    begin
       FreeAndNil(FBitmap);
       inherited Destroy;
    end;
     
    function TBGRABitmapCollection.GetItem(Index: Integer): TBGRABitmapItem;
    begin
       Result := TBGRABitmapItem(inherited GetItem(Index));
    end;
     
    function TBGRABitmapCollection.NewBGRABitmap(AFileName: string): integer;
    begin
       Result:= inherited Add(TBGRABitmapItem.Create(AFileName));
    end;
     
    procedure LoadImages;
    var
      Path: string;
    begin
       Path:= IncludeTrailingPathDelimiter(Application.Location + 'Images');
       BGRACollection.NewBGRABitmap(Path + 'BRoi.png');   // index = 0
       BGRACollection.NewBGRABitmap(Path + 'BDame.png');  // index = 1
       BGRACollection.NewBGRABitmap(Path + 'BTour.png');  // index = 2
       BGRACollection.NewBGRABitmap(Path + 'BFou.png');  // index = 3
       BGRACollection.NewBGRABitmap(Path + 'BCavalier.png'); // ...
       BGRACollection.NewBGRABitmap(Path + 'BPion.png');
       BGRACollection.NewBGRABitmap(Path + 'NRoi.png');
       BGRACollection.NewBGRABitmap(Path + 'NDame.png');
       BGRACollection.NewBGRABitmap(Path + 'NTour.png');
       BGRACollection.NewBGRABitmap(Path + 'NFou.png');
       BGRACollection.NewBGRABitmap(Path + 'NCavalier.png');
       BGRACollection.NewBGRABitmap(Path + 'NPion.png');
    end;
     
    initialization
      BGRACollection := TBGRABitmapCollection.Create;
      LoadImages;
     
    finalization
      BGRACollection.Free;
     
    end.
    Dans l'événement Paint du composant pièce, le code devient (FImageId = l'indice de l'image):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BGRACollection[FImageId].Bitmap.Draw(Canvas, 0, 0, false);
    Cordialement
    Thierry

  7. #7
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Merci Thierry pour ton code. Voici une mise en œuvre rapide, avec toutes les pièces empilées sur la même case. L'effet "BringToFront" fonctionne très bien.
    Fichiers attachés Fichiers attachés

  8. #8
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Une version un peu améliorée, avec les pièces rangées (par un moyen provisoire).

    J'ai commencé à réfléchir à la façon de placer le code pour la gestion des curseurs. J'ai remarqué que l'objet TPiece a une propriété Cursor : ça tombe bien. Mais le code pour le changement de curseur doit être dans l'unité principale.
    Fichiers attachés Fichiers attachés

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Voici une version avec curseurs. Bizarrement, la main ne se ferme que lorsqu'on déplace la pièce et non pas dès qu'on "l'attrape" (je veux dire dès qu'on appuie sur le bouton gauche).
    Fichiers attachés Fichiers attachés

  10. #10
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    3 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : mai 2002
    Messages : 3 382
    Points : 5 738
    Points
    5 738
    Par défaut
    salut

    peut être devrais tu modifier la position de la ligne Cursor dans ta procédure MouseDown
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  11. #11
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par anapurna Voir le message
    peut être devrais tu modifier la position de la ligne Cursor dans ta procédure MouseDown
    J'y ai déjà pensé mais non, ça ne change rien.

  12. #12
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour Roland,

    Sous Delphi7, impossible de modifier le curseur dans l'événement MouseDown.

    "The reason why this does not work is because Delphi captures the mouse when
    left-clicking before calling OnMouseDown, and Delphi refuses to change the
    mouse when it is captured.
    "


    Je pensais que cela ne faisait plus problème dans Lazarus.

    Seule solution : Screen.Cursor:= GRABBING;
    Et, dans MouseUp, réinitialiser : Screen.Cursor:= crDefault;

    Cordialement
    Thierry

    PS : Il faudrait tester le changement de curseur dans la réception du message WMLButtonDown.
    [EDIT] : Test fait, mais sans succès.

  13. #13
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    4 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 016
    Points : 15 094
    Points
    15 094
    Billets dans le blog
    8
    Par défaut
    Merci Thierry ! Ça fonctionne.

Discussions similaires

  1. Faire tourner une pièce
    Par macmonac dans le forum Flash
    Réponses: 1
    Dernier message: 21/09/2007, 11h44
  2. Réponses: 5
    Dernier message: 07/03/2007, 15h06
  3. Réponses: 4
    Dernier message: 10/11/2006, 10h55
  4. Faire glisser une image trop grande avec la souris
    Par avogadro dans le forum Général JavaScript
    Réponses: 25
    Dernier message: 28/07/2006, 16h50
  5. Faire boucler une Macro sur elle même..
    Par volganne dans le forum Access
    Réponses: 5
    Dernier message: 02/06/2006, 11h13

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