HTML

Survive Developement

Itt olvashatod a Survive! nevű játék fejlesztésének állapotát, lépéseit. És mi is lesz a játék? Egy zombis-túlélős játék, ahol elsősorban a csapatmunkára építkezve kell megpróbálni életben maradni egy kihalt városban. A terep teljesen a tietek, nincsenek szabályok: éljetek túl, ahogy tudtok!


Küldj e-mailt nekünk:
gilgamesco@gmail.com

Sikolyok

Ettől tépjük a hajunkat:

Friss topikok

  • Sir Butcher: A gyors mozgású ütközés-érzékelés majd a lövésnél lesz topic :D A második esetben teljesen igaza... (2012.04.05. 16:38) Ütközésérzékelés
  • _fpeti_: Halad ez. (2012.04.04. 22:01) Gravitáció
  • Sir Butcher: Az sem rossz, az tény :D Szerencsére egyelőre annyi különbözőt kell csinálnom, hogy esélyem sincs ... (2012.02.20. 21:48) Scenery - Még több látvány
  • Sir Butcher: Na, ideírom: obj-nél megoldottam a csontokat. Melléktermékként összejöttek, extra számítás nélkül ... (2011.12.02. 11:48) Model Animálás - a probléma, és a (vélt) megoldás
  • Burwor: "A tesztvárosban sétálgatva belefutsz egy házba, aminek hiányzik egy fala. Mit csinálsz?" Zárva a... (2011.11.10. 15:00) Sziduri - a grafmotor bemutatkozik

Ütközésérzékelés

2012.03.28. 18:32 :: Sir Butcher

Ez megint ismeretterjesztő jellegű bejegyzés lesz, szóval akit annyira nem köt le, az görgessen az aljára, van videóm is :)

Elsőnek, pár szóban, mi is az az ütközésérzékelés? (Jó, tudom, a nevéből ered, de itt picit mást értünk rajta azért). Neve alapján az a kód, ami képes érzékelni adott objektumok ütközését. Ez pedig számtalan ok miatt fontos: legtriviálisabb ok az, hogy ne lehessen átmenni a falon, például. De igazából a legtöbb interakciót ütközésérzékelésre lehet levezetni grafikában, hiszen attól, hogy nem mész át a falon, keresztül a lelökhető poháron (a lökés a lényeg, nem az esés :) ) át egészen addig, hogy kinyitsz egy ajtót, számtalan helyzet van, ahol így oldhatóak meg a feladványok.

Na, de nézzük részleteiben! Mivel az ütközésérzékelés az egyik legerőforrás igényesebb művelet (már ha szeretnénk realisztikus pontosak lenni.) Annál több számításigénye talán csak a fényeknek van. Mivel egy komplexebb modell/objektum akár pár százezer háromszögből is felépülhet, és nekünk ezeket mind meg kell vizsgálnunk, hogy érintkeznek-e. Ez két modell esetében nem probléma (annyira) hiszen pár millió műveletben megoldható a dolog. Igen, de a legritkább esetben fordul elő olyan, hogy csupán két objektum van a képernyőn. És ahogy több testet adunk hozzá a kereséshez, úgy növekszik egyre gyorsabban azon pontok száma, amiket egymáshoz képest vizsgálni kell. Ez pedig lehetetlen.

Tehát, a fent vázolt modell, pontosabban megfogalmazva, a pixel-szintű összehasonlítás egy teljes tájra levetítve közel kivitelezhetetlen, bár az tény, hogy rendkívül pontos. A valóságot nem éri el, de nagyon megközelíti. Igen, de mi marad helyette? Jönnek a valóságot egyszerűsítő modellek, vagyis az "ütköző testek" normálisabb szóval "bounding volumes" (de tippem sincs, hogy van ez magyarul).

Ezekre már egy korábbi bejegyzésben kitértem, így csak pár szóval: létrehozhatunk egy gömböt (pont és attól való távolság matematikailag) és egy téglatestet. Ezek ütközését vizsgálni nagyon egyszerű dolog - viszont nagyon pontatlan is, hiszen alapállapotban azt tudjuk csak meg, hogy egyik a másikban van-e, érintkeznek, vagy sem. Három állapot néhány esetben elég, sokban viszont nem.

Elsőnek nézzük az "általános" eseteket, mikor tökéletesen elég. Ez volt az, amin az elmúlt napokban (vagy hétben?) dolgoztam, vagyis az ajtó kinyitása. (Az animáció igazából mellékhatás volt, de lényegtelen.) Ehhez ugyanis elsőnek kellett egy doboz, amivel körbevehetem az ajtót - ugyanis gömböt létrehozni egyszerű, de a legtöbb tárgyunk legpontosabban téglatesttel írható körbe, anélkül, hogy rendkívül sok fölösleges teret zárnánk mellé. Mint például az ajtófélfa, vagy az ajtó maga. Itt tehát egyszerű esetem van: ha ütközés van a modellt körbevevő testtel, akkor ütközik, vagyis nem mehetsz tovább, ha nincs, mehetsz. Eddig egyszerű, és remek.

A probléma ott kezdődik, amikor megjelenek a dinamikus objektumok: ezek folyton mozognak, és velük együtt forognak is. Tehát folyton-folyvást kénytelen vagyok a dobozaikat változtatni ahhoz, hogy rendben legyen a későbbiekben az ütközés-érzékelés. Erre a legegyszerűbb megoldás az az elv, hogy: "Amit nem kell kiszámolni, gyorsabb, mint bármi, ami ki kell" (vagy valami ilyesmi). Tehát egyszerűen felosztottam mezőkre a terepet: a középsőben van a játékos, és a környező nyolcat jelenítem még meg. Ezek mérete szépen változtatható, és az összes többivel nem kell foglalkozni. Tehát nagyon szépen le tudom csökkenteni a lehetséges ütközések számát mindössze a pálya kis szeletére. Kevés modell + kevés lehetséges ütközés = gyors ellenőrzés.

Vagyis az ajtómra levetítve: az algoritmus összeszedi azon modelleket, amiket meg kell jeleníteni az adott 9 négyzetben. Ezekből összeszedi azokat a boundingbox-okat, melyek esélyesek, hogy ütközhetnek (vagyis jelenleg a középsőt, ahol a játékos van, vagyis az "aktív" négyzet), majd, amikor updatelem a modellt (egészen pontosan animáció történik) akkor szépen megvizsgálja, hogy az animáció KÖVETKEZŐ lépése okoz-e ütközést. Azért emeltem ki, mert egy fontos lépés: ugyanis ha elsőnek lépne a modell, és csak utána frissülne, akkor nagyon szépen egymásba "ragadnak" és csak megfelelő "nagyságú" lépés után szabadulnak ki egymásból. (Ismerős néhány játékból talán... :) ) Tehát elsőnek megnézem, mi lenne a következő lépésben: ha ütközés, akkor nem történik meg a lépés - ha nem, akkor a kiszámolt állapotot elmentem.

És máris megvan az ajtó-animáció-elakadás megvalósítása. Na igen ám, de hogyan nyitom ki? Honnan tudja az ajtó, hogy éppen ránézek, éppen azt nyitnám ki? Ismételten egyszerűen: húzok egy vonalat a kamera pozíciójából kiindulva át a kamera célpontján (amerre néz). Mint matekból tudjuk, két pont meghatároz egy egyenest - én pedig fogom, és megnézem, hogy ütközik-e az adott ajtóval, illetve hol. Ha ütközik valamelyik ajtóval (értelemszerűen csak azzal, amelyikre nézek éppen) akkor ellenőrzöm, hogy a karakter adott távolságra (kb kéznyújtásnyira, de ez igazából jelenleg hasraütés érték, majd pontosítom) történt-e az ütközés. És  valóban az ajtóval történt-e az ütközés, nem mással. Ha igen, aktiválom az animációt, ami elvégzi a fenn vázolt lépéseket.

Ez szép és jó, immáron tudjuk, hogyan lehet leverni egy poharat az asztalról, de például hogyan lehet lelőni valakit így? A vicc az, hogy játékban ugyanis lősz fejbe valakit, mint ahogy kinyitod az ajtót (jó, technikailag): húzol a fegyver csövétől a célpont irányába egy egyenest, és megnézed, találkozik-e a modellt körbevevő box-al, illetve, azzal találkozik-e elősször. Ha igen, akkor találat. A modellt több ilyen dobozra felosztva pedig azt is megtudod mondani, hogy egészen pontosan hol találtad el a modellt. (igazából így működik a legtöbb játékban, annyi módosítással, hogy ez így túl könnyű lenne: tehát a gomb megnyomásakor nem végzi el ezeket, hanem csak akkor, ha végetért az animáció. Tehát a legtöbb játékban a játékos megnyomja a gombot, eltelik 1-3 másodperc [vagy akármennyi] és csak utána húzza meg az egyenest - játékos szemszögből ez olyan, mintha időbe kerülne a golyó haladása - pedig "igazából" nem is :)

És, végül, ahogy ígértem, a videó - bár twitteren már kiraktam :)

 

4 komment

Címkék: survive volumes sziduri bounding ütközésérzékelés

A bejegyzés trackback címe:

https://survivedev.blog.hu/api/trackback/id/tr784346294

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

_fpeti_ 2012.04.01. 21:13:44

Jól néz ki a dolog.

Sir Butcher · http://survivedev.blog.hu/ 2012.04.01. 22:47:23

Köszi, igyekszünk amennyire csak lehet :D

Pretender 2012.04.05. 11:54:31

"Tehát elsőnek megnézem, mi lenne a következő lépésben: ha ütközés, akkor nem történik meg a lépés - ha nem, akkor a kiszámolt állapotot elmentem."

Alap megoldásnak jó, de van pár extrém eset. Mondjuk ezeket ki lehet zárni design-time, csak gondoltam megemlítem:
- ha az adott object túl gyorsan mozog, akkor előfordulhat, hogy a jelenlegi és a következő lépése sem ütközik, de közben mégis átment rajta.
- ha a következő lépés ütközik, akkor a legpontosabb eredményt az adná, ha elmozgatnád az (ütközési pont - epszilon)-ig, hiszen gondolj csak bele. Tfh 1 update alatt 10 fokot fordul az ajtó, és mondjuk úgy áll ott a játékos, hogy az ajtó következő lépése már éppen érinti, akkor lesz egy kis "lyuk" a kettő között.

Persze mind a kettő szinte elhanyagolható. És hogy ne csak 'kritikát' írjak: jó lesz, hajrá! :)

Sir Butcher · http://survivedev.blog.hu/ 2012.04.05. 16:38:54

A gyors mozgású ütközés-érzékelés majd a lövésnél lesz topic :D

A második esetben teljesen igazad van, de ez most jelenleg a "goodenough" témába vág. Halálosan pontosat nem tudok elérni, ez viszont a célnak tökéletesen megfelel. Kétlem, hogy bárkinek feltűnne az az apró különbség, 0.75° különbség a maximum az ajtó esetében, a jelenlegi animáció mellett. Ezt elhanyagolhatónak véltem :D

De amúgy abban is igazad van :)

Meg köszi :D
süti beállítások módosítása