物理学を使用した最初のブラウザベースの2Dゲームを作成します

暖かい夏の夜、私は多くの人を訪問するという考えに立ち会いました。自分のゲームを作りたいです! エネルギーは限界を超えていたので、仕事はきらめきとともに進みました。



レーシングゲーム



その結果、物理を備えた小さなプロトタイプブラウザ2Dプラットフォームが完成しました。

カットの下-そのようなゲームを作成するための初心者から初心者のためのガイド。 あなたが経験豊富なイグロデルなら、貴重なヒントを共有してください!



プロジェクトツール



古典的なJavaScript-簡単にするために、言語の最も基本的な構文を使用しようとしました。 また、プロジェクトにはコレクタがありません。各ファイルはそのまま接続されます。 このおかげで、プロジェクトが幅広い開発者に理解できることを願っています。



PixiJS-この2Dグラフィックエンジンが気に入った。 彼の作品に関するコメントはありませんでした。 プラス-優れたドキュメント。



PhysicsJS-プロジェクトの理由の1つは、ビジネスで既製の物理エンジンを試してみたいという願望でした。 選択はPhysicsJSにかかった。 開発プロセスでは、ドキュメントが不足している場合があり、そのソースを開く必要がありました。 しかし、彼は仕事を完了し、身体の物理学は非常に現実的に見えます。



JQuery-ライブラリの機能は最小限で使用され、必要に応じて安全に削除できます。 しかし、私は個人的にjQueryが好きで、それを使用してHTMLを操作することを楽しんでいます。



アプリケーションアーキテクチャ



1秒あたり最大60回、ブラウザーは画面再描画メソッドを呼び出します。



コード
//render.RootStage function animate() { requestAnimationFrame(animate); //... }
      
      





再描画のたびに物理モデルが更新され、マップ、ゲームマシン、賞の星などのゲームのレイヤーが順次描画されます。



コード
 //render.RootStage function animate() { requestAnimationFrame(animate); //  game.step(); //  for (var i=0; i< stages.length; i++) stages[i].update(); }
      
      





ユーザーが画面の再配布の間にコントロールボタンを押すと、モデルはこれに関する情報を受け取ります。この情報は、次回の再描画時に考慮されます。



コード
 //render.RootStage $("#moveRight").mousedown(function(){ game.car().startAccelerator(); }); $("#moveRight").mouseup(function(){ game.car().stopAccelerator(); });
      
      





このプロセスを図として描くことができます:



ゲームプロセス



1.モデルを更新します。

2. PhysicsJSを呼び出して、物理を計算します。

3.再描画のためのレイヤーの連続呼び出し。

4.更新されたモデルをポーリングし、PixiJSを使用して再描画します。



実装機能



衝突 -物理エンジンは、便利な衝突検出APIを提供します。 自分で数学を覚える必要はありません。



コード
 //physics.Game var world = Physics({...}); world.add([ Physics.behavior('body-collision-detection'), ... ]); world.on('collisions:detected', function(data){ for (var i = 0; i < data.collisions.length; i++) onCollision(data.collisions[i]); });
      
      





しかし、時には衝突は必要ありません...-例えば、あなたが賞の星を集めるとき。 衝突の事実を記録するが、他のオブジェクト(ゴーストオブジェクト)とは相互作用しないオブジェクトの種類を物理エンジンに含めるのは論理的に思えます。 残念ながら、PhysicsJSにはそのような可能性はありませんでした。 その結果、衝突後に賞品の星を削除しても、エンジンはすでにプレーヤーの速度を変更し、速度を落としています。









より美しい解決策があると確信していますが、私はこの方法でそれを行いました:衝突の事実の後、PhysicsJSがあなたをそのように欺くことができるので、衝突前にプレーヤーを彼の特性に戻します。



コード
 //model.car.Car function onCollision(otherBody, pos, norm){ if(otherBody.objType == model.ObjectType.POINT) carBody.backPrevForce(); } //physics.BodyPhysicsImpl function backPrevForce(){ var old = body.state.old; body.state.acc.set(old.acc.x, old.acc.y); body.state.vel.set(old.vel.x, old.vel.y); body.state.angular.vel = old.angular.vel; body.state.angular.acc = old.angular.acc; }
      
      





結果-星を集めても、プレイヤーの速度に違反しません。









エンジンのさまざまなモデル -物理エンジンはオブジェクトをその重心の周りで回転させ、デフォルトのグラフィックエンジンはオブジェクトの左上隅を中心に回転します。 この事実を考慮しない場合、結果は非常に面白いものになります。









ちなみに、AndroidのUberクライアントでの車の回転のアニメーションには似たようなものがあります。車の中心ではなく、左上隅にも分岐点があります。 これはバグなので、修正するのが面倒です。



Uberのようなアニメーションの例






解決策は、左上隅ではなく、中心に対して車を描くことです。



コード
 //render.car.PlayerCar function paintCabin(g, model){ //... g.drawRect(model.x - model.w/2, model.y - model.h/2, model.w, model.h); //... }
      
      





今、すべてが正しく見えます









モバイルデバイスでのコントロールボタンの表示 -進行方向を避けて、モバイルデバイス用の大きなコントロールボタンを表示します。 主なことは、ボタンのクランプがタッチイベントによって行われることと、cssスタイルを介したこの長押しによるテキスト選択の表示を禁止する必要があることを忘れないことです。



コード
 //render.RootStage $("#moveRight").on('touchstart', function(){ game.car().startAccelerator(); }); $("#moveRight").on('touchend', function(){ game.car().stopAccelerator(); }); //main.css .moveBtn { -webkit-user-select: none; -moz-user-select: none; }
      
      











ゲームの携帯電話のバッテリー消費が大幅に増加します。 プロセッサに作業を積極的にロードする物理エンジンが原因だと思います。



結論



一般的に、ゲームを作成するプロセスは私にはそれほど複雑ではないと思われました。 グラフィックスと物理学用の既製のエンジンを使用すると、数学をほとんど考慮することなく、開発を大幅に簡素化できます。 このアプローチがどれほど効果的かは、別の記事の質問です。 ご清聴ありがとうございました。長い間これを行うことを計画していたなら、私の成果があなた自身の何かを作成するのに役立つことを願っています! 頑張って



[GitHubのソース]




All Articles