Ce este într-un motor de fiziologie proiectilă?

În acest articol, vom examina utilizarea fizicii pentru a simula efectele proiectilelor în jocuri precum Angry Birds. Vom analiza elementele de bază ale utilizării fizicii 2D în spațiul lumii jocurilor, cum ar fi crearea corpurilor și aplicarea impulsurilor și forțelor.

Fizica motoare

De ce să folosiți un motor de fizică? Ce face de fapt? 

Un motor de fizică ne ajută să facem două lucruri foarte importante pentru jocul nostru:

  1. Detecta coliziuni între obiectele din joc.
  2. Simula forțele și mișcarea rezultată a obiectelor noastre din acele coliziuni ...

Detectarea coliziunii: Jocurile nu s-ar distra prea mult dacă personajul tău a căzut prin podea înainte să poți sări, sau dacă, atunci când ai lovit un dușman cu piciorul tău, ai căzut prin dreapta. Detectarea coliziunilor utilizând un motor de fizică permite ascultarea foarte precisă a contactului și permiterea interacțiunilor între obiecte care trebuie simulate folosind forţele.

Forța de simulare:După o coliziune, ce ar trebui să se întâmple? Logica jocului poate fi apelată, puteți săriți, celălalt obiect de joc ar putea sări, sau nu vă puteți mișca mai departe. Acest lucru este tratat în spatele scenei, folosind forțele calculate ale motorului. Dar forțele nu se limitează la contact; pot apărea alte forțe, cum ar fi gravitatea și impulsurile, fără a atinge obiecte. Forțele afectează acțiunile în joc și mișcarea obiectelor, a personajelor și chiar a spațiului mondial însuși.

.

Ne vom uita Cum motoarele de fizica functioneaza in scurt timp, dar mai intai lasa privim ce motoare pe care ați dori să le utilizați și De ce puteți decide să le utilizați, pe baza nevoilor dvs. specifice.

Alegerea motorului

Când începeți să vă gândiți mai întâi la utilizarea fizicii în jocul dvs., va trebui să decideți cum doriți să abordați problema și ce va necesita jocul dvs. în termeni de simulare. Aveți două opțiuni pentru utilizarea fizicii:

  1. Utilizați un motor fizic existent.
  2. Creați o simulare fizică personalizată

Folosind un motor fizic existent

Există câteva opțiuni excelente pentru motoarele de fizică predefinite și gata de utilizare. Una dintre cele mai populare alegeri pentru jocurile 2D este Box2D; este un motor scris nativ C ++, dar are ambalaje, porturi și extensii care îi permit să fie utilizat în aproape orice platformă 2D. O altă alegere populară este Chipmunk 2D, care este folosită în mai multe motoare de jocuri, cum ar fi Cocos2D.

Crearea unui motor personalizat

În unele jocuri, utilizarea unui motor predefinit nu este neapărat alegerea optimă. Folosirea unui motor de fizică poate provoca unele cheltuieli inutile atunci când funcția completă nu este necesară. În cazul unor platforme simple sau în jocuri de tip "brick-breaker" - în cazul în care nu aveți nevoie de detectarea coliziunilor pixel-perfectă sau de unele dintre celelalte capabilități ale unui motor - aceasta poate consuma în mod inutil resurse care ar putea fi folosite mai bine în altă parte. 

Construirea propriului motor vă poate oferi mai multă flexibilitate în ceea ce privește produsul final, dar poate face lucrurile mai complicate dacă aveți de-a face cu mai multe cazuri de caractere și obiecte.

Jocul Loop

Înainte de a discuta despre proprietățile și detaliile unei simulări fizice, să ne uităm la modul în care se numește în bucla scenei dvs. de joc.

Bucla tipică de joc va trece prin următoarele pentru fiecare cadru, în ordinea:

  1. Intrare
  2. Update / Joc Logic
  3. Simulați fizica jocurilor
  4. Render Screen / Scene

Aceasta înseamnă că calculul fizicii rezultate este ultima sarcină efectuată în buclă înainte de actualizarea ecranului. Acest lucru are sens, deoarece punctul de simulare este de a reacționa la ceea ce sa întâmplat în spațiul de joc al lumii. 

Rețineți că această imagine arată că fizica este simulată în fiecare cadru al jocului. Acest lucru poate duce la unele cheltuieli mari dacă simularea dvs. devine prea mare sau complicată. Din acest motiv, cel mai bine este să păstrați managementul jocurilor și apelurile la simulare și ascultătorii săi limitate. 

Rata fixă ​​vs. Fizica dependentă de cadre

Este logic să discutăm acum două metode diferite de interogare a simulării fizicii: rate fixe față de cadre. Considera (Void) actualizare: metodă consecventă în majoritatea buclelor de joc. Această bucla este numită o dată pe cadranul scenei jocului. Dacă este chemată metoda "simulați fizica" (Void) actualizare:, fizica lumii jocului va depinde de rata de cadre, și asta poate sa conduc la unele simulări nerealiste și nerealiste. În iOS, acest efect este atenuat prin utilizarea usesPreciseCollisionDetection Proprietatea booleană, dar ce zici în alte motoare? 

Luați în considerare următorul segment de cod:

 CFTimeInterval timeSinceLast = actualTime - auto.lastUpdateTimeInterval; self.lastUpdateTimeInterval = actualTime; dacă (timeSinceLast> 1) timeSinceLast = 1.0 / 60.0; 

Acest cod este destinat să compenseze problemele cu valoarea delta pentru timp. Luați în considerare o situație în care jucați jocul pe telefonul dvs. și ați primit un apel: acesta ar ajuta jocul dvs. pentru a vă reinițializa delta înapoi la jocul așteptat 1/60 (pentru un joc de 60 fps). 

Acesta este de fapt primul pas într-o discuție privind decuplarea simulării fizicii de la etapa de timp a (Void) actualizare: metodă. În timp ce un interval de timp modificat ar ajuta cu siguranță la un apel de simulare fizică mai stabil, acesta nu este corect pentru toate situațiile. Pentru a face acest lucru, ar trebui să facem asta elimina apelul de simulare a fizicii de la bucla de redare a jocului și crearea unui ciclu fix în care ar putea funcționa. De exemplu; dacă jocul dvs. este menit să ruleze la 60 fps, setați fizica să simuleze de 60 de ori pe secundă. Această decuplare elimină orice preocupări legate de problemele de randare care cauzează reacții încurcate în simularea fizică.

Pe scurt, fii conștiincios în implementarea fizicii. Dacă vă aflați folosind un motor într-un mediu în care taxați resursele sistemului, luați în considerare o simulare fizică fixă ​​pentru a menține corectitudinea și fidelitatea.

De la Sprite la corpul fizicii

A spiriduș este o imagine redată pe ecranul jocului. Un sprite nu are proprietăți implicite în cadrul unei simulări fizice. Puteți "falsifica" unele dintre comportamentele unei lumi fizice prin utilizarea proprietăților unui sprite, cum ar fi o casetă de legare și un apel de intersecție, dar atunci trebuie să scrieți singură toate logica rezultată. Nu ar fi mai bine dacă jocul ar putea face toate astea pentru noi?

În aceste fragmente, creăm un sprite:

 SKSpriteNode * sprite = [SKSpriteNode spriteNodeWithImageNamed: @ "imagine"]; sprite.position = locație; [auto addChild: sprite];

... și apelați o ciocnire între două sprite:

-(void) actualizare: (CFTimeInterval) currentTime / * Chemată înainte ca fiecare cadru să fie redat * / if (CGRectIntersectsRect (sprite1.frame, sprite2.frame)) // face ceva

Formele corpului

Fizică organisme sunt forme "simple" care definesc dimensiunea și forma durității sprite-ului tău, sau poate defini o zonă activă a sprite-ului tău. Luați în considerare următoarele:

Un corp fizic nu este predefinit de imaginea sprite-ului tău și este de obicei invizibil în joc. Creați forma dinamic, adesea apelând o metodă pentru a desena forma care va alcătui corpul sau folosind un program care vă ajută să trageți și să definiți corpul. Apoi atașați corpul la sprite și obțineți acces la efectele și proprietățile simulate atribuite acelui corp.

Puteți avea mai multe corpuri fizice legate de un singur sprite. Luați, ca exemplu, un sprite al unui erou care poartă o sabie. Ar fi logic să creezi un corp pentru personajul eroului și altul pentru sabia pe care o poartă. Acest lucru vă va permite să creați logica jocului bazată pe coliziunile dintre diferitele corpuri. 

În pseudocod, logica ar arăta astfel:

// logică fizică - (void) physicsCollisionDidOccur comutator (coliziune bitmask) caz (Player || Sword): // nu face nimic; pauză; caz (Jucător || Enemy): // ouch !!; pauză; caz (Sword || Enemy): / / face daune! pauză; implicit: // nu face nimic; pauză; 

Relatând corpul fizicii Sprite-ului

Luați în considerare situația unui joc spațial, unde aveți o nava de erou și o navă inamic:

Probabil doriți să transformați corpul de fizică al jucătorului într-un pic mai mic decât imaginea de bază a spritei din două motive:

Coliziunea vizuală îmbunătățită: Atunci când un jucător se ciocnește cu un obiect din joc, prin crearea acestui corp fizic mai mic, imaginile sprite se vor suprapune temporar în punctul de contact care arată bine vizual. (În plus față de acest punct: când desenați valorile z, păstrați caracterul jucătorului dvs. în fața ierarhiei scena.)

Percepția percepută de către utilizator: Pentru a încerca să-ți faci jocul "echitabil" cu jucătorul, păstrezi corpul care se poate coliziune limitat la cea mai mare parte a obiectului și departe de proeminențele străine, cum ar fi fundul din spate al imaginii de mai sus. În acest fel, nu vor exista "lovituri ieftine" pentru a deranja jucătorii din joc. În schimb, de obicei, doriți ca corpul fizic al inamicului să fie cel puțin la dimensiunea imaginii de bază; dacă dăm eroului nostru spațial un laser pentru a-și împușca inamicul, un corp inamic ușor-prea mare îl face mai rezonabil ca jucătorul nostru să obțină un hit. Luați în considerare, de asemenea, aceeași abordare pentru plăci în platformer sau joc de puzzle care cere jucătorului dvs. să sară de la platformă la platformă. Jucătorii sunt obișnuiți cu un "grație" puțin în aceste tipuri de jocuri; extinderea corpului fizicii o tad va ajuta la menținerea jocului în mod rezonabil "corect".

Constrângeri tipice ale motorului 2D

Există două tipuri principale de corpuri de fizică:

  1. Corpurile de bază
  2. Organisme bazate pe volum

Un corp bazat pe margine este o linie statică, imobila care creează o limită pentru ca alte organisme să se ciocnească. Are o spațiu negativ în interiorul său, care nu are niciun efect asupra oricărui corp. O aplicație foarte bună a acestui lucru ar fi să creați o limită în jurul ecranului dvs. pentru a conține orice corpuri din interiorul acestuia.

Un corp pe bază de volum are volum și masă și poate fi dinamic sau static. Deoarece aceste corpuri au obiecte de masă, obiectele le izbesc și pot fi afectate de contactele forțate. Trupurile bazate pe volum pot fi oricare dintre cele patru forme principale:

  1. Cerc
  2. Dreptunghi
  3. Lanţ
  4. Complexul poligon

Există unele constrângeri în utilizarea corpurilor din motorul tipic fizic 2D. Iată cele două limitări principale:

Convex Physics Bodies 

Dacă este o formă convex, înseamnă că nici un unghi interior nu este mai mic de 180 de grade. 

Pentru a fi clar, este posibil să se efectueze simulări fizice pe forme concave, dar costul de procesare este atât de ridicat încât nu este realist pentru 2D, mai ales atunci când rulează pe un dispozitiv portabil sau mai puțin puternic. Concav-ca formele pot fi construite prin legarea a două forme convexe folosind ceva numit a Articulație statică. Îmbinările sunt o altă caracteristică excelentă disponibilă cu motoarele 2D, dar sunt în afara domeniului de aplicare al acestei discuții.

Corpuri fizice rigide

Când o minge lovește un zid, în lumea "reală" se va întâmpla așa ceva:

Personajul tău spiriduș pot suferi acest tip de transformare, ci corpul său de fizică nu poti. Puteți controla anumite proprietăți ale corpului pentru a le afecta "bounciness", dar nu poate avea o formă mutable. Aceasta este cunoscută sub numele de a Corp rigid, ceea ce înseamnă că organismul însuși nu poate fi deformat sau stricat.

Proprietățile corpului fizicii

Să aruncăm o privire rapid asupra a ceea ce unele dintre cele mai utile proprietăți disponibile pe un corp fizic tipic sunt:

  1. Restituire este o măsură a modului în care "bouncy" este un obiect. Mai formal, măsurarea cantității de energie pe care o reține un obiect după ce se ciocnește cu un alt obiect.
  2. Densitate este măsura în care este un obiect greu. Este folosit ca o calitate relativă - de exemplu, o piatră ar fi mai densă decât o minge, astfel că atunci când mingea lovește piatra, va fi afectată mai mult.
  3. Frecare este măsura în care este un obiect "alunecos". Acest lucru este folosit atunci când un obiect alunecă de-a lungul altui element și determină cât timp va dura să se oprească.
  4. Dacă este un corp dinamic, atunci forțele impuse de ea de către lume și alte obiecte vor avea un efect; dacă este a static corp, atunci nu vor.
  5. Rotație este de obicei o variabilă booleană care poate fi setată pe un corp de fizică. În anumite cazuri, poate doriți să limitați un corp și să nu îi permiteți să se rotească, dar doriți ca forțele să fie încă aplicate acelui obiect.

Majoritatea motoarelor au mai multe proprietăți disponibile decât acestea, dar pentru scopurile acestei discuții, acestea vor fi suficiente pentru a începe.

Mișcare și moment


Într-o lume fizică simulată, corpurile sunt mișcate de aplicarea lui forţele și impulsuri.

Forțele: Forțele generale afectează în mod tipic corpurile mai treptat decât impulsurile. Sunt o forță constantă care se aplică timp de unitate (cum ar fi gravitația sau motorul).

Impulsuri (forțe impulsive): Impulsurile sunt ajustate imediat la ritmul unui organism. Impulsurile sunt de obicei aplicate unei simulări bazate pe intrarea utilizatorului.

Ce urmează?

Acum, că înțelegeți teoria, cel mai bun mod de a vă întări înțelegerea motoarelor de fizică a proiectilelor este să vă construiți unul singur. În continuare, voi distruge codul pentru un joc bazat pe fizică, pe care l-am scris, pentru a vedea exact cum funcționează!