Odwołanie się do Buttona po współrzędnych

0

Cześć.
Piszę klona gry saper ale problem dotyczy nie tylko tego.
Mam formularz na którym jest przycisk Nowa Gra. Po naciśnięciu program generuje 100 przycisków w planszy 10x10.
Po naciśnięciu przycisku wyznaczam jego pozycję na podstawie jego nazwy(dwie ostatnie znaki to np. 56 co oznacza współrzędne x=5 i y=6).
Problem w tym ,że dla każdego pola chciałbym mieć ustawione jakieś właściwości typu: czy jest bombą, ile ma bomb wokół, czy zostało już odkryte. To znaczy zadanie idealne dla klas. Tylko jak powiązać tą dany obiekt klasy z konkretnym buttonem?
Przykładowa klasa:
klasa Pole
{
int WspółrzędnaX;
int WspółrzędnaY;
bool CzyJestBombą;
int IleBombWokół;
jakieś inne dane

jakieś metody np
OdkryjSąsiedniePola
itp.
}

Czyli w przykładowej planszy miałbym 100 obiektów danej klasy tylko jak skojarzyć to, że kliknięcie danego buttona odnosi się do konkretnego obiektu?

1
  1. W klasie dodaj pole publiczne typu system.Windows.Forms.Button lub odpowiednik w używanym przez Ciebie toolkit GUI.
  2. Utwórz słownik Dictionary, gdzie kluczem będzie przycisk (obiekt system.Windows.Forms.Button), a wartością będzie obiekt klasy Pole.
  3. W procedurze zdarzenia kliknięcia przycisku dostajesz referencję do obiektu przycisku. Możesz za pomocą słownika i tej referencji zidentyfikować obiekt związany z danym przyciskiem.
  4. Inny sposób, to przeszukanie całej struktury z obiektami i ustalenie, który ma dany obiekt przycisku (referencja przekazana do procedury kliknięcia) lub który obiekt ma współrzędne odpowiadające nazwie przycisku.
0

Ok dzięki za podpowiedź. A czy kontrolka TableLayoutPanel mogłaby w jakiś sposób ułatwić w tworzeniu sapera? Bo jeśli chodzi o rozmieszczenie przycisków to radzę sobie bez niej ale pytam tak czysto teoretycznie?

1
specjal1990 napisał(a):

Ok dzięki za podpowiedź. A czy kontrolka TableLayoutPanel mogłaby w jakiś sposób ułatwić w tworzeniu sapera? Bo jeśli chodzi o rozmieszczenie przycisków to radzę sobie bez niej ale pytam tak czysto teoretycznie?

Dokładnie tak, z tym że same przyciski utwórz w tabele 2d i dodawaj dynamicznie.
Do każdego przycisku we właściwość Tag wpisz new Point(x,y) czyli jego współrzędne.
Natomiast wartości mina/pusto w innej tabeli, zawsze możesz odwołać się do tych samych współrzędnych

0
_13th_Dragon napisał(a):
specjal1990 napisał(a):

Ok dzięki za podpowiedź. A czy kontrolka TableLayoutPanel mogłaby w jakiś sposób ułatwić w tworzeniu sapera? Bo jeśli chodzi o rozmieszczenie przycisków to radzę sobie bez niej ale pytam tak czysto teoretycznie?

Dokładnie tak, z tym że same przyciski utwórz w tabele 2d i dodawaj dynamicznie.
Do każdego przycisku we właściwość Tag wpisz new Point(x,y) czyli jego współrzędne.
Natomiast wartości mina/pusto w innej tabeli, zawsze możesz odwołać się do tych samych współrzędnych

Czyli odradzasz skojarzenie buttonów z obiektem klasy poprzez Dictionary?
I nie bardzo wiem jak użyć właściwość Tag? Współrzędne to prawdziwe wartości czy takie jakby "wirtualne" indeksy?
Tzn. pierwszy przycisk ma współrzędne 0,0 drugi 0,1 a ostatni 9,9? Bo jeśli tak się tego używa byłoby bardzo pomocne.
Obecnie tak tworzę pola:

        private void CreateFields()
        {
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    Button newbutton = new Button();
                    newbutton.Location = new Point(5 + 30 * j, 40 + 30 * i);
                    newbutton.Size = new Size(33, 33);
                    newbutton.Visible = true;
                    newbutton.Text = i.ToString() + j.ToString();
                    newbutton.Tag=new Point(j, i);//co to dokładnie ma robić?
                    Controls.Add(newbutton);
                    newbutton.MouseUp += button_MouseUp;
                    fields.Add(newbutton, new Field(i, j));//dodanie przycisku do Dictionary fields i skojarzenie z klasą
                }
            }
            
        }
2
specjal1990 napisał(a):

Czyli odradzasz skojarzenie buttonów z obiektem klasy poprzez Dictionary?

Nie to żę odradzam ale Tag działa z lepszym czasiem.

specjal1990 napisał(a):

I nie bardzo wiem jak użyć właściwość Tag?

Wszystkie przyciski muszą mieć tego samego onClick, w którym

Button btn=(Button)evt.Sender;
Point p=(Point)(btn.Tag);
int x=p.x,y=p.y; //masz współrzędne
specjal1990 napisał(a):

Współrzędne to prawdziwe wartości czy takie jakby "wirtualne" indeksy?

Nie, ale zawsze jedno możesz przeliczyć na drugie.

specjal1990 napisał(a):

Tzn. pierwszy przycisk ma współrzędne 0,0 drugi 0,1 a ostatni 9,9?

Dokładnie tak.

Obecnie tak tworzę pola:

Brak podpięcia metody OnClick

0

Brak podpięcia metody OnClick
podpiąłem to pod MouseUp i myślę że działa?

0

a skoro już piszemy o kliknięciach to jak obsłużyć zdarzenie kliknięcia lewego i prawego przycisku jednocześnie jak w prawdziwym saperze? Obecnie wywyłoje zdarzenia dla środkowego przycisku ale lepiej byłoby dla lewego i prawego naraz.

0

Dla lewego i prawego faktycznie MouseUp ale wtedy wypada samemu narysować plansze nie używając przycisków,
Zaś przyciski jedynie rysujesz:

function DrawButtonFace(Canvas: TCanvas; const Client: TRect; BevelWidth: Integer; Style: TButtonStyle; IsRounded, IsDown, IsFocused: Boolean): TRect;
0

Cześć. Trochę kodu napisałem i wyszło mi coś takiego, link do GitHub: https://github.com/Mariusz199005/Saper
Jeśli komuś się chce zajrzeć to proszę o wskazówki lub słowa krytyki. Brakuje mi tylko obsługi jednoczesnego kliknięcia prawym i lewym przyciskiem myszy. Zamieniłem to na wciśnięcie kółka. Jak w ogóle obsłużyć zdarzenie kliknięcia dwoma przyciskami? Bo program i tak chyba przechwyci jeden przycisk wciśnięty parę milisekund szybciej?
Czy mógłby ktoś mnie nakierować jak zrobić to bez przycisków? Na jakiejś planszy np. tableLayoutPanel?

0

Już ci mówiłem - zwykła bitmapa i Picture Box.
Co do przycisków to MouseDown + MouseUp w MouseDown zapisujesz flagę jakie przyciski wciśnięte, zaś w mouse up je obsługujesz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1