最も単純な物理エンジン

ゲームに興味がありますか? ゲームを作成したいが、どこから始めればいいのかわからない? それからここに。 この記事では、GameDev'eで旅を始めることができる最も単純な物理エンジンについて検討します。 そして、はい、最初からエンジンを書きます。



何回か、私の友人は私がゲーム/ゲームエンジンを書く方法に興味を持ちました。 このような質問と回答をもう一度した後、このトピックはとても興味深いので、記事を作成することにしました。



Javascriptがプログラミング言語として選択されたのは、 実験的な知人がIDEとコンパイラをダウンロードする能力を持っていなかったためです。 キャンバスに描きます。



問題の声明



平面上のいくつかのオブジェクトは、重力の基本的な力を使用して相互作用を実現する必要があります。

つまり 宇宙に星を引き付けるようなことをするために。



アルゴリズム



最初に、コンピューター物理学と実際の違いを理解する必要があります。 実際の物理学は継続的に機能します(いずれにしても、現時点ではその反対は証明できません)。 コンピューター物理学は、コンピューターのように、離散的に作用します。 継続的に計算することはできないため、計算を一定の間隔でステップに分割します(25ミリ秒の間隔が望ましい)。 各ステップの後にオブジェクトの座標が変化し、オブジェクトが画面に表示されます。



それでは、重力そのものに取りかかりましょう。



重力の法則(ニュートン重力)の状態:

F = G * m1 * m2 / R^2 (1)
      
      





ここで:

 F []-      G = 6.67*10^-11 [^3/( * ^2)]-   m1, m2 [] -  1  2  R [] -     
      
      







これは、新しい座標の決定にどのように役立ちますか? そして、ニュートンの第二法則を使用して、これらのオブジェクトにこの力を適用します。

 F = m * a (2)
      
      





ここで:

 F [] - ,     m [] -    a [/^2] -   
      
      







しばらくの間、(1)力はスカラーであり、(2)力はベクトルであることを忘れています。 2番目のケースでは、力と加速度をスカラーと見なします。



そのため、加速度に変化がありました。

 a = F / m (3)
      
      







速度と座標の変化は次のとおりです。

 a = v' → a = dv / dt → dv = a * dt v = s' → v = ds / dt → ds = v * dt v += dv Pos += ds
      
      







ここで:

 d -  () v -  s -  Pos - ,   
      
      







ベクトルからスカラーへ:

 ax = a * cos(α) ay = a * sin(α) dv.x = ax * dt dv.y = ay * dt vx += dv.x vy += dv.y ds.x = vx * dt ds.y = vy * dt Pos.x += ds.x Pos.y += ds.y
      
      





ここで:

 cos(α) = dx / R sin(α) = dy / R dx = Pos2.x - Pos.x dy = Pos2.y - Pos.y R^2 = dx^2 + dy^2
      
      







プロジェクトには他のタイプの力はまだないため、この形式では(1)を使用し、計算をわずかに単純化します。

 F = G * m * m2 / R^2 a = G * m2 / R^2
      
      







コード



起動したindex.htmlページをすぐに作成し、コードを接続します。

見れない
 <!DOCTYPE html> <html> <head> <title>Physics</title> <script type="text/javascript" src="script.js"></script> </head> <body></body> </html>
      
      









主な焦点は、 script.jsプログラムコードファイルです。 レンダリングのコードは十分にコメント化されており、トピックには関係ありません。

しばらく見て見て忘れて
 var canvas, context; var HEIGHT = window.innerHeight, WIDTH = window.innerWidth; document.addEventListener("DOMContentLoaded", main, true); function main(){ //           canvas = document.createElement('canvas'); canvas.height = HEIGHT; canvas.width = WIDTH; canvas.id = 'canvas'; canvas.style.position = 'absolute'; canvas.style.top = '0'; canvas.style.left = '0'; document.body.appendChild(canvas); context = canvas.getContext("2d"); /*******   *******/ } function Draw(){ //   context.fillStyle = "#000000"; context.fillRect(0, 0, WIDTH, HEIGHT); //   context.fillStyle = "#ffffff"; for(var i = 0; i < star.length; i++){ context.beginPath(); context.arc( star[i].x - star[i].r, star[i].y - star[i].r, star[i].r, 0, Math.PI * 2 ); context.closePath(); context.fill(); } }
      
      







今、 最良の部分 :物理学を計算するコード。



オブジェクトごとに、質量、座標、速度のみを保存します。 ああ、まだ半径が必要です-衝突を計算するために半径が必要ですが、それについては次の記事で詳しく説明します。



したがって、オブジェクトの「クラス」は次のようになります。

 function Star(){ this.x = 0; this.y = 0; this.vx = 0; this.vy = 0; this.r = 2; // Radius this.m = 1; }
      
      





 var star = new Array(); //        var count = 50; //    var G = 1; //    
      
      





最初のランダムオブジェクト生成:

 var aStar; for(var i = 0; i < count; i++){ aStar = new Star(); aStar.x = Math.random() * WIDTH; aStar.y = Math.random() * HEIGHT; star.push(aStar); }
      
      







ステップは、次の関数で計算されます。

 function Step(){ var a, ax, ay, dx, dy, r; //       for(var i = 0; i < star.length; i++) //   for(var j = 0; j < star.length; j++) //   { if(i == j) continue; dx = star[j].x - star[i].x; dy = star[j].y - star[i].y; r = dx * dx + dy * dy;//  R^2 if(r < 0.1) r = 0.1; //       a = G * star[j].m / r; r = Math.sqrt(r); //  R ax = a * dx / r; // a * cos ay = a * dy / r; // a * sin star[i].vx += ax * dt; star[i].vy += ay * dt; } //   ,        for(var i = 0; i < star.length; i++){ star[i].x += star[i].vx * dt; star[i].y += star[i].vy * dt; } //    Draw(); }
      
      







さて、待望のタイマーが始まります:

 var dt = 0.02; //   timer = setInterval(Step, dt * 1000);
      
      







ここで作品を見ることができ、 ここでコードを見ることができます



オブジェクトが互いに飛び交うことに気付くかもしれません。 衝突処理はまだ十分ではなく、物理的な観点から見ると、すべてのオブジェクトは重要なポイントです。 次の記事では、衝突処理について検討します。



短所



アルゴリズムの複雑さは指数関数的に増大するため、オブジェクトの増加はFPSの顕著な沈下を伴います。 クワッドツリーまたは他のアルゴリズムを使用したソリューションは役に立ちませんが、実際のゲームでは、オブジェクトはそれぞれの原則に従って相互作用しません。



テストは、2.4 GHzの周波数のIntel Pentiumプロセッサを搭載したマシンで実行されました。 計算間隔が1000のオブジェクトでは、すでに20ミリ秒を超えています。



使用する



(3)の異なる力の重ね合わせを力として使用できます。 たとえば、エンジンの牽引力、土の強さおよび空気抵抗、ならびに他のオブジェクトとの衝突。 アルゴリズムは3次元に簡単に拡張でき、 xおよびyと同様にzを入力するだけです。



このアルゴリズムはPascalのGrade 9で書き戻しましたが、これまでは、個人的なHello Worldとしてできるという理由だけで、私が知っているすべての言語に転送されてきました。 ターミナルでも。



また、このアルゴリズムは、電磁(G→k、m→q)という別の基本的な相互作用にも使用できます。 このアルゴリズムを使用して、充電システムの磁気誘導線を作成しましたが、それについては別の記事で詳しく説明します。



読んでくれてありがとう。 この記事があなた自身のゲームの作成に少し役立つことを願っています。

このよう渦巻銀河については、おおよその経過をたどっています。



All Articles