「ゲームの世界」全体がビューポートよりも何千倍も広い場合は、scene2dを使用してゲームオブジェクトをActor
sとして管理したい場合は、現在のビューポートの周りの一部の領域であるべきですが、全世界ではありませんか?Stage
つまり、小さいビューポートサイズの部分にのみオブジェクトをレンダリングしたとしても、幅と高さが大きいStage
はメモリ自体を消費しますか?巨大な世界を持つゲームでscene2dのステージを適切に使用する
答えて
正確にはStage
であると誤解していると思います。ステージは実際にはサイズ自体を持っていません。幅または高さ、またはStage
を指定しない場合は、ビューポートの幅と高さのみを指定します。ビューポートは、あなたの世界の一部、つまり別のシーンのみを表示するウィンドウのようなものです。 Stage
は2Dシーングラフで、Actors
で「成長」します。あなたが持っている俳優の数が多いほど、あなたの舞台は大きくなりますが、実際の俳優の広がりの程度には依存しません。彼らが非常に遠くに広がっていて、Stage
全体のごく一部しか表示していない場合、シーングラフはこの巨大な領域を細分するので、特定のActorを無視するかどうかを非常に迅速に決定できるため、またはスクリーン上に描画します。
つまり、Stage
は実際にこのような状況に必要なものであり、おそらくFPSやメモリの問題はないはずです。 Stage
があなたのビューポートのサイズの1000倍であり、すぐに特定のアクタが表示されないことがわかっている場合は、それらをまだステージに追加しないと意味があります。
ステージは、すべてのアクタを保持するルートノードにすぎません。それは、子どものためにメソッドを呼び出すことです(描画や動作など)。アクターの数と複雑さだけがメモリとフレームレートに影響します。
あなたの状況には、間抜けの方法が必要です。最も簡単なのは、アクタがビューポート内にあるかどうかをチェックし、アクタがスキップしていないかどうかをチェックすることです。カスタム俳優を作成し、このコードを追加:source
public void draw (SpriteBatch batch, float parentAlpha) {
// if this actor is not within the view of the camera we don't draw it.
if (isCulled()) return;
// otherwise we draw via the super class method
super.draw(batch, parentAlpha);
}
Rectangle actorRect = new Rectangle();
Rectangle camRect = new Rectangle();
boolean visible;
private boolean isCulled() {
// we start by setting the stage coordinates to this
// actors coordinates which are relative to its parent
// Group.
float stageX = getX();
float stageY = getY();
// now we go up the hierarchy and add all the parents'
// coordinates to this actors coordinates. Note that
// this assumes that neither this actor nor any of its
// parents are rotated or scaled!
Actor parent = this.getParent();
while (parent != null) {
stageX += parent.getX();
stageY += parent.getY();
parent = parent.getParent();
}
// now we check if the rectangle of this actor in screen
// coordinates is in the rectangle spanned by the camera's
// view. This assumes that the camera has no zoom and is
// not rotated!
actorRect.set(stageX, stageY, getWidth(), getHeight());
camRect.set(camera.position.x - camera.viewportWidth/2.0f,
camera.position.y - camera.viewportHeight/2.0f,
camera.viewportWidth, camera.viewportHeight);
visible = (camRect.overlaps(actorRect));
return !visible;
}
あなたも、さらにパフォーマンスを向上させるために必要がある場合は、手動で表示してものではありません(例:カメラを動かすこと)であるものを決定するために切り替えることができます。すべてのそれらのカリング計算がすべてのアクターのために、毎フレームで実行されるので、これはより速くなります。描画する代わりに数学を行う方がはるかに高速ですが、膨大な数の俳優が莫大な量の不要な呼び出しを与えるでしょう。