Witam.
Potrzebuję zrobić grę w Lazarusie - statki. Szukam komponentu który odzwierciedliłby mi pole gracza i pole komputera.
Myślałem wstawić...200 TShapeów obok siebie ale to byłoby beznadziejne.
- Rejestracja:prawie 12 lat
- Ostatnio:prawie 2 lata
- Lokalizacja:Bielsko-Biała
- Postów:11
Wystarczy TPanel
oraz jakiś silnik obsługujący OpenGL*; jako handle
do silnika podajesz handle kontrolki i voilà.
*
nie jestem pewien, czy DirectX również na takie rzeczy pozwala.
- Rejestracja:ponad 22 lata
- Ostatnio:34 minuty
pobierz pakiet BGRAControls, jest tam komponent (wraz z przykładem) BCGameGrid: http://wiki.freepascal.org/BGRAControls#BCGameGrid
- Rejestracja:prawie 12 lat
- Ostatnio:prawie 2 lata
- Lokalizacja:Bielsko-Biała
- Postów:11
Próbowałem z tym TPaintBox i jakoś mi nie chce działać. Mam taką procedurę:
procedure Draw;
begin
Form1.PaintBox1.Canvas.Pen.Color:=clRed;
Form1.PaintBox1.Canvas.MoveTo(200, 200);
Form1.PaintBox1.Canvas.LineTo(100, 100);
Form1.PaintBox1.Update;
end;
i w momencie wywołania jej na TPaintBox'ie widzę na 0,1 sekundy czerwoną linię. Tak to TPaintBox jest pusty. w OpenGL'u ciężko będzie to zrobić. Dlatego najpierw skorzystam z najprostszych rozwiązań (pobawię się trochę TStringGrid'em)
- Rejestracja:prawie 12 lat
- Ostatnio:prawie 2 lata
- Lokalizacja:Bielsko-Biała
- Postów:11
@_13th_Dragon, dzięki za kod.
Bawiłem się TStringGridem i powiem, że w ogóle nie nadaje się do tego.
Został TPaintBox, nigdy w tym nie rysowałem więc, napisałem to tak:
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
Draw;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
iType := 0;
PaintBox1.Invalidate;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
iType := 1;
PaintBox1.Invalidate;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
iType := 2;
PaintBox1.Invalidate;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
iType := 3;
PaintBox1.Invalidate;
end;
procedure Draw;
begin
if iType = 1 then
begin
Form1.PaintBox1.Canvas.Pen.Color := clRed;
Form1.PaintBox1.Canvas.LineTo (20, 30);
end else if iType = 2 then
begin
Form1.PaintBox1.Canvas.Pen.Color := clGreen;
Form1.PaintBox1.Canvas.LineTo (40, 50);
end else if iType = 3 then
begin
Form1.PaintBox1.Canvas.Pen.Color := clBlack;
Form1.PaintBox1.Canvas.LineTo (50, 60);
end else
begin
Form1.PaintBox1.Canvas.Pen.Color := clBlue;
Form1.PaintBox1.Canvas.LineTo (70, 80);
end;
end;
Kod mniej więcej "działa". Pytanie da się jakoś to uprościć? Czy to jest dobrze napisane?
Czego potrzebuję:
Program musi narysować plansze: statków gracza i trafień.
Mogę "jakoś" użyć zdarzenia OnClick na PaintBox'ie i odczytywać współrzędne kursora zdarzeniem onMouseMove co pozwoliłoby mi na interakcję - głupie rozwiązanie i trudne ale da się napisać.
Muszę planszę zmieniać, czyli rysować prawie to samo, ale np. za drugim razem z wypełnionym na niebiesko jednym polem w planszy.

case .. of
i tablice, a skrócisz rysowanie do dwóch instrukcji; Możesz też przyciskom nadać Tag
równy iType
i przypisać im wspólne zdarzenie OnClick
;

- Rejestracja:prawie 17 lat
- Ostatnio:około 3 lata
- Lokalizacja:Szczecin
- Postów:4191
Zrobisz jak będziesz uważał. Ale jeżeli nie chcesz używać silników, co polecił Tobie @Patryk27, a robić to pod czystym Delphi. To oczywiscie można się męczyć PaintBoxem, ale nie wiem dlaczego przy braku wiedzy, upierasz się na niego, zamiast na zasugerowany wcześniej również TStringGrid
. Jakie są jego plusy? Otóż że poza tym, iż łatwo sobie rysujesz "wodę", statek trafiony albo chybiony strzał, chocby: http://stackoverflow.com/questions/9924259/inserting-image-in-stringgrid-cell - gdzie wiadomo zamiast grafiki z TImage
podstawiamy jakąś z zasobów. A poza swobodnym niemal rysowaniem komórek StringGrida posiada on jeszcze własności Objects
. To daje Tobie możliwosć utworzenia jakiejś klasy bazowej na przykład TGameField
, która obsłuży w przyszłosci wyswietlanie grafiki trafien i innej, odtwarzanie dźwięków (ja bym takie coś przewidział, co komu dzisiaj z niemej gry, a tak pakujemy sobie bass.dll do zasobów, używamy dllloader.pas
, o ktorym niedawno pisałem tutaj przy okazji wątku o dołączeniu i korzystaniu z dllki do zosobów exeka i jazda) i reakcje gry na to czy już zatopiono nasze lub przeciwnika statki. I tak dalej. Tak bym kombinował. A i widze, że to chyba po raz kolejny odświeżenie tematu pisania gry "Statki" w Delphi. I tak się zastanawiam czy to na prawdę aż tak trudne zadanie. Wydaje mi się, że po przemyśleniu tematu jest to do ogarnięcia, a schody mogą się zacząć dopiero przy eleganckim obsłużeniu gry sieciowej czy implementacji sztucznej inteligencji CPU, o ile taką planujesz. A tak do testów na szybko z losowym celowaniem komputera to po prostu usiąść, pomyśleć i to napisać, nie mnożąć sobie zbędnie problemów na zaś :)

- Rejestracja:ponad 19 lat
- Ostatnio:2 miesiące
olesio napisał(a):
To oczywiscie można się męczyć PaintBoxem, ale nie wiem dlaczego przy braku wiedzy, upierasz się na niego, zamiast na zasugerowany wcześniej również
TStringGrid
.
@olesio, bardzo przepraszam ale chrzani waść. Co może być prostsze od PaintBox'a?
Ot całe rysowanie:
procedure TForm1.PaintBoxPaint(Sender: TObject);
var y,x:Integer;
begin
for y:=0 to 9 do for x:=0 to 9 do ImageList.Draw(PaintBox.Canvas,x*32,y*32,Tb[y,x]);
end;
StringGrid nawet się nie umywa.

- Rejestracja:prawie 17 lat
- Ostatnio:około 3 lata
- Lokalizacja:Szczecin
- Postów:4191
No można i tak. Teraz doczytałem, że to Lazarus, więc odpadają moje porady o takim użyciu bass.dll z zasobów, bo za pewne się okaże, że tam ten moduł jak to Lazarus ma w zwyczaju nie być kompatybilnym wstecz, nie zadziała. Ale nie sprawdzałem, więc i mozę się da jak nie tym, to innym. W sumie można mieć też i dwie tablice 10x10 na trzymanie obiektów do obsługi pola gry. Po prostu mi się wydawało, że pod TStringGrid
to zrobić łatwiej. Tylko pytający nie zrobił chyba jeszcze nic i kombinuje z tą grą jak nie wiem z czym, zamiast przysiąść i zaprogramować to. A ja, że śmiałem polecić TStringGrid, to zaraz "chrzanie". Tylko już nieraz było tak, że ktoś na forum o coś spyta z tematyki Lazarus / Pascal / Delphi, to mimo iż mija kilkadziesiąt minut, a nie jest ani późno w nocy, ani wcześnie nad ranem, a i ja nie mam codziennie wolnego, to jakoś mogę odpisać. Najlepiej jest zwkleać z odpowiedzią, a innym zarzucać chrzanienie. Teraz to nie będe pisał nic, wątki będą bez odpowiedzi, a każdy kto podważy opinie Dragona będzie chrzanił. Niezłych czasów doczekaliśmy.




- Rejestracja:ponad 20 lat
- Ostatnio:4 miesiące
To może i ja coś od siebie dorzucę :P
W załączniku jest edytor poziomów do ramake'a gry Tower of The Sorcerer dla canvas HTML5.
Edytor był pisany w Delphi 5 na szybko do własnego użytku (w grze jest tylko 50 poziomów), ale możesz sobie zobaczyć jak łatwo jest zrobić rysowanie planszy i wyliczać współrzędne.
link do skompilowanego exe - nie wiem czy w lazarusie są wszystkie użyte komponenty
http://speedy.sh/KMynW/Project1.exe
- Project1.zip (196 KB) - ściągnięć: 92


- Rejestracja:prawie 17 lat
- Ostatnio:około 3 lata
- Lokalizacja:Szczecin
- Postów:4191
Faktycznie, proste acz geniealne. Może i chrzaniłem, ale wydawało się mi, że przy użyciu TStringGrid będzie prościej. A Twój projekt @szopenfx przyda się w przyszłości. Dodalem go sobie po drobnych poprawkach do moich projektów z prefiksem NOT_MINE
. Zbieram tak niektóre źródła tutaj, które mnie zaciekawią. A nie jest tego wiele, bo jak pewnie kojarzycie tylko ja miałem głównie wcześniej zwyczaj zapodawania na forum gotowców.
Tylko zastanawiam się czy mozolnie wczytałeś bitmapy do ImageList czy podzieliło je i tak ładnie dopasowało, bo u mnie po wczytaniu bitmapki robią się tak małe jak dla celów obrazków w TListView, a nie tak jak to u Ciebie samo [?] Delphi zrobiło?



- Rejestracja:prawie 12 lat
- Ostatnio:prawie 2 lata
- Lokalizacja:Bielsko-Biała
- Postów:11
@szopenfx, dzięki, twoim sposobem jest najprościej.
To tak, tworzę komponent TImage jemu w canvas moge wstawić obrazek TBitmap w pozycji x,y. (metoda draw).
Nie pozostaje mi nic innego jak stworzyć obrazek planszy i obrazki pól planszy. Takie pytanie, czy da się cofnąć metodę draw? W Canvas nie ma metody Undo ;)

Undo
, więc nie zrobisz tego tak łatwo;

- Rejestracja:prawie 17 lat
- Ostatnio:około 3 lata
- Lokalizacja:Szczecin
- Postów:4191
Znowu sobie mnożysz problemy gdzie ich nie ma @shJeff. Nie wiem w czym problem żeby stworzyć tablicę ze zmiennymi klasy, o której wspominałem. Można w niej zdefiniowac zmienne jak Indeks obrazka po jego ustawieniu i po kliknięciu na undo. Tak ja bym kombinował. Zresztą układanie statków na planszy to jedyny według mnie etap gdzie można pozwolić na Undo, w przypadku właściwej gry to też można założyć. Ale wtedy się gracz może na swóje ostateczne strzały decydować w nieskończoność i je cofać. A i @furious programming zauażył błąd w kodzie @szopenfx'a. Oczywisćie nie problem to naprawić ustawiając SelectedIndex
na taki sam, jak zwykły.
Bo tak to jest, jak się chce odizolować broń Boże od nauki czegokolwiek nowego...
Stwórz sobie PaintBox
, zadeklaruj tablicę 10x10
(albo dwie - jeszcze z polem przeciwnika) o dowolnym wygodnym typie i na jej (ich) podstawie rysuj odpowiednie pola w komponencie; Gdzieś trzymaj informacje o ostatnim ruchu i jeśli gracz cofnie ruch to nie nie kombinuj z implementacją metody Undo
w klasie kanwy, tylko przemaluj jeden kwadracik o współrzędnych z ostatniego ruchu (trzeymałbyś je w ww. zmiennej); Stwórz sobie też tablicę z grafikami dla odpowiednich stanów jedego kwadracika;
Możesz nawet szarpnąć się na klasę do obsługi pól gry i w niej przechowywać wszelkie informacje na temat położenia statków, ilości oddanych strzałów, ilości zniszczonych statków itd.; Uprościłoby to wiele problemów;
Poza tym proponowałbym przestać pytać - usiądź i zastanów się najpierw jak to ma działać.
olesio napisał(a)
A i @Furious Programming zauażył błąd w kodzie @szopenfx'a. Oczywisćie nie problem to naprawić ustawiając SelectedIndex na taki sam, jak zwykły.
Dodatkowo domalowałbym jakąś ramkę na grafice, żeby się wyróżniała :]

2 * 10 * 10 = 200
;)