JavaScriptでの小惑星の実装

30行に向かう傾向をどうにかして薄めるために、私はかなり完全で、30行と比較して、古典的な小惑星ゲームの体積実装を書くことにしました。

スクリーンショット

コードの行数または文字数では測定されません。 かなり普通のデザインで、コメントさえあります。

ゲームの世界はキャンバスに描かれ、世界のすべてのオブジェクトは統合され、衝突検出器はピクセルごとのテストを使用します。 単純な声の演技、人生、出現後の最初の数秒でのゴッドモッド、眼鏡、眼鏡の複雑化、そしてもちろん、小惑星の断片への崩壊があります。

ここで試してみることができます 。 Chromeまたは少なくともFFを強くお勧めします。





ロジックの量を減らすために、世界のすべてのオブジェクトをユニバーサルにし、特定のタイプに応じて最小限の分離を行います。 オブジェクトのジオメトリは、glBegin(GL_LINES)を使用して行うのと同じように、頂点リストに格納されます。 ロジックを同じように統一するために、2つのジオメトリが船に割り当てられます(通常の場合と加速中に炎が発生する場合)。 コードを破ると、船の形をした小惑星や弾丸などを作ることができます。 ジオメトリのすべてのポイントは座標[-1..1]で設定され、特定のサイズはキャンバスのレンダリングレベルでスケーリングすることで取得されます。 また、小惑星のサイズに関係なく、任意のジオメトリを適用できます(小惑星のいくつかのオプション)。



各オブジェクトには特性のグループがあります。



統一により、オブジェクトが画面を離れるときにラップするなど、特別な状況の処理が大幅に簡素化されました。

両軸のすべてのラッピングロジック
S-オブジェクトデータ、W-ワールドデータ
[{x:'x', W:Ww}, {x:'y', W:Wh}].forEach(function(_) { var limit = (_.W>>1)+Sr, diff = _.W+2*Sr; if (S[_.x] < -limit) {S[_.x] += diff} else if (S[_.x] > limit) {S[_.x] -= diff} });
      
      



コードは短縮できます。 しかし、私見はあまり明確になりません。


最初のバージョンの1つで、オブジェクトを2つの部分に分けて表示するオプションを試してみました。部分的にアプローチして(一種のポータル) それは面白そうに見えたが、それは完全に標準的ではないように思えた。 たぶんそれは戻る価値がありますか?



タイプによる区別は、衝突処理のロジックでのみ実行され、それが直面しているものを理解します。 船内の小惑星と弾丸の衝突が考慮されるようになりました。 小惑星同士の衝突についての考えがあり、もちろん、UFOのゲームの紹介もあります。



画像 シェル上の衝突の最初のバリアント(丸で囲まれた円を通るバウンディングボックス)は、右の図のように衝突が機能した場合に矛盾を示しました。 「ドライブ」全体を奪ったため、これは受け入れられませんでした。 彼は2つの解決策を思いつきました:ジオメトリの交差の数学的計算(オブジェクトは閉じたセグメントのセットのように見えます)とブラウザエンジンがレンダリングする通りのピクセルごとのテストです。 理論的には、最初のオプションはリソースをあまり消費しませんが、2番目のオプションを選択しました。

2番目のキャンバスが作成され、その上で(シェルテストで交差の可能性が確認された場合のみ)2つのオブジェクトがチェックされますが、50%のアクティブブレンドを備えた赤と緑の配色です。 その結果、実際の交差点の場所に、赤と緑の両方の成分を持つピクセルができます。 非常に簡単ですが、効果的ではありません。

2番目のキャンバステストは次のようになります
画像

スクリーンショットは、レンダリングとスクリーンショットの同期がとれていないため、少し曲がっています




さて、最終的には多少なりとも「肉」:

画像

小惑星はワイヤーフレームで出力されていることがわかります。 繰り返しますが、少し標準化するためです。



All Articles