Ahoj, hraju si v pascalu s grafikou a potřebuju poradit s detekcí kolize. Zatím mají všechny objekty, i ty kruhové, pro detekce kolize model obdélníka, a občas to ne úplně lícuje. Tak se chci zeptat, jestli se dá nějak zjišťovat kolize s kruhem?
Fórum › Pascal
Detekce kolize
To Tomass: Jo, Pythagorova věta a poloměry... vidíš, to mě ani nenapadlo... díky moc. Zmíním tě v Credits :)
A jak by to vypadalo pro kolizi kruhu a obdélníka? (sorry, jsem dneska nějakej natvrdlej...)
//nebo obecně kruhu a bodu?
///už jsem na to asi přišel... prostě jako že poloměr 0 :D
Tak jsem zkusil kolizi dvou kruhů (taky se mi hodí) jak jsi napsal, ale hází mi to Arithmetic overflow... co je špatně?
repeat
{saucer}
if sqrt(sqr(h-mx[z])+sqr(v-my[z]))<(size+25) then sracka:=true;
inc(z);
until sracka or (z>cycles);
h a v jsou souřadnice středu 'létajícího talíře', do kterého nesmí nic narazit, mx[*] a my[*] jsou souř. středů kruhů, u kterých se zjišťuje jestli do něj narazily... ty jsou všechny stejné a jejich poloměr je size. 25 je poloměr 'létajícího talíře'.
To Laaca: Asi vím, kam tím míříš a napadlo mě to taky... všichni zúčastnění jsou integer, jenom z a size jsou byte a sracka je samozřejmě boolean.
Ten Tomassův postup jsem zkoušel v samostatném programu a očividně funguje tak jak má, ale jakmile to zabuduju kamkoliv do svého programu, vyhodí to ten overflow... nevím, co tomu může vadit...
Tak nakonec pomohlo vyměnit integer u mx a my za longint nebo word... ale to mi teda někdo vysvětlete, proč...
No já jsem nepočítal s tím že on ty výpočty bude dělat v těch proměnných...
Když se počítá hodnota nějakého výrazu, uloží se do dočasné proměnné, která je toho "největšího" typu ze všech proměnných a konstant použitých ve výrazu. Když mám třeba sqr((i*l) div b), kde i je integer, l longint a b byte, tak výsledná hodnota, která se předá jako parametr sqr, bude longint. Kdybych tam měl místo longintu integer, byl by výsledek taky integer.
Btw., přeteklý integer = záporné číslo. Potom pozor na odmocniny.
Moje stránka.
Nevíte někdo, jak udělat kolizi obdélníka a kruhu?
To už je trošku složitější, budeš muset řešit několik případů.
Předpokládám, že máš kruh o středu kx,ky a poloměru r a obdélník s levým horním rohem lhx,lhy a pravým dolním pdx,pdy.
1) (kx>=lhx)and(kx<=pdx): pak je kruh buď nad obdélníkem nebo pod ním a nebo aspoň částečně v něm. If (ky+r>=lhy)or(ky-r<=pdy) then kolize ano.
2) (ky>=lhy)and(ky<=pdy): je buď vlevo nebo vpravo nebo v něm - to samé pro vodorovný směr: If (kx+r>=lhx)or(kx-r<=pdx) then kolize ano.
3) ostatní případy, tj. střed kruhu je někde šikmo, ale není ani nad, ani pod, ani vodorovně stranou od obdélníka. Potom: if (vzdalenost(kx,ky,lhx,lhy)<=r)or(vzdalenost(kx,ky,lhx,pdy)<=r)or(vzdalenost(kx,ky,pdx,lhy)<=r)or(vzdalenost(kx,ky,pdx,pdy)<=r) then kolize ano (prostě testuju, jestli kružnice přesahuje nějaký roh). Funkce Vzdalenost(a,b,c,d) počítá vzdálenost bodu a,b od c,d, to už určitě zvládneš.
Moje stránka.
Dík, nemusels to psát takhle do detailů. Stačilo říct, že přímo to nejde, ale musí se přes body. Ale v normální analytický geometrii tohle jde docela jednoduše: když mám rovnici kružnice a parametrické rovnice úsečky, řeší se to jako soustava dvou rovnic nebo v tomhle případě by to šlo i snad sloučit do jedný rovnice... zamyslel bych se nad tím, ale momentálně mě trápí úplně jiný problém, a pokud ho nevyřeším, tak je mi detekce kolize k ničemu... snad nebude vadit když se zeptám tady.
for b:=0 to e do begin
if (mx+25>h) and (mx-25<h) then begin {disruptors}
dx:=mx;
dy:=my;
disruptor:=true;
end;
(...)
for c:=0 to e do if disruptor[c] then begin {disruptory - grafika}
setcolor(0);
line(dx[c],dy[c],dx[c],dy[c]-5);
line(dx[c]-1,dy[c]-1,dx[c]+1,dy[c]-1);
line(dx[c]-1,dy[c]-3,dx[c]+1,dy[c]-3);
dy[c]:=dy[c]+2;
setcolor(10);
line(dx[c],dy[c],dx[c],dy[c]-5);
line(dx[c]-1,dy[c]-1,dx[c]+1,dy[c]-1);
line(dx[c]-1,dy[c]-3,dx[c]+1,dy[c]-3);
end;
mx[*],my[*]: tentokrát souřadnice nepřátelských lodí
h,v: souřadnice lodi hráče (Enterprise)
dx[*],dy[*]: souřadnice projektilu z disruptoru
disruptor[*]: boolean array, určuje, jestli ta či ona loď už vystřelila nebo ne
Co to má dělat:
Podmínkou pro vystřelení je, aby se loď nacházela v takovém rozsahu x souřadnic, aby trefila Enterprise, tedy h plus mínus 25. Pokud je podmínka splněna, do disruptor se uloží true a za souřadnice projektilu se zkopírují souřadnice lodi (jak jinak). Dále program zjišťuje v cyklu, střely od jakých lodí na obrazovce jsou a od jakých ne, a podle toho je vykresluje - smaže, pak posune (projektil je 2x rychlejší než loď) a zase nakreslí.
Co to dělá:
Když je splněna původní podmínka, před nepřátelskou lodí se nakreslí projektil, ale zůstane tam přilepený a začne se pohybovat tak jak má až za několik sekund. Nechápu proč. Taky se ty projektily během letu občas zaseknou a už se nesmažou... prostě je to nějaký divný.
Vidíte v tom kódu někde chybu nebo je tohle prostě nad možnosti BGI?
Začátek:
if (mx+25>h) and (mx-25<h) then...
bych přepsal na:
if (abs(mx-h)<25) and not disruptors then...
První část je jen zjednodušená podmínka "když xová vzdálenost je menší než 25", druhá testuje, jestli už náhodou příslušný klingon nevystřelil. Tady asi byla ta chyba, protože když to neotestuješ, tak se bude tatáž střela vytvářet v každém cyklu znova a tak dlouho, dokud s Enterprise neodletíš mimo ten rádius 25 pixelů.
(Edit: teď koukám, že ta původní podmínka byla navíc špatně. Měla by být if (mx+25<h) and (mx-25>h) then...)
Zbytek je asi OK. Jenom bych ještě doporučil vyřešit kreslení střel procedurou, kterou předáš jako parametry souřadnice a barvu. Mazání pak vyřešíš voláním KresliDisruptor(x,y,0) a kreslení KresliDisruptor(x,y,10) - bude to pohodlnější.
Moje stránka.
>Mircosoft: Máš pravdu, s absolutní hodnotou je to lepší. Jo, testovat tu podmínku, to je proč to nefunguje... díky moc - jsem prostě potřeboval aby se na to podíval někdo jinej, protože já v tom vlastní chyby nevidím.
Kreslení disruptoru bych procedurou nedělal, jsou to tři řádky kódu, takže to bordel nedělá.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Detekce ovládání myši skrz aplikaci v c#, detekce bota v c# — založil ejtix
Kolize — založil Dusan
Kolize kodovani — založil tribalcz
Moderátoři diskuze