2022年3月14日月曜日

プロジェクトヴァルハラが以下の問題に取り組んではいます。

 

 · 

フォロー
Paul Pacheco

はい。

ゲーム開発に携わりたいならC++かC#に乗り換えるべきです。Javaはゲーム開発に適していません。なぜなら、Javaにはカスタム可能な値型がまだないからです。

ゲームの中の3Dキャラクターや動物を考えてみましょう。どのように表現されていると思いますか? ビデオカードに送るデータはどうなっているでしょうか? それはポリゴンメッシュで、こんな感じで数千個の三角形により構成されています。

各三角形には3つの頂点があり、各頂点は複数の三角形が共有します。ビデオカードは様々な形式のメッシュに対応していますが、一般的には次のような構造しています。

  1. class Mesh { 
  2. Vector3d vertices[]; 
  3. Color32 colors[]; 
  4. Vector3d normals[]; 
  5. Vector3d tangents[];  
  6. Triangle triangles[]; 
  7. }  

頂点データには巨大な3Dベクトル配列があります。各頂点には色、法線、接線のデータがあり、同じ大きさの配列が3つあります。次に3角形のリストがあります。三角形は前の配列にある3つの頂点情報の単なるインデックスでできています。

キャラクター、動物、モンスター、ビル、木、岩など、それぞれ1つ1つにメッシュを作ります。

C++やC#の場合、Vector3d、Color32、Triangleなどは値型ですので、配列は連続したメモリブロックになります。Vector3dが12バイトで、5000頂点ある場合、頂点の配列は60,000バイトの大きなブロックになるでしょう。

Javaには値型がありませんので、Vector3d、Color32、Triangleはクラス(参照型)にするしかありません。つまりそれぞれの頂点、色、法線はヒープのどこかにバラバラに確保されることになります。5つの配列はポインタの配列でしかなく、実際のデータはヒープ上に点在しています。これではビデオカードが読めません。

これをJavaでやる唯一の現実的な方法は、浮動小数点数の配列を使い、各頂点のxyz座標のインデックスを手動で操作することです。これは本当に大変です。

値型がないと、全てのオブジェクトは動的に確保され、ガベージコレクタが管理しないといけません。ゲームはリアルタイムなアプリケーションですから、Javaが実行を中断し、ガベージコレクタが動作するタイミングが狂うと、ゲームがリアルタイム更新するタイミングまでに間に合わず、フレーム飛びが発生するかもしれません。ユーザーにはこれがカクツキに見えます。

もしJavaに値型が導入されたら、ゲームエンジンに採用されるかもしれず、あなたは人より先に使いこなすかもしれません。それまでは、Javaはゲーム業界ではマイナーな存在でしょう。


Jon Rさんのコメント

マインクラフトを除く。

Paul Pachecoさんの返信

確かにマインクラフトはJavaで書かれてますが、Javaで書かれたメジャーなゲームは他にないでしょう。マインクラフトのコードを見たことはありませんが、Javaの制限を回避するためにスパゲティなコードになっていると思います。

0 コメント:

コメントを投稿