Poruszanie punktem

Witam.Robię taką małą,prostą gierke.Napisałem kod,ok wszystko działa.Ale w grze chodzi o poruszanie się gwiazdką w labiryncie.Żeby dodać labirynt itd nie ma sprawy.Problem z tym żeby gwiazdka nie mogła przejść przez ścianki labiryntu.Pomóżcie!

uses Crt;

var znak:char;

    x,y : byte;

procedure a (dx, dy : integer); {procedura do poruszania gwiazką tz. gdzie możę iść a gdzie nie}

 begin

 if (x+dx>=1) and (x+dx<=80) and

    (y+dy>=1) and (y+dy<=24) then

   begin

   gotoxy(x, y); write(' ');

   x:=x+dx; y:=y+dy;

   gotoxy(x, y); textcolor(lightgreen); write('*');

   end;

   else

   begin


   end

  end;

 begin

  clrscr;

  gotoxy(1, 25);

  textcolor(yellow);

  write('Sterujesz w,s,a,d,q,e,z,c.Jeli skoäczye zabaw© nacinij p.');

  gotoxy(50, 13);

  write('|');

  x:=40; y:=12;

  a (0, 0);

  repeat

   znak:=readkey;

   case Upcase(znak) of

   'W': a (0, -1);

   'S': a (0, 1);

   'A': a (-1, 0);

   'D': a (1, 0);

   'E': a (1, -1);

   'Q': a (-1, -1);

   'Z': a (-1, 1);

   'C': a (1, 1);

   else

   begin


    end;

   end;

  until Upcase(znak)='P';

end.

Próbowałem dodać w proceurze a to:

uses Crt;

var znak:char;

    x,y : byte;

procedure a (dx, dy : integer);

 begin

 if (x+dx>=1) and (x+dx<=80) and

    (y+dy>=1) and (y+dy<=24) and

    (x+dx<>50) and (y+dy<>13) then

   begin

   gotoxy(x, y); write(' ');

   x:=x+dx; y:=y+dy;

   gotoxy(x, y); textcolor(lightgreen); write('*');

   end;

   else

   begin


   end

  end;

 begin

  clrscr;

  gotoxy(1, 25);

  textcolor(yellow);

  write('Sterujesz w,s,a,d,q,e,z,c.Jeli skoäczye zabaw© nacinij p.');

  gotoxy(50, 13);

  write('|');

  x:=40; y:=12;

  a (0, 0);

  repeat

   znak:=readkey;

   case Upcase(znak) of

   'W': a (0, -1);

   'S': a (0, 1);

   'A': a (-1, 0);

   'D': a (1, 0);

   'E': a (1, -1);

   'Q': a (-1, -1);

   'Z': a (-1, 1);

   'C': a (1, 1);

   else

   begin


    end;

   end;

  until Upcase(znak)='P';

end.

A przy okazji mam jeszcze takie pytanie.Zrobiłem tak żeby trzeba było zjadać inne gwiazdki.Spoko działa.ALE jak zrobić,że jak się zje ostatnią na ekranie to wczytuje następny lev?

Z tym zjadaniem gwiazdek to proste jest :slight_smile: Ustalasz ile gwiazdek jest na mapie, potem gdy zjadasz jakaś gwiazdkę to odejmujesz od ilości gwiazdek na mapie, jeśli liczba gwiazdek na mapie == 0, kończysz pętle programu i wczytujesz kolejny level :wink:

Wszystko super tylko,że jak mam zrobić tak,że jak zjadam gwiazdkę to odejmuje?Jak na mam tak napisany kod,że tak gdzie była gwiazdka wpisuje się spacja a w nowe pole wpisuje się nowa gwiazdka.

Ja zawsze robię tak z mapą że jest to mapa zmiennych, potem przy funkcji wyświetlającej mapę tylko to uwzględniam :wink:

Np tak :

unsigned short WyswietlMape (short Mapa [23] [40])

{

        for (unsigned short i = 0 ; i<=22 ; i++)

        {

            for (unsigned short i2 = 0 ; i2 <= 39 ; i2++)

            {

                switch (Mapa [i] [i2])

				{

				case 0: cout << " ";break;

				case -1: cout << char (219);break;

				case -2: cout << char (17);break;

				case -3: cout << char (16);break;

				case -4: cout << char (31);break;

				case -5: cout << char (30);break;

				case -6: cout << char (42);break;

				}

			}

        if (i == 22 ) 

		{

			cout << char (186);

			cout << endl;

			for (unsigned short i3 = 0 ; i3 <= 39 ; i3++) cout << char (205);

			cout << char (188);

		}

		else cout << char (186);

	    if (i != 22) cout <

		}

		return 0;

}

Fajnie tylko,że ja piszę w pascalu :stuck_out_tongue: A gwiazdki mają być rozmieszczane losowo :smiley:

Robisz sobie strukturę w której trzymasz mapę(tablica dwuwymiarowa). Ta tablica to, powiedzmy, tablica charów. Jeśli dane pole x,y == ‘*’ to znaczy, że można zjeść, jeśli ‘o’, to gracz, jeśli ’ ’ to puste pole, jeśli coś innego - przeszkoda. Poruszasz graczem po tej planszy zamieniając miejscami znak gracza ze znakiem odpowiadającym znakowi na polu na które gracz ma wejść. Jeśli to gwiazdka to zjadamy ją i odejmujemy 1 od licznika gwiazdek(żeby nie trzeba było skanować całej planszy), jeśli przeszkoda to nie ruszamy, jeśli puste pole, tylko zamieniamy. Jeśli ruszymy gracza czyścimy screen i odrysowujemy całą planszę, bądź tylko zmiany.

EDIT:

PS. To co z tego, że jest w C++? To tylko poglądowy kod, wiele rozumieć nie trzeba.

@ kalin93 : nie podawaj więcej gotowego kodu bo to nie nauczy młodego programisty nic.

@ Fiołek , widzę że opisałeś mój sposób tylko że na tablicy char :wink: Z podawaniem gotowego kodu, on i tak musiałby go sobie przepisać do Pascala wiec czegoś go tam nauczy :wink:

PS. Ja tez jestem młodym, niedoświadczonym programistą (8 miesięcy programuje)

Co do problemu zjadania gwiazdek udało mi się obmyślić własny sposób,który po wielu poprawkach już działa:)Problem tylko z tymi przeszkodami,bo z tego co napisałeś Fiołek o przeszkodzie dużo mi nie pomogło :slight_smile:

A i jeszcze żeby potem nie było-gwiazdki mają być losowo(rozwiązane) a mapa z pliku .txt.Zrobić,załadować-to proste.Ale wciąż nie wiem jak zrobić by gwiazdka nie wchodziła na ściany labiryntu.

@ kalin93 :

Na charze będzie wydajniej, do tego ty trzymasz to jako liczby nieznakowe, więc, żeby to wyświetlić potrzebny jest dodatkowy koszt, do tego zaciemnia kod.

Rozszerzając mapę o jedną kolumnę z prawej i wpisując w nią znaki nowej linii możemy za jednym razem wyświetlić całą mapę(przy użyciu funkcji systemowych) - “darmowe” podwójne buforowanie.

PS. przyznam, że nie analizowałem wcześniej Twojego kodu.

EDIT:

A co to za problem? Jeśli dany znak jest różny od * i różny od ’ ’ to jest to przeszkoda, tu nie ma wielkiej filozofii :stuck_out_tongue_winking_eye:

Wybierasz sobie dowolną pozycję na mapie i jeśli w tym punkcie jest ’ ’ to wstawiamy gwiazdkę, jeśli nie - powtarzamy od początku.

@Fiołek/b]

To oc napisłeś o przeszkodzie wciąż mi nie pomaga.Co z tego,że napiszę,że jak jest ’ ’ to jest przeszkoda.Mi chodzi o to jak napisąć by gwiazdka nie mogła tam wejść.A co do mejego sposobu coś się skiepściło i przestało działać.

uses Crt;

var q:integer;

    znak:char;

    x,y : byte;

    i,p : byte;

    zostalo:integer;

procedure a (dx, dy : integer);

 begin

 if (x+dx>=1) and (x+dx<=80) and

    (y+dy>=1) and (y+dy<=24) then


   begin

   gotoxy(x, y); write(' ');

   x:=x+dx; y:=y+dy;

   gotoxy(x, y); textcolor(lightgreen); write('*');

   end

   else

   begin


   end

 end;


 begin

  zostalo:=0;

  clrscr;

  textcolor(yellow);

  randomize;

  for q:=5 downto 1 do

  begin

  i:=random(80)+1;

  p:=random(24)+1;

  gotoxy(i, p);

  write('*');

  end;

  textcolor(yellow);

  gotoxy(1,25);

  write('Sterujesz w,s,a,d,q,e,z,c.Jeli skoäczye zabaw© nacinij p.');

  x:=40; y:=12;

  a (0, 0);

  repeat

   znak:=readkey;

   case Upcase(znak) of

   'W': a (0, -1);

   'S': a (0, 1);

   'A': a (-1, 0);

   'D': a (1, 0);

   'E': a (1, -1);

   'Q': a (-1, -1);

   'Z': a (-1, 1);

   'C': a (1, 1);

   else

   begin


    end;

   end;

  if (x and y) = (i and p) then

  inc(zostalo);

  if zostalo=5 then

  begin

  gotoxy(30,5);

  write('Brawo');

  end;

  until Upcase(znak)='P';

end.

Nie zebrałem wszystkich gwiazdek a nagle wyskakuje ‘brawo’.Co popsułem?Próbowałem zmienić ten kod ale za każdym razem tak jest.Jak zrobiłem np. zamiast ‘inc(zostalo);’ ‘dec(zostalo);’ i tam wyżej zmieniłem,że zostalo :=5 po to by odejmowało też nie działa. :frowning:

Szkoda, że nie ma emotki ilustrującej łapanie się za głowę. :stuck_out_tongue:

Po pierwsze zastanów się nad robieniem jakichś porządnych wcięć… ten kod jest nieczytelny. Może nauka Pythona pomoże? :twisted:

Po drugie:

Brakuje średnika po ostatnim end , a w ogóle to to całe else jest niepotrzebne, bo przecież nic nie wykonuje. Powinno więc się zakończyć średnikiem po tym end przed else , czyli bez else begin end. Po trzecie:

Tu dokładnie ta sama sytuacja. else begin end; nic nie robi, niepotrzebne i do wywalenia… I po czwarte i chyba o to Ci przede wszystkim chodzi:

Zauważ, że wcale nie zapamiętujesz zmiennych i i p , tylko je cały czas nadpisujesz, a jednak:

Zakładasz, że i i p są zapamiętane w jakiś magiczny sposób. Jeśli chcesz koniecznie tym sposobem, to zrób na to tablice, a najlepiej jedną tablicę dwuwymiarową. A i tak najlepszy sposób podał Fiołek , więc radziłbym się nad nim zastanowić, tylko to będzie wymagało przepisania prawie całego kodu. Zwróć jeszcze uwagę na warunek, jaki postawiłeś w powyższym ifie: (x and y) = (i and p) - to oznacza: Jeśli suma logiczna wartości zmiennych x i y jest równa sumie logicznej wartości zmiennych i i p , to. Oczywiście w Twoim kodzie to jest bezużyteczne. Powinno być: Jeśli wartość zmiennej x jest równa wartości zmiennej i oraz wartość zmiennej y jest równa wartości zmiennej p , to.

Aha i jeszcze powinieneś przerwać wykonywanie pętli po napisaniu Brawo. Służy do tego break;. Zapoznaj się też z continue;.

Co do wcięć-racja troche niczytelnie.Jeśli chodzi o else to tam jeszcze nic nie wstawiłem-zostawiłem to na koniec.A co do

if (x and y) = (i and p) then

  inc(zostalo);

Zauważyłem tylko w tym sprawa,że nei wiem jak to zrobić inaczej.

A próbowałeś coś takiego:

IF (x = i) AND (y = p) THEN

Oczywiście to też nie zadziała tak jak trzeba, bo i i p trzeba wsadzić do tablicy, żeby zapamiętać współrzędne wszystkich gwiazdek. W tym sprawdzaniu więc zastosowałbyś pętlę FOR. Nadal proponuję przepisać program, według sposobu Fiołka.