Wykrywanie kolizji prostokątów i losowość ich tworzenia w prostej grze

0

Witam
Oto mój kod:

program gra;
uses crt, graph;
var
        ster, tryb:integer;							{sterowanik i tryb graph}
        x1, x2, y1, y2 :integer;					{wspolrzedne "statku"}
        wspbomb:array [1..20, 1..4] of longint;		{tablica ze wspolrzednymi "bomb", pierwszy wymiar to liczba statków, drugi ich wspolrzedne: 1=x1, 2=x2, 3=y1, 4=y2}
        czas:longint;								{potrzebny do opoznienia ruchu bomb}
        znak:char;									{wciskany klawisz}
        ilbomb, szansa, i, tor, wynik:integer;		{ilbomb - licznik bomb dla procedur "ruchbomby" i "kolizja"; szansa - zmienna losowa, 1 = stworzenie bomby; i - licznik potrzebny w kilku miejscach}
        wynikw:string;

function CzytajZnak:char;				{funkcja czytajaca wcisniety znak}
var tmp:char;
begin
   tmp:=#0;								{domyslny znak}
   while keypressed do tmp:=readkey;	{oproznienie buforu z pamiecia ostatniego znaku}
   CzytajZnak:=tmp;						{zwrocenie znaku}
end;

procedure bomba(i:integer);			{procedura tworzaca bombe}
begin

   tor:=random(10);					{losowy tor po ktorym poruszala sie bedzie bomba}
   wspbomb[i,1]:=(((60 * tor)+2));	{wsp x1}
   wspbomb[i,2]:=-57;				{wsp y1}
   wspbomb[i,3]:=(wspbomb[i,1]+56);	{wspx2}
   wspbomb[i,4]:=-1;				{wsp y2}

end;

procedure ruchbomby;				{ruch bomby; zwiekszanie wspolrzednych y bomb}
begin
   ilbomb:=1;
   while (ilbomb <= i) and (i > 1) do
   begin
        wspbomb[ilbomb,2]:=(wspbomb[ilbomb,2]+3);
        wspbomb[ilbomb,4]:=(wspbomb[ilbomb,4]+3);
        rectangle(wspbomb[ilbomb,1], wspbomb[ilbomb,2], wspbomb[ilbomb,3], wspbomb[ilbomb,4]);	{rysowanie bomb}

        if wspbomb[ilbomb,2] > 485 then bomba(ilbomb);		{tworzenie nowej bomby w momencie opuszczenia ekranu przez poprzednia}

        inc(ilbomb);
   end;
end;


procedure brzegekranu;					{ograniczenie ruchu statku poza krawedzie ekranu}
begin
                   if x1 > 600 then
                   begin
                      x1:=2;
                      x2:=58;
                   end;

                   if x1 < 0 then
                   begin
                      x1:=542;
                      x2:=590;
                   end;

                   if y1 < 0 then
                   begin
                      y1:=10;
                      y2:=30;
                   end;

                   if y2 > 480 then
                   begin
                     y1:=460;
                     y2:=480;
                   end;
end;

procedure kolizja;					{wykrywanie kolizji statku z bomba}
	var
		ktora:integer;				{wewnetrzny licznik bomb procedury "kolizja"}
begin
        ktora:=1;
        while ktora <= ilbomb do	{sprawdzanie kolizji z kazda bomba po kolei}
        begin
           if x1 = wspbomb[ilbomb,1] then	{jesli x1 statku = x1 bomby}
             if (y1 < wspbomb[ilbomb,4]) and (y1 > wspbomb[ilbomb,2]) then	{jesli y1 statku < y2 bomby i y1 statku > y2 bomby}
             begin
             SetColor(red);
             x1:=302;			{reset statku na pozycje wyjsciowa}
             x2:=358;
             y1:=400;
             y2:=420;
             end;
             if (y2 > wspbomb[ilbomb,2]) and (y2 < wspbomb[ilbomb,4]) then	{jesli y2 statku > y1 bomby i y2 statku < y2 statku}
             begin
             SetColor(red);
			 x1:=302;			{reset statku na pozycje wyjsciowa}
             x2:=358;
             y1:=400;
             y2:=420;
             end;
             inc(ktora);

        end;

end;


begin
        ster:=VGA;
        tryb:=VGAHi;
        initgraph(ster, tryb, 'C:\FPC\2.4.4\units\i386-win32\graph');

        i:=1;			{nadanie wartosci 1 licznikowi i}
        randomize();

        x1:=302;		{polozenie statku na ekranie}
        x2:=358;
        y1:=400;
        y2:=420;

                repeat

                   begin
                   znak:=CzytajZnak;
                   OutTextXY(210, 20, znak);

                   rectangle(x1,y1,x2,y2);

                  if znak = chr(119) {w} then		{STEROWANIE STATKIEM--}
                     begin												{|}
                        y1:=(y1-30);									{|}
                        y2:=(y2-30);									{|}
                        ClearDevice;									{|}
                        rectangle(x1,y1,x2,y2);							{|}
                     end;												{|}
																		{|}
                   if znak = char(115) {s} then							{|}
                   begin												{|}
                        y1:=(y1+30);									{|}
                        y2:=(y2+30);									{|}
                        ClearDevice;									{|}
                        rectangle(x1,y1,x2,y2);							{|}
                   end;													{|}
																		{|}
                   if znak = char(97) {a} then							{|}
                   begin												{|}
                        x1:=(x1-60);									{|}
                        x2:=(x2-60);									{|}
                        ClearDevice;									{|}
                        rectangle(x1,y1,x2,y2);							{|}
                   end;													{|}
																		{|}
                   if znak = char(100) {d} then							{|}
                   begin												{|}
                        x1:=(x1+60);									{|}
                        x2:=(x2+60);									{|}
                        ClearDevice;									{|}
                        rectangle(x1,y1,x2,y2);							{|}
                   end;								{--------------------|}


                   brzegekranu;			{wywolanie procedur}
                   kolizja;

                end;

                   szansa:=random(10);					{losowe tworzenie bomb} {nie dziala poprawnie}
                   if (szansa = 1) and (i < 10) then
                   begin
                     bomba(i);
                     inc(i);
                   end;


                     inc(czas);				{opoznienie ruchu bomb}
                     if czas = 100 then
                     begin
                        cleardevice;
                        ruchbomby;			{ruch bomb}
                        czas:=0;
                     end;

                    { OutTextXY(10, 470, 'Twoj wynik to: ');		{TO TEZ NIE DZIALA}
                     wynikw:=string(wynik);
                     OutTextXY(40, 470, wynikw);}



                until znak = chr(113);


        znak:=readkey;
        repeat until znak=chr(122);
end.

A to moje problemy:

  1. Nie działa wykrywanie kolizji statku z bombami. Nie mam pojęcia dlaczego, wydaje mi się że wszystko jest OK.

  2. Losowość tworzenia bomb też nawala. Pojawiają się w poziomych rzędach zamiast losowo. Wcześniej w kodzie miałem coś takiego:

if (szansa = 1) and (znak > #0) and (i < 10) then

zamiast

if (szansa = 1) and (i < 10) then

i bomby miały różne współrzędne Y, ale pojawiały się dopiero po wciśnięciu klawiszy :/

  1. Wyświetlanie wyniku. Kodu odpowiedzialnego za naliczanie punktów jeszcze nie ma, ale przy wcześniejszych próbach rzutowania integer na string miałem błędy.

Pomocy, to projekt do szkoły i już mam obniżoną ocenę o jeden stopień za przekroczenie terminu :|

0

Poprawny kod na wyświetlanie wyniku:

str(wynik, wynikw);

Procedura str konwertuje liczbę typu Integer na tekst.

Kod na sprawdzanie kolizji:

          
if x1 = wspbomb[ktora,1] then
begin
  if (y1 < wspbomb[ktora, 4]) and (y2 > wspbomb[ktora,2])  then
  begin
    outtextxy(100,100, 'Kolizja!');
  end;
end;

Aby bomby pojawiały się losowo również w pionie możesz na przykład wprowadzić zmienną torY := random(ilosc_wierszy) i uzależnić wspbomb[i,2] od tej zmiennej tak jak to zrobiłeś z wspbomb[i,1] :).

0

Dzięki wielkie :D teraz wszystko działa (ale dalej nie pojmuje dlaczego kolizje nie działały na moim kodzie). ale zastanawia mnie dlaczego muszę robić te tory dla bomb dla współrzędnych Y O_o skoro bomby tworzone są w innym czasie to czy nie powinny pojawiać się w innych miejscach?

pozdrawiam

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