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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    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 Expert
    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
    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 Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    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
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    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 Expert
    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
    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
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 20
    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 Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    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 !

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