Android Programjaim

Android, Flutter/Dart, Kotlin, Java, Unity, HarmonyOS

Android jBox2D kis áttekintő, mi-merre-hogyan

2011. május 06. 12:53 - lacas8282

Üdv!

Mivel magyar oldalról nem igazán tudok, ahol lenne Box2D ismertető, így pár dolgot leírok róla. Először is a Erin Catto írta még c++-ban anno. Mi is ez? A Box2D egy fizikai szimuláció/rendszer, amely lehetővé teszi, hogy ne kelljen saját magunknak megírni bonyolult fizikákat/matekot, hanem használjuk ezt a már készen kapott dolgot. Leírás róla. Megmondom őszintén: ha ezzel szeretnénk foglalkozni, és hiányos az angol tudásunk, vagy ha van is angol tudásunk, de bizony szívni fogunk. Google és van pár oldal, az igaz...de én pl. egyszerre 70-80 oldalt nyitottam meg és ez alapján tanultam/fejlesztettem.

Elsőre persze bonyolultnak tűnik, mivel elsőre az is...Lényegében amúgy arról van szó, hogy egy általános fizikai cuccot kapunk, testekkel, alakzatokkal, vertexekkel, polygonokkal.

Vertex: egy pont gyakorlatilag.
Polygon: sok összekapcsolt vertex, amely egy formát alkot 2D-ben.

Először is: akinek nincs elég nagy fejlesztési tapasztalata az bele se vágjon. Értsd: java-ban jar file inkludolása, re-buildelése, c#-es tapasztalatok, Flash AS3 fejlesztési tapasztalat... Mivel a neten lévő legtöbb segítség sajnos Flashben van megírva. Ezt bizony át kell írni arra a nyelvre amire akarjuk... Nem is beszélve a C#-es ökörködésekről (mint pl. egy alakzat vertexeinek meghatározása, azaz a polygonjának kinyerése /persze erre vannak kész cuccok: lásd phisycsseditor/)

Flashdevelop letöltése, mivel már említettem, hogy a neten Flash support a legerősebb. 
Android/Java support egy vödör kaki...

Még amivel számolni kell: hiába tudunk jelen esetben AS3-ul, C#-ül, Java-ul, bizony a legújabb Box2D verzióban (2.0.1 (2008-as)) sok dolog máshogyan van, mint az eredeti doksiban. Azaz vannak olyan dolgok, amiket átírtak benne, vagy jelen esetben nincs is benne a JBox2D-ben.

Akkor lássunk neki...Feltételezem, hogy a kezdeti nehézségeken túljutottunk, azaz felállítottunk egy ütőképes kit java/android projectet, és a /libs könyvtárba beleraktuk a jbox2d.jar filet. Majd hozzáadtuk a projecthez...

A legelején egy furának tekinthető dolog: a Box2D alap egysége ugyanis a méter, és nem a pixel.:) Persze... Szóval hülyeség lenne, ha mi pixelben adnánk meg a poziciókat a Box2D számára, illetve a méreteket.

Sok változás nem lesz, azaz csak annyi, hogy a méter-pixel közti váltószám 30, azaz, amikor egy testet definiálunk a box2d számára, akkor bizony a test poziciójának pixel méretét el kell osztani 30-al. Célszerű, ha nem varázsszámokkal dolgozunk, hanem egy konstanssal. Megint csak célszerű, ha final static-re rakjuk a dolgot, mert akkor gyors.

private final static RATIO=30;

Remek! Állítsuk akkor fel végre az első Box2D-s cuccunkat!

Az egésznek a forrása marha egyszerű, íme:

        worldAABB = new AABB(); 
        worldAABB.lowerBound.set(lower); 
        worldAABB.upperBound.set(upper); 
 
        world = new org.jbox2d.dynamics.World(worldAABB, gravity, doSleep); 

általában ugye b2Vec2-vel dolgozik a box2D, ami egy x,y-ot vár fura mód, ami float érték.

Tehát a lower, és upper valamint a gravitáció így fog kinézni:

...create() {
        Vec2 lower    =new Vec2((float) 0, 0);
        Vec2 upper    =new Vec2((float) height+5)/RATIO, width+5)/RATIO);
        Vec2 gravity =new Vec2((float) 0, (float) 10);
}

nyilván mindenki rájött, hogy a lower illetve az upper értékekkel magát a területet határozzuk meg, ahol történni fog a szimuláció. Ez egy rectangle..

Míg a gravity értékkel pedig a gravitációt határozzuk meg. Ez lehet akármi...később a telefon szenzorjához is rendelhetjük... A lényeg, hogy a 0, 10 az egy kb-i 9.81-es gravitáció, és ilyenkor ugye lefele fog hullani a test, míg -10 esetén felfele.

Ugyanígy 10,0 esetén jobb oldalt lesz a gravitáció, és -10-nél baloldalt.

Következő pár sor:

        mWorld = new box2d.physics.PhysicssWorld(); 
        mWorld.create(lower, upper, gravity, true);

Hm...oké elkészült a terep eddig jók vagyunk...de még semmilyen test sincs sehol...

Hát hajrá...

        BodyDef bodyDef     = new BodyDef(); 
        bodyDef.position.set((location.x+(size.width/2))/RATIO,(location.y+(size.height/2))/RATIO);
        bodyDef.angle        =angle;
       
        Body body = world.createBody(bodyDef);
        body.m_userData        =name;
       
        PolygonDef shape     = new PolygonDef(); 
        shape.setAsBox((size.width/2)/RATIO, (size.height/2)/RATIO);
        shape.density         = density;
        shape.restitution   = resti;
       
        body.createShape(shape); 
        if (type==BODY_TYPE.DYNAMIC)    body.setMassFromShapes();

elemezzük: BodyDef egy test definiciója, megadjuk a test pozicióját a már említett RATIO-s osztással. Egyébként a location és size változónk egy-egy class Location és Size class, ami tárolja x,y-t, és width, height-et. Csak hát így szebb nah...

angle-vel megadjuk, hogy a test melyik szögben álljon. létrehozzuk a testet a világban és elnevezzük. az m_userData arra jó, hogy oda bármit bepakolhassunk, amire szükségünk van, jelen esetben elnevezzük, így később hivatkozni tudunk rá.

definiálunk egy Polygont, ami egy BOX lesz, tehát téglalap alakú cucc, aminek megadjuk a méreteit, kettővel elosztva. megadjuk a test jellemzőit azaz density (sűrűség, tömeg), restitution (rugalmasság) és lehetne még súrlódást is.

létrehozzuk a polygonunkat és hozzárendeljük a testünkhöz. Ha a testünk dinamikus, akkor szükség van arra, hogy közöljük a rendszerrel, hogy ez bizony dinamikus, azza mozogni fog. (body.setMassFromShapes();) más esetben statikus lesz, azaz helyhez kötött.

Tudni való itt: Egy body (test) több alakot is tartalmazhat.

A box2d csak konvex cuccokat kezel, konkávot nem, de ez se probléma, mert konkáv shape-et is lekezelhetünk, csak akkor a shape-et triangulálni kell, azaz beszéljen egy kép helyettem:

 Szóval ha van egy olyan képünk (mondjuk egy banán), amiből szeretnénk egy polygont készíteni mi a teendő? Először is készítünk egy transzparent png képet, amin már csak a banán alakja van, és használjuk mondjuk a physicseditor-t, majd a kapott értékeket egyszerűen hozzáadjuk a testhez. Ezt egyébként Delaunay triangulation-nak nevezik. A fenti kép érdekessége, hogy egy Open Framework-öt felhasználva akár egy webkamerán keresztül, és egy képfeldolgozó API-val, mint pl a AForge C#-re real-time azaz futási időben is létrehozhatunk a Box2D-ben egy olyan Polygont (testet), ami pl a testünket vizualizálja, majd ezek alapján jó kis mókákat hozhatunk létre. Én igazából ennek nem látom még az értelmét, de játszani jó.

De eltértünk a tárgytól... A kirajzolás még nincs meg, de ezt rátok bízom. (vagytok annyira PRO-k, ha fejleszteni akartok.. én OpenGL ES-ben írtam a vizualizációt)

Mit tud még a Box2D? Joint-okat, azaz pl testeket kapcsolhatunk össze, RevolutionJoint (pl egy kötél), GearJoint (pl egy autó kerekei) stb.

Azt hiszem mára ennyi elég is volt, eléggé lefáradtam.:)
 
Végül kis kedvcsinálás: 

komment
süti beállítások módosítása