Pascal - przerywanie pętli podczas wykonywania

0

Witam, mam pewien problem, otóż tworze ponga w pascalu, aktualnie stworzyłem kod odpowiadający za lot piłki po prostej, ale niestety nie działa tak jak należy. Problem polega w tym, że mam paletkę i jeśli już wprawię w ruch piłeczkę i wcisnę raz strzałkę w góre to paletka przesunie się w góre dopiero po zakończeniu całej pętli (aktualnie pracuje nad trybem trening, tj. odbijanie o ściane) - czyli lot do ściany, odbicie się od niej i powrót do paletki.

Jeśli natomiast wcisnę więcej razy strzałkę to moge swobodnie poruszać paletką, jednak mimo wszystko po zakończeniu jednej pełnej pętli czyli lot - ściana - powrót - paletka i tak przemieści paletkę o jedną pozycję w góre lub w dół.

Odpowiedni kod to do tego to:

     {rozpoczecie lotu pileczku z paletki po prostej}
         if pozKontrolna=0 then
     begin                                                                             
            repeat            
             Inc(pozXp);
             gotoxy(starapozXp,shootedpozYp);
             write(' ');
             gotoxy(pozXp,shootedpozYp);
             write(pilka);
             starapozXp:=pozXp;
                                           
              if keypressed then
               begin
                break;
                goto paletka;
                goto paletka2;                                   
                continue;                                                
               end;
           {predkosc poruszania sie pileczki} 
               delay(20);                         
            until pozXp=79;
         
                                 
    end; 
      {////// koniec lotu po prostej od paletki}
    
    if pozXp=79 then pozKontrolna:=1;   
    
      {odbicie sie od sciany po prostej}  
   if pozKontrolna=1 then
      begin
        repeat            
             Dec(pozXp);
             gotoxy(starapozXp,shootedpozYp);
             write(' ');
             gotoxy(pozXp,shootedpozYp);
             write(pilka);
             starapozXp:=pozXp;
              
              if keypressed then
               begin                                                                
               break;
               goto paletka;
               goto paletka2;                              
              continue;    
               end;
          {predkosc poruszania sie pileczki}       
                delay(20);                         
            until pozXp=9;
  
   if pozXp=9 then pozKontrolna:=0;

jesli chodzi o labele: paletka zmniejsza odpowiednią zmienna o 1 w gore lub w dol jesli zostala wcisnieta strzalka w gore/dol, a paletka2 zmienia pozycje pileczki na ekranie bazujac na poprzednich obliczeniach.

dodam, ze tworze bez modolu graph, czysto w konsoli.

dzięki z góry za pomoc.

1
break;
goto paletka;
goto paletka2;                              
continue; 

co Ty tu chcesz zrobic...?

0
cimak napisał(a)
break;
goto paletka;
goto paletka2;                              
continue; 

co Ty tu chcesz zrobic...?

W zamyśle: przejść do części kodu odpowiedzialnej za zmianę pozycji paletki, zmienić ją i wrócić do pętli

1

ale... break opuszcza petle. a continue przechodzi do nastepnego wywolania petli.
jestes pewien, ze to co po break costanie wywolane? a jesli jest break to po co continue..?

0
cimak napisał(a)

ale... break opuszcza petle. a continue przechodzi do nastepnego wywolania petli.
jestes pewien, ze to co po break costanie wywolane? a jesli jest break to po co continue..?

A to ciekawe, ja wyczytalem ze break przerywa petle, a continue ją kontynuuje od momentu zatrzymania... Mój błąd. Pomimo tego, i tak nie mogę uzyskać efektu, żeby po naciśnięcie raz strzałki w góre w czasie lotu piłeczki, paletka została natychmiast przesunięta do góry - a nie jak teraz po zakończeniu lotu piłeczki..

1

poza tym, masz balagan w kodzie. zrob sobie dwie procedury, typu rysujPilke(x,y) i rysujPaletke(x,y) a potem wystarczy jedna petla w ktorej:
zarowno sprawdzasz klawisze,
zmieniasz odpowiednie zmienne x/y
i jenoczesnie rysujesz co trzeba.
odradzam uzywania goto.

druga sprawa to uzycie przez Ciebie delay(). ja bym tego nie robil.

GoTo
Break
Continue

0
cimak napisał(a)

druga sprawa to uzycie przez Ciebie delay(). ja bym tego nie robil.

To jak w inny sposób mogę spowolnić zmianę pozycji piłki ?

1

wez pod uwage ze stosowanie delay(20) blokuje Ci cały program na te 20ms. jesli w tym czasie zostanie nacisniety jakis klawisz to porgram orientuje sie dopiero po tych 20ms. jesli wszystko jest w petli to w efekcie moze sie ciąć i ruch nie bedzie płynny.

mozesz dac np delay(1); a zamiast zmieniac pozycje pilki o 1 zmieniaj o np 0.05.

0
cimak napisał(a)

wez pod uwage ze stosowanie delay(20) blokuje Ci cały program na te 20ms. jesli w tym czasie zostanie nacisniety jakis klawisz to porgram orientuje sie dopiero po tych 20ms. jesli wszystko jest w petli to w efekcie moze sie ciąć i ruch nie bedzie płynny.

mozesz dac np delay(1); a zamiast zmieniac pozycje pilki o 1 zmieniaj o np 0.05.

Nie da się bez trybu graficznego zmieniać pozycję piłki o 0,05 ... także, zostaje tylko delay, chyba, że funkcja gotoxy(x,y) obsługuje części setne? ..

1
blocha napisał(a)

chyba, że funkcja gotoxy(x,y) obsługuje części setne? ..

funkcja nie.
deklarujesz sobie zmienne x/y typu real;
do niech dodajesz np 0.01;
pozniej wywolujesz gotoXY( round(x), round(y) );
round() zaokragla liczby do calkowitych.

tu masz na szybko napisane, bardzo okrojone mozliwosci chodzi o to zebys zrozumial zasade.
troche trzeba zmienic, np wylaczyc wyswietlanie mrugajacego kursora, ograniczyc ruch pilki.paletki do granic ekranu, czy zastosowac rozwiazanie inne niz clrScr zeby nie mrugalo:

program gra;
uses crt,dos;


procedure rysujPilke(x,y:Real);
begin
  gotoXY( round(x),round(y));
  write('O');
end;

procedure rysujPaletke(x,y:integer);
begin
  gotoXY(x,y);
  write('===========');
end;



var pX,pY:real; {pozycja pilki}
    palX, palY:integer;
    key:char;
BEGIN
palX:=0;
palY:=0;

pX:=20;
pY:=10;

    repeat
    if KeyPressed then
      begin
        key:=ReadKey;
        if key=#0 {niewaz niektore klawisze, takie jak "strzalki" sa poprzedzone klawiszem #0, czyli tak jakby wcisniecie dwoch klawiszy jeden po drugim}
          then key:=readKey;
        if key=#27
          then exit; {po wcisnieciu Esc wyjscie z programu. w zasadzie tez powinno byc w case of, ponizej}

        case key of
          #80: palY:=palY+1; {dol}
          #72: palY:=palY-1; {gora}
          #75: palX:=palX-1;{lewo}
          #77: palX:=palX+1;{prawo}
        end;
      end;

    pY:=pY+0.005; zmieniamy pozycje pilki
    if pY>palY //jesli pilka jest nizej niz paletka to ustawiamy ja na gorze ekranu.
      then pY:=0;
      
    clrScr;
    rysujPaletke(palX, palY);
    rysujPilke(pX, pY);
    until false;
END.
0

Ok, zrobiłem co nie co - ale mam problem.. nie wiem w jaki sposób zapętlić to wszystko, żeby piłka leciała bez wciskania jakiegokolwiek z klawiszy już po zaczęciu gry...

repeat
    if (keypressed) or (zaczeto) then
    begin 
      arrow:=M_Readkey;
      
          sprawdzPal;
          
              
        if (arrow=VK_Enter) or (zaczeto) then
          begin
            zaczeto:=true;
             if round(pilX)=9 then pozKontrolna:=1; 
          
            {Od paletki do sciany}      
                  if pozKontrolna=1 then
                       begin                                                                             
                         repeat            
                            starapozXp:=pilX; 
                            pilX:=pilX+0.1;
                            rysujPilkeprosta(pilX,pilY);
                                           
                  
                  if keypressed then
                       begin                                                                                                                                    
                          arrow:=M_Readkey;
                          sprawdzPal;
                          rysujPaletke(palX,palY);
                       end;
                                                                                               
                         until round(pilX)=79;                                         
                       end; 
    
            {Ustalanie punktu kontrolnego na scianie}
                    
                  if round(pilX)=79 then pozKontrolna:=0;
       
            {Od sciany do paletki}
                  if pozKontrolna=0 then
                        begin
                          repeat            
                              starapozXp:=pilX; 
                              pilX:=pilX-0.1;
                              rysujPilkeprosta(pilX,pilY);
                                
              
                   if keypressed then
                        begin                                                                             
                        arrow:=M_Readkey;
                        sprawdzPal;
                        rysujPaletke(palX,palY);                                                  
                        end;
             
          
                                          
                          until round(pilX)=9;
            
                 
                 {Jesli nie trafi w paletke, to przegrywasz!}
                  if (paletkaTab[pilY]=' ') and (round(pilX)=9) then
                          begin                             
                              zaczeto:=false;
                              trescOkienek('Game over ! You failed.');             
                           end;
                         
                        
                        
                        end;     
   
   
                  
             
             
          end;
  
         end;
                           
      
      rysujPaletke(palX,palY);
              
     
            
  until arrow=VK_ESC;  
 
1
blocha napisał(a)

nie wiem w jaki sposób zapętlić to wszystko, żeby piłka leciała bez wciskania jakiegokolwiek z klawiszy już po zaczęciu gry...

przeciez podalem Ci kod w ktorym takie cos ma miejsce... pomysl troche.

0
cimak napisał(a)
blocha napisał(a)

nie wiem w jaki sposób zapętlić to wszystko, żeby piłka leciała bez wciskania jakiegokolwiek z klawiszy już po zaczęciu gry...

przeciez podalem Ci kod w ktorym takie cos ma miejsce... pomysl troche.

Tyle, że zupełnie nie wiem jak to przełożyć na mój kod... nie wystarczy zrobić jakiejś zmiennej/warunku odpowiedniego? Próbowałem już kilka pomysłów i żaden nie działał poprawnie...

@Edit
nvm... już ogarnąłem i działa : ) w razie jakichkolwiek pytań napiszę tutaj, a tymczasem wielkie dzięki, idę pisać kod na odbijanie się po skosie ;)

0

odczytywanie klawiszy, przemieszczanie i rysowanie (w tej kolejnosci) robisz w jednej i tej samej, głownej petli programu, co w tym trudnego?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.