"Latający" po ekranie przycisk.

0

Witam :)

Piszę sobie program, który ma służyć jako prosta gra. Jednym z jego elementów jest ruchomy przycisk, który lata po planszy przyjmując pewne luźne reguły. Oto moja procedura dla jego ruchu:

procedure wrog;
begin
 randomize;
  k:=k+1;
   if k=4 then k:=0;
    if k=0 then i:=random(5);
     case i of
      1:form1.wrog.Top:=form1.wrog.Top+4;
      2:form1.wrog.Top:=form1.wrog.Top-4;
      3:form1.wrog.left:=form1.wrog.left+4;
      4:form1.wrog.left:=form1.wrog.left-4;
     end;
    if form1.wrog.left>600 or if form1.wrog.left<10 or if form1.wrog.top<10 or if form1.wrog.top>500 then

    begin
     form1.wrog.Top:=random(150)+200;
     form1.wrog.Left:=random(200)+200;
    end;

Ta procedura będzie podpięta do timera. Niestety, przy próbie kompilacji wywala mi błąd - na ostatnim endzie procedury: "Operator not applicable to this operand type", a że w programowaniu jestem świeży jak szczaw, nie mogę znaleźć istoty problemu. Bardzo prosze o podpowiedź :)

I przy okazji bardzo chętnie zadam drugie pytanie: Wczoraj napisałem kalkulator. Starałem się jakoś sensownie zabronić wstawiania drugiego przecinka w okienku wyniku. Zrobiłem to tak, że można wpisać tylko jeden przecinek, tzn. można wpisać 19,1, ale 19,2,1 już nie - niestety nie sprawdza się to, jeśli w oknie wynikowym jeden przecinek już jest - wtedy można dopisać drugi. Brakuje mi "zdania" sprawdzającego, czy w oknie na którymkolwiek miejscu pojawił się już przecinek - jak to zrobić?

Pozdrawiam!

0

Bo masz za dużo wrog'ów, kontrolka, procedura i kto wie co jeszcze.

0

@_13th_Dragon: akurat tutaj nie jest to problemem, o ile wrog nie jest metodą klasy (a jak wynika z tego kodu - nią nie jest).

Problem jest tutaj:

 if form1.wrog.left>600 or if form1.wrog.left<10 or if form1.wrog.top<10 or if form1.wrog.top>500 then

To kompletnie nie ma sensu.

Brakuje mi "zdania" sprawdzającego, czy w oknie na którymkolwiek miejscu pojawił się już przecinek - jak to zrobić?

Pos
0

Zarówno procedurze, jak przyciskowi nadałem identyczną nazwę "wrog", już to zmieniłem :) Dziękuję za odpowiedzi! Patryk27, i dziękuję za podpowiedź :) W tej chwili już przycisk działa mi jak należy, a kod zmieniłem na następujący:

procedure wrogpierwszy;
var a:byte;

begin
 randomize;
  k:=k+1;
   if k=4 then k:=0;
    if k=0 then i:=random(5);
     case i of
      1:form1.wrog.Top:=form1.wrog.Top+4;
      2:form1.wrog.Top:=form1.wrog.Top-4;
      3:form1.wrog.left:=form1.wrog.left+4;
      4:form1.wrog.left:=form1.wrog.left-4;
     end;
    if form1.wrog.left>600 then a:=1;
    if form1.wrog.left<10 then a:=1;
    if form1.wrog.top<10 then a:=1;
    if form1.wrog.top>500 then a:=1;

   if a=1 then
    begin
     form1.wrog.Top:=random(150)+200;
     form1.wrog.Left:=random(200)+200;
     a:=0;
    end;

Ale mam wrażenie, że jednak or byłby w stanie uprościć sytuację, tylko ja nie potrafię się z nim dogadać - mam rację? :)
Czy w tej chwili procedura jest zbudowana "sensownie" czy gdzieś coś powinienem poprawić?

1

Ale mam wrażenie, że jednak or byłby w stanie uprościć sytuację, tylko ja nie potrafię się z nim dogadać - mam rację?

Yup:

if (form1.wrog.left>600) or (form1.wrog.left<10) or (form1.wrog.top<10) or (form1.wrog.top>500) then
 a:=1;

można by jeszcze pokombinować ze zbiorami, ale nie chce mi się nad tym teraz myśleć

Czy w tej chwili procedura jest zbudowana "sensownie" czy gdzieś coś powinienem poprawić?

Po pierwsze: zmienna a powinna być typu boolean, a najlepiej, jakby jej w ogóle nie było:

if (form1.wrog.left>600) or (form1.wrog.left<10) or (form1.wrog.top<10) or (form1.wrog.top>500) then
begin
 form1.wrog.Top:=random(150)+200;
 form1.wrog.Left:=random(200)+200;
end;

Po drugie: Twój kod jest poprawny pod względem składni, lecz mimo wszystko sugerowałbym zmianę identyfikatorów na angielskie oraz inną nazwę tej funkcji.

0

Jeżeli uważasz, że powinieneś użyć inaczej or to go użyj. Instrukcje warunkowe masz opisane na: Instrukcje warunkowe - niestety nie formatujesz kodu po ludzku i nie wstawiasz go we właściwe znaczniki. Dlatego za pewne nie tylko ja, ale wielu tutaj nawet na to nie spojrzy. Bo wybacz, nie szanujesz czasu "czytaczy", to i nie wszyscy z nich mają ochotę zagłębiąć się w kod, który podałeś i marnować na to czas.

0

olesio, Jeśli nie formatuję kodu poprawnie i nie używam właściwych znaczników, to, daję słowo, nie przez niedbałość, brak szacunku, nienawiść do oczu czytających czy złośliwość :) Nie ma w tym ani grama złej woli, tylko czysta niewiedza :D Może nawet pamiętasz ten czas, kiedy patrzyłeś na swój własny kod świadomy, ile jeszcze wiedzy masz do zdobycia, i nie byleś pewien, czy wszystko ma właściwy kształt czy jest totalnie pokrzywione? ;) Bardzo chętnie nauczę się działać poprawnie i przejrzyście, a do tego potrzebuję takich właśnie wskazówek - porada kogoś bardziej doświadczonego ładnie wskazuje konkretne błędy, przez czytanie poradników nie wszystko wchodzi do głowy idealnie poprawnie ;] Nie przez przypadek założyłem ten temat w Newbie (jakby był dział Total Newbie to na pewno bym poszedł prosto tam) i pytam, czy kod ma sensowny kształt (mi się wydawało, że jest względnie czytelny) - ja tego po prostu jeszcze nie potrafię ocenić, bo może o czymś elementarnym nie wiem :D

Podsumowując: jeśli wam, czytający, nie będzie się chciało czytać kodu i rozważać jego problemu, bo będzie mało czytelny - rzućcie proste "Popraw to i to, bo razi w oczy, to i to jest ok", żebym wiedział, czego się douczyć ;)

Przejrzałem pomoc dotyczącą "or", ale jakoś mojej uwadze umknęła waga nawiasów - starałem się, ale jednak błąd, i to prosty, dziękuję za naprostowanie ;]

Patryk27, dzięki za wyrozumiałość :D Zmieniłem już nazwę procedury, a zrodziło mi się pytanie (znowu pewnie oczywiste), czy dobrze mówi mi intuicja i wiedza, że zmienna k powinna być lokalna zamiast globalnej?

Kolejna kwestia: chciałbym, żeby podobna procedura dotyczyła jeszcze paru przycisków ("wrogów"). Z tym, że na innych zmiennych zamiast "k" oraz "i", to znaczy, żeby przyciski zmieniały kierunek ruchu całkiem niezależnie od siebie (w innych momentach).

  1. Gdyby mi na tym nie zależało, dobrym pomysłem byłoby użycie zmiennych globalnych - prawda czy fałsz?
  2. Aby tego dokonać, muszę stworzyć tyle procedur, ile będzie przycisków, czy da się to jakoś skrócić?

Proszę zwrócić uwagę, że na te pytania po prostu nie da się znaleźć w sensowny sposób odpowiedzi w internecie (ewentualnie - nie mam pomysłu na sensowne zapytanie), chyba, że przypadkiem trafiłbym na podobny problem na forum ;]

0

Na wszystkie twoje pytania można znaleźć odpowiedzi w google przy użyciu TBrain. Poczytaj najpierw i zamiast pytać jak coś zrobić pytaj czy dobrze robię i pokaż kod.

1

Zmieniłem już nazwę procedury, a zrodziło mi się pytanie (znowu pewnie oczywiste), czy dobrze mówi mi intuicja i wiedza, że zmienna k powinna być lokalna zamiast globalnej?

Nie mam bladego pojęcia, bo nie wiem jak wygląda reszta kodu.
Ale z kawałka ukazanego tutaj rodzi się właśnie taka konkluzja.
tl;dr - tak.

Aby tego dokonać, muszę stworzyć tyle procedur, ile będzie przycisków, czy da się to jakoś skrócić?

Najlepiej chyba byłoby stworzyć własny przycisk dziedziczący po TButton (bądź czym tam to Twoje form1.wrog jest), który by to implementował.
Wtedy byś wywoływał coś w rodzaju:
Form1.Enemy1.Move();, a najlepiej: Enemy[1].Move(), gdzie Enemy to globalna tablica elementów typu TTwojButtonDziedziczacyPoTButton tworzonych dynamicznie, wtedy ta aktualna procedura wrog byłaby właśnie metodą Move. Lub w każdym razie ja bym tak najprawdopodobniej zrobił ;)

1

@Cyrd: spoko, do lepszego wyświetlania kodu wystarczy wstaiwać go w znaczniki code, ale z określeniem języka. Albo w przypadku Delphi/Pascala/Lazarusa najszybciej można po prostu użyć znaczników delphi. I tak, faktycznie moich początków z programowaniem w Delphi można się wstydzić. Brak elementarnej wiedzy o dllkach, używanie ukrytych TListBox do przechowywania listy linijek tekstu, zamiast chocby oczyistego TStringList. Niewiedza, że funkcje odczytujące czy zapisujące bufor z/do pliku zapiszą/odczytają tekst do zmiennej typu string kiedy użyjemy zapisu Cosik[1]. Formatowanie kodu to w moim wykonaniu też było nieporozumienie. Miałem taki idiotyczny nawyk i uparcie mimo wskazówek nawet prowadzącego zajęcia z programowania obiektowego na studium policelanym, po prostu usuwałem z uporem maniaka wszystkie wcięcią, bo uważałem stosowanie wcięć za głupotę :) Do tego kompletnia nieznajomośc tematyki pisania pod WinAPI. Ale z czasem, między innymi pomagając często w wielu banalnych problemach na tym forum zdobułem w moim odczuciu wiele doświadczenia i wiedzy.

Natomiast co do formatowania. Najprostsze są według mnie te trzy poniższe rozwiązania.

  1. Używać Lazarusa jako IDE i korzystać z wbudowanego w te środowisko formattera (domyślnie pod skrótem Ctrl+D).
  2. Zainstalować darmowy dodatek GExperts. Następnie wygooglować jego alternatywną wersję, która zawiera formatter kodu i podmienić stosowną dllkę w zależności od posiadanej wersji środowiska Delphi. Może nie wspierać najnowszych wersji tego IDE.

Powyższe rozwiązanie są wprawdzie wygodne, bo działają pod IDE. Jednak o ile się orientuje formatują tylko kod w oknie aktywnego edytora kodu. Jeżeli jednak chcemy masowo i szybko sformatować kod w wielu plikach kodów źródlowych w Delphi/Pascalu. I mamy je do tego w kilku podkatalogach to warto skorzystać z roziązania trzeciego.

  1. Jedi Code Formatter. To osobny program. Pozwoliłem go sobie umieścić pod adresem: http://olesio.eu/jcf - wystarczy pobrać i rozpakować archiwum do katalogu PROGRAM FILES. Następnie dwuklikiem importować do rejestru te dwa pliki jcf_loader_exe.reg i jcf_settings.reg. Dzięki temu program zostanie ustawiony tak, że na przykład z pod Total Commandera wywołamy go poleceniem, w szybki sposób pisząć jcf. Wywoływany jcf_loader.exe to mój mały twór, który uruchamia właściwy program, a wcześniej dopisuje do rejestru aktualną ściezkę z której został wywołany. Dodatkowo importowane ustawienia powodują, że obsługiwany jest dołączony plik z ustawieniami (jcfsettings.cfg). Ustawienia te wzięte zostały z pliku gdzieś wygooglowanego i delikatnie przeze mnie poprawione. Takze formatowanie odbywa się prawidłowo na 2 spacjowe wcięcia, słowa kluczowe są z małych liter, spacja występuje zarówno przed dwukropkiem jak i za nim, a także pomiędzy innymi operatorami. Oraz inne standardowe rzeczy. Czyli kod źródlowy jest na pewno o wiele bardziej czytelniejszy. Dodatkowo kod programu głownego został spatchowany zgodnie z moim opisem w tym wpisie na moim Blogu: http://blog.olesio.eu/uzycie-idr-do-szybkiego-przeanalizowania-aplikacji-napisanej-w-delphi - dzięki czemu nie wyświetla się dodatkowy, zbędny według mnie nag.

No coż, rozpisałem się jak to ja ;P Ale chyba trzeba będzie napisać krótki artykuł o tym jak można formatować kod Delphi. Bo wiele osób tego nie stosuje, bo albo nie wie albo niestety częśćiej ma tę tematykę po prostu "gdzieś" :/ A tak to będzie do czego odsyłać.

0

Byłem odcięty od świata zewnętrznego przez tydzień. Dziękuję wszystkim za odpowiedzi! szopenfx, bardzo fajny artykuł! olesio nie testowałem wprawdzie jeszcze Twojej propozycji programu, ale brzmi to świetnie :) I tego typu artykuły są całkiem przydatny, z kilkoma przykładami, dobrze jest wziąć sobie takie reguły do serca na samym początku zabawy z programowaniem.

Mogę się pochwalić, że mój program działa - "postacie" się kręcą, jeden strażnik obchodzi punkt docelowy, a kod jest wybitnie nieposkładany i nawet ja jestem w stanie określić, że Everestu w dziedzinie programowania nie stanowi ;)

Pozdrawiam!

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