Diskuze: Výpočet kolizí
Člen
Zobrazeno 13 zpráv z 13.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |
Podle typu hry a situace - pokud je to třeba pacman, tak zjistíš, kdo s kým kolidoval - pokud strašidlo se strašidlem, tak nic neřešíš, pokud pacman s puntíkem, nastavíš mu stav, že může žrát strašidla, pokud strašidlo s pacmanem, tak podle toho, v jakém je pacman stavu - buďto zavoláš konec hry (prohrál) a nebo zavoláš akci, kdy pacman sežral strašidlo...
To mě napadlo jako první, ale potom bych musel ve složitějších hrách, kde je objektů (druhů koliz) více, dělat každou kolizi zvlášť pro každý objekt. Takže jestliže by hra měl 10 objektů, tam se každý objekt může setkat s tím druhým, takže implementovat 100 kolizí se mě nezdá jako 2x vhodný způsob.
Jinak to bohužel nejde.
Nemusíš samozřejmě řešit 100x100 typů kolizí, pokud opravdu nemají všechny objekty se k sobě chovat různě, ale můžeš si objekty rozlišit do skupin, takže to pak zredukuješ na pár skupin - třeba hráč a nepřítel, hráč a tečka, hráč a bonusový objekt apod.
Zkus si objekty roztřídit do Tagů. V případě kolize kontroluješ jen s jakou skupinou Tagu objekt kolidoval. To ti kód především zpřehlední.
A jak se to řeší v kódu? Všechny objekty, které se můžou podílet na kolizi budou mít nějakou přetíženou funkci, kde budou postupně všechny jiné objekty?
class pacman {
void kolize(duch x);
void kolize(puntik x);
void kolize(stena x);}
Nebo se to řeší nějakým jiným způsobem?
Ale z toho stále vyplývá že budu mít ve třídě jednu metodu několikrát přetíženou pro každý druh kolize. Nebo se to řeší nějak jinak mimo tyto objekty? Neříkám že by to takhle nešlo, ale rád bych věděl jak se to řeší prakticky u velkých projektů.
Proč? Jako parametr bude objekt, který impletuje interface .
Interface IColision
{
void kolize(IColision druhyObjekt);
public string typObjektu;
}
class nejakyObjekt : IColision
{
//nejakyMetody
public string typObjektu="hrac";
void kolize(IColision druhyObjekt)
{
//zde se musim stejne rozhodnout na jakou akci budu reagovat
if(druhyObjekt.typKolize=="stena")
this.vratitSeZpet();
else if (druhyObjekt.typKolize=="duch")
this.zemrit();
//atd
}
}
//zbytek kodu programu
//propocitani kolizi
kolizniPole [] pole=new kolizniPole[pocetPoli];
foreach(jednoPolicko policko in pole)
{
if(policko.jsouPritomnyDvaObjekty())
{
IColision prvniObjekt=policko.getPrvni();
IColision druhyObjekt=policko.getDruhy();
prvniObjekt.kolize(druhyObjekt);
druhyObjekt.kolize(prvniObjekt);
}
}
Takto nějak bych to řešil právě teď, je to správně?
Řeší se to různě a záleží na tom, u kolika objektů se kolize
detekuje. Tyto algoritmy jsou hlavní částí herních enginů a jejich
rychlost bývá klíčová.
Jakkoliv hezký je design virtuální metody pro detekci, kterou si každý
objekt implementuje sám, můžeš to udělat pro řádově jednotky až
desítky objektů. Pokud jich je více, není to dobrý způsob, protože je to
velice pomalé.
Jeden způsob, jak implementovat velice rychlou metodu detekce kolizí, která bude fungovat i pro tisíce objektů (ve 2D):
funkce I) předběžná detekce kolize
funkce II) úplná detekce kolize
for (int i = 0; i < objectArray.length; i++)
{
for (int j = i + 1; j < objectArray.length; j++)
{
if (!prematureDetection(objectArray[i], objectArray[j]))
break;
if (!fullDetection(objectArray[i], objectArray[j]))
break;
// KOLIZE mezi objectArray[i], objectArray[j]
}
}
Tenhle postup má několik výhod:
Děkuji, to je velmi dobrá odpověď.
Nicméně tu zůstává otevřená otázka, co dělat po zjištějí kolize?
Výše jsem napsal jednu možnost, ale zdá se mi těžkopádné se rozhodovat
podle typu kolize (zvláště když třeba bude 100 druhů kolizí). Navíc,
kdybych přidal novou kolizi, musel bych všechny objekty znovu projet a
připsat ji tam.
Nedokážu si představit situaci, kdy by bylo 100 druhů kolizí. Většinou jich bude několik málo. A pokud u kolize různých objektů má program reagovat různě, pak je, samozřejmě, musíš všechny zpracovat.
V případě pac-mana by nebylo ani 5 typů objektů a 2 typy kolizí. Kvůli rychlosti se pak používá spíše vector execution (aka delegates). Takže objekt bude mít metodu update(), kterou si registruje do hlavního enginu. Engine pak volá update() před každým vykreslením framu. Objekt se potom chová autonomně a stará se sám o sebe.
No... a to je v podstatě celé. Algoritmus, který jsem uvedl v předchozím příspěvku, se dá použít i tady, a když pac-man testuje své kolize, bude to provedeno v konstatním čase.
Zobrazeno 13 zpráv z 13.
