JavaScriptゲヌムパヌト1. Box2dず物理の基瀎



序文の代わりに。


私はい぀もコンピュヌタヌゲヌムが倧奜きで、倧奜きです。 圌らはある皮の独自の内郚魔法を持っおいたす。それは垞に同時に魅力的で魅力的です。 私の人生では、ベテランのWolfensteinやDune 2から珟代の倧ヒット䜜たで、䜕十ものゲヌムを繰り返しおきたした。 そしお今、次のヒットを終えお最終的なビデオずクレゞットを芋るず、「もしも 」ずいう考えが頭の䞭にたすたすひらめきたす。

しかし、本圓に、あなたがあなた自身のゲヌムを取り、曞いたらどうでしょう もちろん、AAAのタむトルを単独で行うこずはできないこずは明らかです。これらは長幎にわたる䜜業などですが、道は進むのでしょうか。 たたたたデスクトッププログラミングでは率盎に蚀っお匱いので、Web開発者にずっおはそれほど倚くの遞択肢はありたせん。 しかし、近幎、すべおが劇的に倉化し、今ではブラりザヌはコヌヒヌメヌカヌず倚くの共通点があり、javascriptは私のようなものではなく、軍事郚門のニヌズも簡単に満たすこずができたす。

次の思考ずかなり深刻な颚邪の最䞭に、Ant.Karlovのゲヌム孊者でBox2dに関する蚘事に出䌚いたした。 読んで倢を芋た埌、私はすぐにこのラむブラリのJSポヌトを芋぀けたした。そしお、䜕かを小さくするずいう叀いクレむゞヌなアむデア、そしお最も重芁なこずは私のものが、元気を取り戻し始めたした。

䞀般に、より少ない哀れみ、より倚くの仕事。 興味を持っおいただければ幞いです。 CPAPでAngry Birdsを䜿甚するこずを厳しい神が蚱しおくれたす^ _ ^

玹介ず免責事項


䞀連のノヌト党䜓の最終的な目暙は、少なくずも3皮類の投weapon歊噚ず5぀の異なるレベルで、Angry Birdsの本栌的なクロヌンを䜜成するこずです。 はい、すでに十分な数があり、さたざたなレむアりトであり、Angry Birds自䜓も少なくずも3぀のバヌゞョンですが、䜕かを緎習する必芁がありたすか その過皋で、物理゚ンゞン自䜓、ラスタヌグラフィックスの凊理、レベル゚ディタヌこれは間違いなく必芁、メニュヌ/クレゞット/蚭定の圢匏のバむンディング、サりンドず音楜、その他䜕千もの重芁なこずすべおに觊れようずしたす。 実際、私自身はただこれらのすべおを持っおいるわけではありたせんが、執筆の過皋で、䜕をどうやっおやったのか、そしおそれが䜕に぀ながったのかをここで説明したす。

いく぀かの特に長いコヌドを楕円で瀺したす。 特にむラむラする人のために、メモの最埌に実際の䟋ぞのリンクがありたす。

唯䞀のこず-私はプロのゲヌム開発者ではありたせん。非垞に倧きなヒヌリングレヌキず倧きなバンプの詰め蟌みの助けを借りお倚くの手順が䞎えられたす。そのため、どこかで間違いを犯した堎合、厳密に刀断せず、トマトを投げないでください。

行こう


それでは始めたしょう。 最初に必芁なこずは、ゲヌムワヌルドを䜜成し、テストレベルを入力しお、最初の「鳥」を最初の「豚」に投げ蟌もうずするこずです。 Angry Birds自䜓で疑䌌珟実の物理孊を芋たので、ゲヌムの䞖界で衝突や鳥、豚、その他のオブゞェクトの移動を凊理するのに忙しい物理゚ンゞンが必芁です。

いく぀かの理由から、物理゚ンゞンずしおBox2dを遞択したした。

1.圌にはかなり匷力なFlashコミュニティがあり、ヘルプやアドバむスを求めるこずができたす。
2.䜿甚するこずにしたBox2dWebラむブラリは、盎接Box2dASポヌトであるため、少なくずも参照APIは既に存圚したす。
3.反モンゎル語ではありたすが、開発プロセスず゚ンゞンの内郚に関する十分な情報。
4.そしお、もちろん、䜕癟もの成功したアプリケヌション。

䞀般に、私たちにぱンゞンがありたす。今、私たちは必芁なものを倧たかに想像しお、小さくお快適な䞖界を䜜る必芁がありたす。 おそらく、小さなHTMLブランクから始めたす。 キャンバスペヌゞにドロップしお、ゲヌムのベヌスオブゞェクトを䜜成したす。

< html >
< é ­ >
< title >怒っおいる鳥WRYYYYYYYY !!!! < / タむトル >
< script src = "/js/jquery.js" type = "text / javascript" > < / script >
< script src = "/js/box2d.js" type = "text / javascript" > < / script >

< スクリプト >
$ドキュメント.ready関数{
新しいゲヌム;
};
< / スクリプト >
< 本䜓 >
<canvas id = "canvas" width = "800" height = "600" style = " background- color  333333 ; "> </ canvas>
< / 本䜓 >
< スクリプト タむプ = "text / javascript" >
ゲヌム=関数{
...
}
< / スクリプト >
< / html >


玠晎らしい、さらに実隓するためのテンプレヌトがありたす。 ここで、物理的な䞖界を䜜成し、Box2dを積極的に䜿甚する必芁がありたす。 これが私たちがやるこずです。

ゲヌム= 関数   {

//すぐにオブゞェクトタむプを定数ずしお指定するこずにしたした
const PIG = 1 ;
const BIRD = 2 ;
const PLANK = 3 ;

//「throw」を凊理するずきに必芁になるフラグ。
isMouseDown = false ;

//仮想パチンコの未来のガム
mouseJoint = false ;

//スロヌ凊理䞭に䜿甚されたす
body = false ;
mousePosition = { x  0 、 y  0 } ;

//珟圚のニヌズに必芁なすべおのリ゜ヌス。
//刀読䞍胜で読みにくいコヌドのキロメヌトルをブロックしないように、すぐに再定矩するこずにしたした。
//各リ゜ヌスの倀蚘事の埌半で説明しようずしたす。
b2AABB = Box2D。 衝突 b2AABB ;
b2World = Box2D。 ダむナミクス 。 b2World ;
b2Vec2 = Box2D。 共通 æ•°å­Š b2Vec2 ;
b2DebugDraw = Box2D。 ダむナミクス 。 b2DebugDraw ;
b2Body = Box2D。 ダむナミクス 。 b2Body ;
b2BodyDef = Box2D。 ダむナミクス 。 b2BodyDef ;
b2FixtureDef = Box2D。 ダむナミクス 。 b2FixtureDef ;
b2PolygonShape = Box2D。 衝突 シェむプ 。 b2PolygonShape ;
b2CircleShape = Box2D。 衝突 シェむプ 。 b2CircleShape ;
b2MouseJointDef = Box2D。 ダむナミクス 。 ゞョむント b2MouseJointDef ;
b2ContactListener = Box2D。 ダむナミクス 。 b2ContactListener ;

//ワヌルドを䜜成したす。
world = new b2World 
new b2Vec2  0、10  //重力ベクトル。
、 true // doSleepフラグ。
 ;

init = function   { //オブゞェクトの䜜成時に呌び出される、私たちの䞖界のすべおの初期化
...
}

init   ;
}


䞖界のパラメヌタヌに぀いおもう少し詳しく芋おいきたいず思いたす。 最初は重力ベクトルです。 Box2dは、呚囲の䞖界の物理を十分に詳现にモデリングしおいるため、重力の圱響なしではできたせん。 このベクトルを䜿甚しお、重力加速床をY軞に沿っお1秒あたり10仮想メヌトルに蚭定したす2番目のパラメヌタヌdoSleepは、珟圚非アクティブな芁玠を蚈算しないようにしたす。 これは䜜業速床に倧きく圱響するため、このパラメヌタヌを倉曎するこずはお勧めしたせん。

たた、Box2dがデフォルトで巊䞊隅を開始点ずする座暙系を䜿甚するこずを远加したいず思いたす。

ゲヌムのスクリヌン凊理はフレヌムごずに行われ、Box2dも䟋倖ではないこずをここの誰もが知っおいるず思いたす。 したがっお、オブゞェクトの再蚈算ずグラフィックの再描画のために垞に呌び出されるように、曎新メ゜ッドを䜜成し、このメ゜ッドをSetTimeoutに駆動する必芁がありたす。

ゲヌム= 関数   {
...
init = function   {
りィンドり。 setInterval 曎新、 1000/60  ;
}

曎新= 関数   {
䞖界。 ステップ  1 / 60、10、10  ;
䞖界。 DrawDebugData   ;
䞖界。 ClearForces   ;
}
}


update関数では、たず䞖界の曎新頻床1秒あたり60フレヌムを蚭定し、オブゞェクトの速床ず1クロックサむクルごずの䜍眮の倉化の凊理むベントの最倧数も蚭定したす。 これらのパラメヌタヌを増やすず、党䜓的な反応速床は䞊がりたすが、オブゞェクトの数が増えるず、システムリ゜ヌスに埋もれ、枛少するず、枬定ごずにオブゞェクトの凊理が䞍正確になりたす。 10-非垞に健党な平均。

もちろん、今では、キャンバスを゚ンゞンハンドラヌに結び付けお、䜕かを描くこずができたす。

ゲヌム= 関数   {
...
init = function   {
buildWorld   ;
initDraw   ;

りィンドり。 setInterval 曎新、 1000/60  ;
}

initDraw = function   {
debugDraw = new b2DebugDraw   ;

debugDraw SetSprite  document。GetElementById  "canvas"  。 GetContext  "2d"   ;
debugDraw SetDrawScale  30.0  ;
debugDraw SetFillAlpha  0.5  ;
debugDraw SetLineThickness  1.0  ;
debugDraw SetFlags  b2DebugDraw。E_shapeBit | b2DebugDraw。E_jointBit  ;
䞖界。 SetDebugDraw  debugDraw  ;
}

buildWorld = function   {
fixDef = new b2FixtureDef   ;

fixDef。 密床 = 1.0 ;
fixDef。 摩擊 = 0.5 ;
fixDef。 反発 = 0.2 ;
}
}


はい、珟圚のフォヌムで衚瀺するためにデバッグモヌドのみを䜿甚するこずを远加する䟡倀がありたす。 テクスチャやグラフィックスを䜿甚せずに、物理䞖界のオブゞェクトを盎接衚珟したす。 いわゆる-珟状のたた。 そのため、update関数でDrawDebugDataメ゜ッドを呌び出したす。この衚瀺のために、b2DebugDrawオブゞェクトを䜜成したす。 同じ堎所で、スケヌル、半透明床を蚭定し、正確に描画する必芁があるものをビットで蚭定したす。 詳现に぀いおは、b2DebugDrawのすべおがAPIリファレンスに詳现に説明されおいたす。

たた、Box2dはグリッドデヌタずしおピクセルを操䜜しないこずを远加する䟡倀がありたす。 もずもずは暙準Cシステムを䜿甚するように蚭蚈されおいたため、メヌトル、キログラム、秒、および察応する倉換がありたす。 ここでは、この領域の詳现には觊れたせんが、Box2dビュヌの1メヌトルは玄30ピクセルの画面スペヌスであるこずに泚意しおください。

さお、fixDef構造に぀いおもう少し远加したす-これはオブゞェクト物理孊の基本的なパラメヌタヌのセットです。 この構造では、オブゞェクトの盞互䜜甚のプロセスの物理孊が蚈算される基本的なパラメヌタヌが蚘述されたす。 ご芧のずおり、オブゞェクトの摩擊、密床、匟性のパラメヌタヌを瀺したした。

描画


ゲヌムの仕組みを蚭蚈するずいう倧事な目暙に近づきたしたが、最初にいく぀かのオブゞェクトを私たちの䞖界に眮き、それから䜕かをしようずする必芁がありたす。 したがっお、スペヌスのリミッタヌを構築するinitメ゜ッドに远加し、長方圢を䞍滅のボヌドずしお、円を「豚」ずしおレベルを描画したす。

ゲヌム= 関数   {
...
PigData = function   { } ;
PigData プロトタむプ GetType = function   {
PIGを返し たす。
}

PlankData = function   { }
... // PigData.GetTypeず同様のGetType

buildWorld = function   {
...
bodyDef = new b2BodyDef   ;
bodyDef。 タむプ = b2Body。 b2_staticBody ;

fixDef。 shape = new b2PolygonShape ;
fixDef。 圢状 SetAsBox  20、2  ;
bodyDef。 ポゞション 。 セット  10、600 / 30 + 1.8  ;
䞖界。 CreateBody  bodyDef  。 CreateFixture  fixDef  ;

... //さらに3぀の壁

canvasPosition = $  "#canvas"  。 オフセット   ;
}

buildLevel = function   {

createPlank  22、20、0.25、2 
... //さらに8぀のボヌドを描画する

createPig  20、11、0.5  ;
... //さらに2頭の豚
}

createPlank = function  x 、 y 、 width 、 height  {
bodyDef。 タむプ = b2Body。 b2_dynamicBody ;
fixDef。 shape = new b2PolygonShape ;
fixDef。 圢状 SetAsBox 
幅
、高さ
 ;

bodyDef。 ポゞション 。 x = x ;
bodyDef。 ポゞション 。 y = y ;
プランク=ワヌルド。 CreateBody  bodyDef  ;
板。 SetUserData  新しい PlankData    ;
板。 CreateFixture  fixDef  ;
}

createPig = function  x 、 y 、 r  {
... // createPlankメ゜ッドに䌌たメ゜ッドですが、CircleShapeずPigDataが䜿甚されたす。
}
}


Box2dでは、ゲヌムロゞックを盎接実装できる远加の「ナヌザヌ」むンタヌフェむスを任意の物理オブゞェクトにバむンドできたす。 そのため、PigDataずPlankDataずいう2぀のオブゞェクトを远加したした。これらはオブゞェクトのタむプを返したす。 これは、衝突凊理を扱うずきに少し埌で重芁になりたす。

BodyDef構造は、オブゞェクトの幟䜕孊的特性ずその䞀般的な動䜜を説明するこずを目的ずしおいたすFixtureDefはその物理的特性を説明したす。 BodyDefでは、静的たたは動的のいずれであるかを問わず、1぀たたは別のブロックの蚈算方法を瀺したす。 䞀般的に、Box2dには、ドキュメントに蚘茉されおいるように、3皮類のオブゞェクトがありたす-静的、぀たり 完党に静的なオブゞェクトDebugView内-緑のオブゞェクト、動的-完党に独立した動的オブゞェクト、および運動孊的-移動の原因ずなるオブゞェクト。 䟋ずしお、静的は道路であり、動的は車ず車茪のサスペンションであり、動的は車の゚ンゞンです。

ここで、オブゞェクトの幟䜕孊的圢状、その巊䞊隅の䜍眮、および寞法を瀺したす。 すべおはメヌトル単䜍ですああ、私のサむズずピクセルが䞀臎しない理由をどれだけ掚枬したしたか。

最埌に、新しいdrawLevelメ゜ッドを終了したす。このメ゜ッドは、ボヌドず豚ずずもにレベル党䜓を描画したす。

スリングショット


物語の最も興味深い郚分。 次に、豚に鳥を攟぀パチンコの任意のプロトタむプを䜜成しおみたしょう。

これにはマりスが必芁です。

ゲヌム= 関数   {
...
init = function   {
bindMouse   ;
...
}

bindMouse = function   {
$ ドキュメント 。 mousedown  function  e  {
isMouseDown = true ;
handleMouse  e  ;
$ ドキュメント 。 bind  "mousemove" 、 { } 、 handleMouse  ;
}  ;

$ ドキュメント 。 mouseup  function  e  {
isMouseDown = false ;
$ ドキュメント 。 unbind  "mousemove"  ;
}  ;
}

handleMouse = function  e  {
mouseX =  e。clientX - canvasPosition。left  / 30 ;
mouseY =  e。clientY-canvasPosition。top  / 30 ;
} ;

曎新= 関数   {
if  isMouseDown  {
if    body   {
mousePosition = { x  mouseX 、 y  mouseY } ;
createPig  mouseX 、 mouseY 、 0.40  ;
body = getBodyAtMouse   ;

md = new b2MouseJointDef   ;
md。 bodyA =ワヌルド。 GetGroundBody   ;
md。 bodyB = body ;
md。 タヌゲット Set  mousePosition。X 、 mousePosition。Y  ;
md。 collideConnected = true ;
md。 maxForce = 300.0 *本䜓。 GetMass   ;
mouseJoint = world。 CreateJoint  md  ;
䜓。 SetAwake  true  ;
}

䜓。 SetPosition  新しい b2Vec2  mouseX 、 mouseY   ;
}

if  mouseJoint &&  isMouseDown  {
mouseX = mousePosition。 x ;
mouseY = mousePosition。 y ;
if  getBodyAtMouse    {
䞖界。 DestroyJoint  mouseJoint  ;
mouseJoint = null ;
body = false ;
}
}
...
}
}


ここで䜕をしたしたか 1぀目は、もちろん、mousedownおよびmouseupマりスハンドラヌが小さなゲヌムに釘付けになっおいるこずです。 これで、プレむフィヌルドでマりスボタンをクリックするず、isMouseDownフラグが蚭定されたす。たた、マりスを移動するず、mouseXおよびmouseYに栌玍されおいる座暙が倉曎されたす。 2番目に達成したのは、マりスがクリックされたずきにオブゞェクトを動的に䜜成するこずでした。この郚分をupdateメ゜ッドに入れたした。 倧たかに蚀っお、私たちの囜では「ブタ」タむプのオブゞェクトであるにもかかわらず、そこになければ「鳥」をすぐに䜜成したす。

さらに興味深いのは、GetBodyAtMouseメ゜ッドを䜿甚しお、凊理のために鳥のオブゞェクト本䜓をすぐに取埗し、MouseJointを䜿甚しおそれを䞖界にアタッチするこずです。 ぀たり 鳥を発射するパチンコの茪ゎムを䜜成するのはMouseJointです。 同じ堎所で、柔軟なカップリングず最倧の力の䜜甚方向を瀺したす。

この䟋は、マりスボタンをクリックするず、特城的な青みを垯びた靭垯が䞭心に付いた新しい円が衚瀺されるこずを明確に瀺しおいたす。 マりスボタンを抌さないず、バンドルは円の䞭心たで䌞びたす。 しかし、あなたが絞るず...

抌されるずisMouseDownフラグが倉曎され、2番目の条件が機胜し始めたす。同じgetBobyAtMouseメ゜ッドを䜿甚しお、ボディがアタッチされた靭垯の䞭心を亀差したかどうかを刀断し、亀差した堎合は靭垯を削陀したす。 次に、身䜓、すなわち 私たちの鳥の豚は飛んでいないすべおの豚ぞの恐怖のために自由飛行に送られたす^ _ ^。

GetBodyAtMouseメ゜ッドに぀いお、さらに詳しく説明したいず思いたす。非垞に興味深いです。

関数 getBodyAtMouse   {
mousePVec = new b2Vec2  mouseX 、 mouseY  ;

var aabb = new b2AABB   ;
aabb。 lowerBound 。 セット  mouseX - 0.001 、 mouseY - 0.001  ;
aabb。 upperBound 。 蚭定  mouseX + 0.001 、 mouseY + 0.001  ;

selectedBody = null ;
䞖界。 QueryAABB  getBodyCallback 、 aabb  ;
selectedBodyを返し たす。
}

getBodyCallback = function  fix  {
if フィクスチャ。GetBody   。 GetType   = b2Body。b2_staticBody  {
if フィクスチャ。GetShape   。 TestPoint フィクスチャ。GetBody   。 GetTransform   、 mousePVec   {
selectedBody =フィクスチャ。 GetBody   ;
falseを 返し たす 。
}
}
trueを 返し たす 。
}


ここで最初に行うこずは、珟圚のマりス䜍眮で新しいベクトルを䜜成するこずです。 次に、マりスポむンタヌの䞋にあるBox2d座暙系の画面スペヌスの䞀郚を割り圓おる構造を䜜成し、getBodyCallbackを䜿甚しお、マりスの䞋の領域が䜕らかのボディず亀差するかどうかを刀断し、そうであれば、新しいselectedBodyを蚭定したす。 原則ずしお、すべおは単玔であり、重芁です。

豚


このパヌトの前に、原則ずしお、暙準的な䟋の抂芁ではすべおが単調に進みたした。 しかし、衝突を正しく凊理するには、正盎にマニュアルを掘り䞋げなければなりたせんでした。 今䜕をする必芁がありたすか ほんの少し-レベルにあるブタが確実に消えるようにしたす。 しかし、接觊からだけでなく、䞀定の努力での接觊から。 これを行うには、暙準のコンタクトハンドラを再定矩し、衝突䞭にブタが受信した合蚈むンパルスのカりントを远加する必芁がありたす。

ゲヌム= 関数   {
...
GameContactListener = function   { } ;
GameContactListener。 プロトタむプ = b2ContactListener。 プロトタむプ ;

GameContactListener。 プロトタむプ PostSolve = function  contact 、 impulse  {
if  contact。GetFixtureB   。 GetBody   。 GetUserData    {
var BangedBody =連絡先。 GetFixtureB   。 GetBody   ;
if  contact。GetFixtureB   。 GetBody   。 GetUserData   。 GetType   == PIG  {
var imp = 0 ;
for  aむンパルス。normalImpulses  {
imp = imp +むンパルス。 normalImpulses [ a ] ;
}

if  imp > 3  {
砎壊された プッシュ  BangedBody  ;
バンデッドボディ。 visible = false ;
BangedBody = null ;
}
}
}

var contactListener = new GameContactListener   ;
䞖界。 SetContactListener  contactListener  ;
曎新= 関数   {
...
destroyedBodies = Array   ;
...
侖界 ClearForces   ; //重芁
while  destroyedBodies。length > 0  {
䞖界。 DestroyBody  destroyedBodies。Shift    ;
}
}
}


ここで最初に行うこずは、暙準のContactListenerを再定矩するこずです。 これは、すべおの衝突を凊理するオブゞェクトです。 そこで、メ゜ッドを䜿甚しおUserDataをチェックし、実際におたふく颚邪をひいたこずを確認し、それをたたいた勢いに満足したら、それを戊堎から隠し、削陀するために配列に入れたす。

私は正盎に頭に灰を振りかけたす-必芁な努力の衝動を手で取る力がなくなったので、衝動の匷さをランダムに拟いたした。 最適なオプションを遞択したこずを願っおいたす。 ワヌルドの䜜成では、ワヌルドが静的な状態になるたで衝突も発生するため、この状態も重芁ですおそらく、レベルを䜜成するずきにFlash同様のテヌマの䞀郚のゲヌムで芳察したした、フロアスラブの簡単な痙攣ここでも、実際には、ブタがそのような衝突で消えないように-総むンパルスをチェックする必芁がありたす。

曎新メ゜ッドの最埌に、ClearForcesを呌び出した埌、配列を消化し、空飛ぶ効に容赊なくlessられたすべおの豚を削陀したす。 この堎所を重芁であるず意図的に匷調したした-物理孊の蚈算プロセスが進行するたで、単䞀のオブゞェクトを削陀するこずはできたせん。 これらはBox2dの条件です。 すべおのオブゞェクトが数孊から解攟された埌にのみ、それらを自由に削陀できたす。 それが、実際にシヌンが終わった埌にのみブタが砎裂した理由です。

たずめ


Fuf、ちょっずシヌトのように完成したした。 倧量のコヌドず゚ラヌの可胜性をおpoびしたす。

私が玄束したように-䞊蚘で説明したすべおが完党に実装されおいる䟋ぞのリンク。

さお、結果の䜜品のスクリヌンショット



実際、私たちには珟圚倚くの䞍正確さがありたす-あなたは䞖界のどこからでも任意の方向に鳥を発射するこずができたす、力は必芁以䞊のものです、豚の死埌埗点はありたせん、鳥が亀差点を過ぎお発射するこずができ、束から分離しないバグ鳥はたったく鳥ではなく、豚です それでも、最初のレむダヌは非垞に機胜するゲヌムメカニクスを䜿甚しお描画されたため、いく぀かの小さなこずを仕䞊げるこずは非垞に可胜です。

近い将来の蚈画から-カップリングをい぀砎壊する必芁があるかを決定するロゞックを倉曎したす。これで、鳥を円で走らせるこずができたす。 もちろん、レベル゚ディタヌを䜿甚する必芁がありたす。 しかし、これは次の蚘事のトピックです。

ご枅聎ありがずうございたした、か぀お建蚭的な批刀をしたす^ _ ^

䟿利なリスト


code.google.com/p/box2dweb-Box2dWeb、Javascript甚のBox2dASポヌト。
www.box2dflash.org/docs/2.1a/reference-アンチモンゎルAPIリファレンス。
docs.google.com/View?id=dfh3v794_41gtqs6wf4&pli=1-ロシア語でかなり完党なガむド。 VirtualMaestroず圌のブログ-flashnotes.ruに感謝したす。 Box2dには䟿利なこずがたくさんありたす。
www.emanueleferonato.com-特にBox2dおよびむンディヌ党般に関する非垞に圹立぀ブログ。
ant - karlov.ru-銖謀者のブログ、誰かが興味を持っおいるなら^ _ ^

Source: https://habr.com/ru/post/J127991/


All Articles