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.

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