Gra typu 2048 - klawisze strzałek w funkcji KeyPress

0

Buduję grę typu 2048. Chcę oprogramować sterowanie na klawisze strzałek, jednak gdy chcę to zadeklarować w timerze to muszę użyć funkcji KeyPress i nie wiem co wrzucić w nawias, by były to strzałki. Mógłby mi ktoś powiedzieć co trzeba tam wpisać?

void __fastcall TForm1::TimerDwojekTimer(TObject *Sender)
{
        while(true)
        {
                if(KeyPress('') || KeyPress('') || KeyPress('') || KeyPress(''))
                {
                        if(Image1->Picture=="images/Pusty.bmp")
                        {
                        Image1->Picture->LoadFromFile(("images/2.jpg"));
                        }
                        else if(Image2->Picture==("images/Pusty.bmp"))
                        {
                        Image2->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image3->Picture=="images/Pusty.bmp")
                        {
                        Image3->Picture->LoadFromFile(("images/2.jpg"));
                        }
                        else if(Image4->Picture=="images/Pusty.bmp")
                        {
                        Image4->Picture->LoadFromFile(("images/2.jpg"));
                        }
                        else if(Image5->Picture=="images/Pusty.bmp")
                        {
                        Image5->Picture->LoadFromFile(("images/2.jpg"));
                        }
                        else if(Image6->Picture=="images/Pusty.bmp")
                        {
                        Image7->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image8->Picture=="images/Pusty.bmp")
                        {
                        Image8->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image19->Picture=="images/Pusty.bmp")
                        {
                        Image9->Picture->LoadFromFile("images/2.jpg");
                        }                        }
                        else if(Image10->Picture=="images/Pusty.bmp")
                        {
                        Image10->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image11->Picture=="images/Pusty.bmp")
                        {
                        Image11->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image12->Picture=="images/Pusty.bmp")
                        {
                        Image12->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image13->Picture=="images/Pusty.bmp")
                        {
                        Image13->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image14->Picture=="images/Pusty.bmp")
                        {
                        Image14->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image15->Picture=="images/Pusty.bmp")
                        {
                        Image15->Picture->LoadFromFile("images/2.jpg");
                        }
                        else if(Image16->Picture=="images/Pusty.bmp")
                        {
                        Image16->Picture->LoadFromFile("images/2.jpg");
                        }

                }
        }
}
1

Trochę (bardzo) źle masz to zrobione. Masz timer, a w nim nieskończona pętla. Ogólnie to jeśli chcesz to pisać w Builderze to nie musisz używać do tego żadnych timerów. Wystarczyło by użyć odpowiednich zdarzeń dla formatki z ustawionym parametrem KeyPreview na true. I wtedy piszemy w zdarzeniu OnKeyDown/OnKeyUp:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  if (Key == VK_LEFT)
  {
    ShowMessage("Lewa strzałka");
  }
}
//---------------------------------------------------------------------------
0

Dobra, a co byś zaproponował na losowanie położenia tych dwójek, które się pojawiają co ruch?

1

Jeśli chcesz to robić w taki sposób (każdy image odpowiada za jedno pole), to każdy image musisz mieć w jakiejś tablicy. Tak naprawdę to powinna być jakaś większa klasa, która dodatkowo Ci powie, czy pole jest puste, czy w polu jest jakaś konkretna wartość.

2

Zawartość planszy powinna być przechowywana w całości w obiekcie gry. Klasa takiego obiektu powinna zawierać wszystko co gry dotyczy - stan planszy, punktacja itd.

Jako płótno powinna być użyta wewnętrzna bitmapa, na której rysowana była by każda klatka gry (bez względu na to czy używa się animacji, czy się nie używa). Back Buffering umożliwi szybkie malowanie, dzięki czemu obraz nie powinien migać na ekranie (w trybie okienkowym bardzo łatwo o taki defekt).

Natomiast właściwym elementem wyświetlającym grę powinno być albo płótno formularza, albo komponent typu PaintBox. I nie pięćdziesiąt komponentów, a jeden. W obu przypadkach, najpierw należy wyrenderować klatkę na pomocniczej bitmapie, a następnie wywołać Invalidate (formy lub kontrolki). A w zdarzeniu OnPaint (formy lub kontrolki) tylko namalować bitmapę na właściwym płótnie.

0

Czyli sugerujecie, że powinienem zacząć od początku?

0

Dokładnie tak. Przy czym najpierw zastanów się dobrze nad tym jak ma to wyglądać, a dopiero później usiądź do pisania kodu. W przeciwnym razie znów wyjdzie spaghetti.

0

OK dzięki

Do rysowania bitmap to WinAPI tak?

0

Niekoniecznie - bez problemu możesz użyć metody Draw z klasy TCanvas. W Twoim projekcie nie będą potrzebne jakieś kosmiczne optymalizacje, więc aż tak bardzo nie musisz się przejmować wydajnością :]

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