2016-11-21 14 views
2

私はむしろlibgdxの開発者ですが、私はしばらく問題を抱えていますので、ここで質問しました。ビューポートを使用したlibgdxカメラの位置

私はFillViewport、TiledMap、Scene2d、OrtographicCameraを使用します。私はカメラが私のプレーヤーのインスタンスに従うことを望みますが、境界が定義されています(マップ・サイズに等しい)。それは、カメラが決して地図の外に出ることは決してないので、プレーヤーが地図の終わりに来ると、カメラは追従しなくなり、画面自体の端に行きます。たぶん、複雑に聞こえるかもしれませんが、シンプルで、私はあなたが私の言いたいことを知っていると確信しています、それはあらゆるゲームで使われています。

I 4つの値計算:

camera.position.set(Math.min(maxCameraX, Math.max(posX, minCameraX)), Math.min(maxCameraY, Math.max(posY, minCameraY)), 0); 

(POSX、POSY:Iは、単位変換、camera.zoom等のような必要なものは、その後、私は、このようなカメラの位置を設定しないで除去

minCameraX = camera.viewportWidth/2; 
minCameraY = camera.viewportHeight/2; 
maxCameraX = mapSize.x camera.viewportWidth/2; 
maxCameraY = mapSize.y - camera.viewportHeight/2; 

を基本的にプレイヤーの位置にカメラを設定していますが、それが高くても小さすぎても、前に定義された最大値または最小値に設定されます。 (私もMathUtils.clamp()を試して同じことをします。

これまでのところすべてが完璧です。縦横比が変わると問題が発生します。デフォルトでは1280x768を使用していますが、私の電話は1280x720です。

最大値と最小値を変更し、比の差を計算して計算に加え、カメラのサイズを変更しようとしましたが、FillViewportの動作が原因で画面が切れてしまいました。 、さまざまなビューポート、その他のものがありますが、成功しません。

ありがとうございます。 ありがとう

+0

正確にはどのような問題がありますか?あなたのカメラは、もはや動作しないメカニズムに縛られていますか、または画面の一部が途切れてしまうという問題ですか? – noone

+0

第2のもの。上端と下端が切り取られているので、たとえば地図の終了フレームは表示されません。もちろん、私はそれがFillViewportの仕組みだと知っていますが、カメラの境界を修正して修正するのは可能でしょう –

+0

この場合にはうまくいかないのですが、 'getTopGutterHeight()'と 'getBottomGutterHeight() ) 'をminCameraYとmaxCameraYに追加してください(または、別の方法で、addの代わりにsubstractしてください) – noone

答えて

0

私は上記のコメントからnooneとTenfour04のソリューションを試しました。どちらも、完璧ではないですが、私は私が推測するに十分なsatisified午前:

誰も:

camera.position.x = MathUtils.clamp(camera.position.x, screenWidth/2 + leftGutter, UnitConverter.toBox2dUnits(mapSize.x) - screenWidth/2 + rightGutter); 
camera.position.y = MathUtils.clamp(camera.position.y, screenHeight/2 + bottomGutter, UnitConverter.toBox2dUnits(mapSize.y) - screenHeight/2 - topGutter); 

は、それが唯一の解像度の小さなスペクトルのためしかし、働いていました。アスペクト比がデフォルトのものと大きく異なる奇妙な解像度については、境界線の後に白い縞模様が見えました。それは国境全体がプリンターであり、国境の外の世界の一部であったことを意味します。私は理由を知らない

Tenfour04: ビューポートをExtendViewportに変更しました。何も断ち切られませんが、異なるアスペクト比で私は国境の外の世界を見ることができます。

両方の解決策は、境界線と同じ色の画面をクリアすることと、どちらの場合でも満足のいく効果を与えたレベルの背景をクリアすることです。

いくつかの制限があります。ボーダーは世界の一部(タイルブロック)であるため、同じ色の場合は問題ありません。ボーダーが異なる色を持つ場合、ボーダーの外に1つのカラーをレンダリングすることは解決策にはなりません。

おかげで誰もとTenfour04と私はまだ提案を開いています:)

ここではいくつかのスクリーンショットです:あなたの代わりにFullViewportのFitViewportを使用していないのはなぜ https://www.dropbox.com/sh/00h947wkzo73zxa/AAADHehAF4WI8aJ8bu4YzB9Va?dl=0

+0

世界が少なくとも画面と同じくらい大きければ、私はあなたがあなたの質問に示したカメラのクランプを使用していると仮定して、どのように国境を越えて見ることになるかわかりません。私がしているのは、4:3の解像度の仮想幅と高さを使用して、世界が少なくとも16:9のバージョンをカバーするのに十分であることを確認することです。たとえば、仮想サイズが400x300の場合、空白が見えないように、世界は少なくとも534ワイドにする必要があります。余分な風景タイルを追加して、これを小さな段階で確実に行うことができます。 – Tenfour04

+0

問題を視覚化するためのスクリーンショットをいくつか追加しました –

0

?そうすれば、それはあなたの画面を断つことはありませんよね?

+0

と醜い白い縞 –

0

少し遅れていますが、妥協のない解決策があります。

ここで、幅と高さはワールドサイズ(ピクセル単位)です。私はFillViewportでこのコードを使用し、すべて優れています!

float playerX = player.getBody().getPosition().x*PPM; 
float playerY = player.getBody().getPosition().y*PPM; 

float visibleW = viewport.getWorldWidth()/2 + (float)viewport.getScreenX()/(float)viewport.getScreenWidth()*viewport.getWorldWidth();//half of world visible 
float visibleH = viewport.getWorldHeight()/2 + (float)viewport.getScreenY()/(float)viewport.getScreenHeight()*viewport.getWorldHeight(); 

float cameraPosx=0; 
float cameraPosy=0; 

if(playerX<visibleW){ 
    cameraPosx = visibleW; 
} 
else if(playerX>width-visibleW){ 
    cameraPosx = width-visibleW; 
} 
else{ 
    cameraPosx = playerX; 
} 

if(playerY<visibleH){ 
    cameraPosy = visibleH; 
} 
else if(playerY>height-visibleH){ 
    cameraPosy = height-visibleH; 
} 
else{ 
    cameraPosy = playerY; 
} 

camera.position.set(cameraPosx,cameraPosy,0); 

camera.update(); 
関連する問題