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

C++Builder Discussion :

Aligner des objet sur une grille à la fin d'un clicker glisser


Sujet :

C++Builder

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut Aligner des objet sur une grille à la fin d'un clicker glisser
    Bonjour,

    je suis en train de concevoir le jeu de bille "le solitaire" en C++ avec Borland 2006. Mon problème est que lorsque je déplace les billes je voudrais qu'elle s'aligne automatiquement. Je pense qu'il faudrait faire une sorte de grille mais je vois vraiment pas comment... ce n'est pas clair pr moi.

    J'ajoute que si je déplace une bille il faudrait qu'elle s'alligne sur la zone la plus proche, exactement comme les icones du bureau lorsqu'on active l'option "aligner sur la grille".

    Merci pour vos réponses

  2. #2
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Ça n'a pas l'air très difficile mais il faudrait préciser ce que sont ces billes. Sont-ce des objets ou des dessins sur un Canvas quelconque ? Aligner consiste simplement à avoir des coordonnées identiques en x ou en y. Donnez quelques précisions supplémentaires et éventuellement un bout de code pour qu'on voit un peu votre environnement de travail.

    À bientôt
    Gilles

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    L'idée est de passer par le modulo pour calculer si on est dans une case ou la suivante (en restant sur le plateau du jeu bien évidemment).
    Il me semble que l'on peut faire comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int Ajuster(int Valeur, int Pas)
    {
    int h = Pas / 2; // axe d'une case (vertical comme horizontal)
    int v = Valeur - h; //le référentiel est celui de l'axe d'une case
    int i = ( (v % Pas) >= h); // donne 1 si vrai
    int c = (v / Pas) + i; // en terme de case (colonne ou ligne)
    //Pour rester sur le plateau du jeu
    if(c < 0) c = 0;
    if(c > max) c = max; //max est à définir ici
    return( (c * Pas) + h ); //en terme de pixel
    }
    Donc ajuster la position de l'objet en X et en Y.
    Sa position finale sera sans doute à calculer en fonction du plateau de jeu lui-même...

    A plus !

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut
    merci de vos réponses rapides

    les billes sont des images simple.

    J'ai trouvé une solution (qui n'est pas forcément très propre je l'avoue) qui fonctionne. La voilà :

    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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
     
    // c'est la fonction qui gère la fin de déplacement des billes.
    // une autre fonction récupère les valeurs des positions en X et Y de départ avant le déplacement
    void __fastcall TfmGame::billeAllEndDock(TObject *Sender, TObject *Target, int X, int Y)
    {
    	TImage *Bille = dynamic_cast<TImage *>(Sender);
     
    	Pos_end_X = Bille->Left;  //variable de position X après le déplacement
    	Pos_end_Y = Bille->Top; //variable de position Y après le déplacement
     
     
    	NbCoups++;
    	fmGame->LaCoups->Caption=NbCoups;
    	ufmMain->lb_nbcoups->Caption=NbCoups;
     
    	La_Pos_end_X->Caption = Pos_end_X;
    	La_Pos_end_Y->Caption = Pos_end_Y;   //jusqu'ici rien d'important
     
    	Pos_dif_X = Pos_end_X - Pos_start_X; 
    	Pos_dif_Y = Pos_end_Y - Pos_start_Y; //ici je calcule la diférence des 2 positions pour savoir plus tard si il faut que je déplace la bille en X ou en Y
     
     
    	if(Pos_dif_X < 0)
    	{
    		Pos_dif_X_d = Pos_dif_X * (-1);
    	}
    	if(Pos_dif_Y < 0)
    	{
    		Pos_dif_Y_d = Pos_dif_Y * (-1);
    	}
     
    	if(Pos_dif_X_d > Pos_dif_Y_d)  //si la différence en X > que Y alors je prépare à déplacer en X
    	{
    		dir=false; //dir = direction => false = X et true = Y
     
    		La_dir->Caption="X";
     
    		if(Pos_dif_X > 0) //là je calcul le sens du déplacement gauche (-) / droite (+)
    		{
    			sens=true;
    			La_sens->Caption="+"; 
    		}
    		else
    		{
    			sens=false;
    			La_sens->Caption="-";
    		}
    	}
    	else //sinon le déplacement est vertical
    	{
    		dir=true;
     
    		La_dir->Caption="Y";
     
    		if(Pos_dif_Y > 0) // gauche /droite
    		{
    			sens=true;
    			La_sens->Caption="+";
    		}
    		else
    		{
    			sens=false;
    			La_sens->Caption="-";
    		}
    	}
     
    	if((dir==false)&&(sens==false)) //si direction = X et sens = - => je v à gauche et je déplace pile du nombre de pixel qu'il faut pour aller 2 cases plus loin
    	{
    		Bille->Left=Pos_start_X - 82;
    		Bille->Top=Pos_start_Y;
    	}
    	if((dir==true)&&(sens==false)) // là je monte
    	{
    		Bille->Top=Pos_start_Y - 74;
    		Bille->Left=Pos_start_X;
    	}
    	if((dir==false)&&(sens==true)) // je v à droite
    	{
    		Bille->Left=Pos_start_X + 82;
    		Bille->Top=Pos_start_Y;
    	}
    	if((dir==true)&&(sens==true)) // en bas
    	{
    		Bille->Top=Pos_start_Y + 74;
    		Bille->Left=Pos_start_X;
    	}
    	if((Pos_dif_X_d < 41) && (Pos_dif_Y_d < 37)) // si le déplacement est inférieure à "une case" je remet sur la case originale
    	{
    		Bille->Top=Pos_start_Y;
    		Bille->Left=Pos_start_X;
    	}
     
     
     
    }
    cette méthode fonctionne donc je pense que je vais garder ca surtout que comme je l'ai codée moi meme je la comprend mdr

    maintenant je risque d'avoir des problèmes pour savoir si la place est libre de cases plus loin.. mais je v réfléchir on verra bien je vous redirai merci ++

  5. #5
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Vous ne devriez pas écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(Pos_dif_X < 0)
    {
    Pos_dif_X_d = Pos_dif_X * (-1);
    }
    On préfère aller droit au but :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pos_dif_X=abs(Pos_dif_X) ;
    On n’écrit pas if(dir==false) mais if(!dir), de même if(dir==true) s’écrit simplement if(dir).

    Un petit shampoing s'impose.

    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
    void __fastcall TForm1::Image1EndDock(TObject *Sender, TObject *Target, int X, int Y)
    {
    TImage *Bille = dynamic_cast<TImage *>(Sender);
     
    Pos_end_X = Bille->Left;  //variable de position X après le déplacement
    Pos_end_Y = Bille->Top; //variable de position Y après le déplacement
    NbCoups++;
    fmGame->LaCoups->Caption=NbCoups;
    ufmMain->lb_nbcoups->Caption=NbCoups;
    La_Pos_end_X->Caption = Pos_end_X;
    La_Pos_end_Y->Caption = Pos_end_Y;   //jusqu'ici rien d'important
    Pos_dif_X = Pos_end_X - Pos_start_X;
    Pos_dif_Y = Pos_end_Y - Pos_start_Y; //ici je calcule la diférence des 2 positions pour savoir plus tard si il faut que je déplace la bille en X ou en Y
    Pos_dif_X=abs(Pos_dif_X) ;
    Pos_dif_Y=abs(Pos_dif_Y) ;
    if(Pos_dif_X_d > Pos_dif_Y_d)  //si la différence en X > que Y alors je prépare à déplacer en X
    	{
       dir=false; //dir = direction => false = X et true = Y
       La_dir->Caption="X";
       if(Pos_dif_X > 0) //là je calcul le sens du déplacement gauche (-) / droite (+)
    		{
          sens=true;
          La_sens->Caption="+";
    		}
       else
    		{
          sens=false;
          La_sens->Caption="-";
    		}
    	}
    else //sinon le déplacement est vertical
    	{
       dir=true;
       La_dir->Caption="Y";
       if(Pos_dif_Y > 0) // gauche /droite
    		{
          sens=true;
          La_sens->Caption="+";
    		}
       else
    		{
          sens=false;
          La_sens->Caption="-";
    		}
    	}
    if(!dir && !sens) //si direction = X et sens = - => je v à gauche et je déplace pile du nombre de pixel qu'il faut pour aller 2 cases plus loin
    	{
       Bille->Left=Pos_start_X - 82;
       Bille->Top=Pos_start_Y;
    	}
    if(dir && !sens) // là je monte
    	{
       Bille->Top=Pos_start_Y - 74;
       Bille->Left=Pos_start_X;
    	}
    if(!dir && sens) // je v à droite
    	{
       Bille->Left=Pos_start_X + 82;
       Bille->Top=Pos_start_Y;
    	}
    if(dir && sens) // en bas
    	{
       Bille->Top=Pos_start_Y + 74;
       Bille->Left=Pos_start_X;
    	}
    if((Pos_dif_X_d < 41) && (Pos_dif_Y_d < 37)) // si le déplacement est inférieure à "une case" je remet sur la case originale
    	{
       Bille->Top=Pos_start_Y;
       Bille->Left=Pos_start_X;
    	}
    }
    À bientôt
    Gilles

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut
    a ouai merci je n'ai pas appris comme ca et donc c pas toujours super cler pour moi loool mais merci xD

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Il serait plus simple de travailler avec des objets fixes servant à la fois à représenter un trou ou une bille.
    C'est ce que j'ai fait avec des TShape, donc 33 en tout prêts pour le jeu (mais ça reste vrai pour avec des TImage) !
    Dans ce cas, le drag utilise un objet supplémentaire mais qui ne sert que pour le drag & drop (donc mis en oeuvre avec les événementielles de la souris).
    Le tag de chaque objet est initialisé pour indiquer sa position dans le jeu, en terme de Lignes/Colonnes.

    J'ai fait comme ceci :

    Tag = (ligne << 8) + colonne

    A partir de là, on sait calculer la différence en termes de lignes et de colonnes.
    Si le déplacement des objets commence à Dep pour arriver à Arr :

    dep_lig = Dep->Tag >> 8
    dep_col = Dep->Tag & 0xFF
    arr_lig = Arr->Tag >> 8
    arr_col = arr->Tag & 0xFF

    Les offsets du déplacement :

    off_lig = dep_lig - arr_lig
    off_col = dep_col - arr_col

    Le test de validité du saut, de case en case, peut utiliser les valeurs absolues :

    r = abs(dif_lig)
    c = abs(dif_col)
    ((r == 0) && (c == 2)) || ((r == 2) && (c==0))

    La position du mouton est alors :

    Row = arr_lig + (off_lig / 2)
    Col = arr_col + (off_col / 2)

    On n'a donc pas besoin d'analyser le sens de déplacement.

    Si on met en liste ces 33 objets on peut alors développer une méthode pour rechercher le mouton...

    A plus !

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut
    Merci henderson mais je ne comprend pas tout ( je suis pas super doué )

    par exemple que signifie les " << " et " >> " par exemple :

    Citation Envoyé par henderson Voir le message

    Tag = (ligne << 8) + colonne
    dep_lig = Dep->Tag >> 8
    Ceci n'en plus je ne comprend pas :

    Citation Envoyé par henderson Voir le message

    arr_col = arr->Tag & 0xFF
    Ensuite pour le reste, je comprend plus ou moins cmt tu fais mais c quand meme flou... c comme si je connaissais les mots d'une phrase sans comprendre la phrase lol

    mais merci qm pour ta réponse !

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut
    je voudrais aussi savoir comment je pourrais récupéré le nom d'une des billes en fonction de sa position en pixel

    par exemple :

    je déplace la bille de 2 cases à gauche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if((dir==false)&&(sens==false)) //si direction = X et sens = - => je v à gauche et je déplace pile du nombre de pixel qu'il faut pour aller 2 cases plus loin
    	{
    		Bille->Left=Pos_start_X - 82;
    		Bille->Top=Pos_start_Y;
    	}
    donc -82 pixel horizontalement ce qui fait que la bille qui se trouve 41 pixel à gauche de la position de départ de la 1ere bille doit se rendre invisible

    le problème est donc qu'il faut que je sache le nom de la bille en fonction de sa position en pixel et la position de départ de la bille sauteuse...


    je ne vois pas vraiment comment faire...

    merci de vos réponses

  10. #10
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Vous devriez écrire if(dir) ou if(!dir) comme je vous l'ai dit et ne pas utiliser de valeur en dur dans le code, on utilise des constantes. Ainsi, si vous voulez modifier ces constantes, ça marchera de la même façon juste après une autre compilation, sinon vous êtes condamné à rechercher toutes les valeurs dans le code, ça ne se fait pas.

    Sinon, je ne sais pas comment vos billes fonctionnent mais rien ne vous empêche de créer un tableau dans lequel seraient stockées les coordonnées et noms de vos billes. Si toutefois vous cliquez ces billes (car je ne comprends pas votre problème), le Sender vous donnera son adresse, à partir de laquelle vous pourrez accéder à ses propriétés, notamment son Tag qui peut la représenter de façon unique.

    À bientôt
    Gilles

  11. #11
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Je pense comme Gilles Louïse !
    Il faudrait, je pense, réfléchir d'avantage sur la façon de procéder !
    Eventuellement, si on souhaite repartir sur de nouvelles bases je peux proposer mes sources !

    A plus !

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut
    ok

    c clair que je ne comprend pas comment procéder....

    sinon si je n'ai pas été clair, mon problème maintenant est que lorsque je veux sauter par dessus une bille, celle-ci doit devenir non visible
    pour cela je dois savoir quelle bille a été sautée
    il faut donc que je sache son nom
    le problème, c'est que les billes ne sont pas toujours à la meme position et je ne peut pas me référer à un tableaux fixe

    mais en écrivant je commence à comprendre ce que vous me proposer xD

    alors en fait je fais un tablau de variable contenant la position de chaque bille en temps réel
    et lorsque je déplace une bille je repère les 4 billes autour qui seraient succeptible d'être sautée
    et lorsque le déplacement est fini je rend invisible la bille concernée en fonction de la direction et du sens
    .........
    mouai
    je vais voir si j'arrive merci !

  13. #13
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Est-ce que tu utilses un tableau pour permettre à ton programme d'avoir une vision du jeu ?
    Dans ce cas... la solution est dans le tableau.

    Si ce n'est pas la cas, il y a la possibiité d'analyser les objets dont la Form est le parent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    TImage *Image;
    for(int j = 0; j < ControlCount; j++)
        {
        if(Controls[j]->ClassNameIs("TImage"))
            {
            Image = (TImage*)Controls[j];
            if(Image->Visible)
                {
                //REM : Image->BoundsRect
                // si c'est le mouton alors...
                } 
            }
        }
    Ca peut quand même présenter des inconvénients... et ça dépend de la manière dont tu programme ton jeu !

    Si tu as dès le départ un raisonnement en termes de lignes et de colonnes, le traitement est simplifié surtout avec le tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TImage *Tableau[7][7];
    A plus !

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    Points : 9
    Points
    9
    Par défaut
    merci mais je suis confu je n'arrive moi meme pas a me représenter comment faire..

    je vais réfléchir merci pour ta réponse

Discussions similaires

  1. [GridBagLayout] Placer des composants sur une grille virtuelle
    Par dev197 dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 13/08/2009, 14h21
  2. Aligner des images sur une même ligne
    Par cdevl32 dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 08/10/2007, 03h13
  3. Dock des objets sur une fenêtre
    Par digital prophecy dans le forum Powerbuilder
    Réponses: 2
    Dernier message: 10/08/2006, 17h14
  4. Réponses: 13
    Dernier message: 09/05/2006, 16h30
  5. Afficher des images sur une grille
    Par Coussati dans le forum Composants VCL
    Réponses: 3
    Dernier message: 27/10/2005, 09h27

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