OrthographicCameraで2Dカメラ
今回はカメラの処理をやります。2Dです。
ビューポートが絡んでいるみたいなので実機でのどのように表示されているか確認をしたいところですが、 確認できていないので後ほど。
→20150810 add とくに問題なかった!
公式Wikiはここ↓だと思います。
https://github.com/libgdx/libgdx/wiki/Orthographic-camera
以下のソースも上のコードを改変したものです。
/** * 2Dカメラ処理のサンプル */ public class OrthographicCameraSampleListener extends ApplicationAdapter { private Stage stage = null; private OrthographicCamera cam; private float rotationSpeed; @Override public void create() { rotationSpeed = 0.5f; float w = Gdx.graphics.getWidth(); float h = Gdx.graphics.getHeight(); stage = new Stage(); Gdx.input.setInputProcessor(stage); cam = (OrthographicCamera) stage.getViewport().getCamera(); //stageが持っているカメラを使う cam.setToOrtho(false, w/2, h/2); Texture t2 = new Texture("./profile.gif"); Image image = new Image(t2); image.setPosition(0, 0); stage.addActor(image); } @Override public void render() { Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); //画面クリア handleInput(); stage.draw(); } private void handleInput() { if (Gdx.input.isKeyPressed( Input.Keys.A)) { cam.zoom += 0.02; } if (Gdx.input.isKeyPressed(Input.Keys.Q)) { cam.zoom -= 0.02; } if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) { cam.translate(-3, 0, 0); } if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { cam.translate(3, 0, 0); } if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) { cam.translate(0, -3, 0); } if (Gdx.input.isKeyPressed(Input.Keys.UP)) { cam.translate(0, 3, 0); } if (Gdx.input.isKeyPressed(Input.Keys.W)) { cam.rotate(-rotationSpeed, 0, 0, 1); } if (Gdx.input.isKeyPressed(Input.Keys.E)) { cam.rotate(rotationSpeed, 0, 0, 1); } } @Override public void resize(int width, int height) { cam.update(); } @Override public void dispose() { stage.dispose(); } }
以下、自分がつまずいた部分を書いておく。
OrthographicCameraを作るとき
2D用に使えるクラスはOrthographicCameraというクラスらしい。
このインスタンスを作るとき、
OrthographicCamera camera = new OrthographicCamera(w, h);
↑コンストラクタの引数でカメラのサイズを渡すと、カメラ座標の中心が原点のまま
OrthographicCamera camera = new OrthographicCamera(); camera.setToOrtho(false, w, h);
↑上のようにsetToOrthoメソッドにすると、左下が原点になってくれる。
Scene2dを使っていてカメラを使うとき
//... SpriteBatch batch = new SpriteBatch(); Sprite sprite = new Sprite(texture); //... batch.setProjectionMatrix(camera.combined); batch.begin(); sprite.draw(batch);
↑のようにSpriteBacth#setProjectionMatrixにカメラオブジェクトを渡してdrawする例はあるのだけど、
自分はScene2d*1を使って描画をしているので、
Stageのメンバがもっているカメラを使います。
Stageをnewするときに引数を指定しなければ、StageクラスでSpriteBatchとViewport(とカメラ)をnewしてくれてます。
cam = (OrthographicCamera) stage.getViewport().getCamera(); //stageが持っているカメラを使う
あと、Stage#drawの中で Sprite#draw(Batch)やCamera#update をやっているので、 Stage#drawをやっていればこれらのメソッドを呼ぶ必要はないみたいです。わかってなかったけどこういうのがあるので、seane2dは便利。
今のとこの理解だと、 描画をするのはSpriteを使うのが基本みたいで、StageのdrawはSpriteをラッピングして便利にしているクラスってこと、っていう認識。
こんなかんじ↓
上記の内容をもとに、今作ってるゲームに取り込んでみた。
画像なのでわかりにくいけど、プレイヤー(棒人間)が動くとプレイヤーも移動していますが、 描画の度にプレイヤーがカメラの中心になるようにカメラ座標を合わせているので、 背景が逆方向に動いているようなかんじになります。
今いるところから…(↑)
左に移動するとこんな見た目になります。(↓)
昔のポケモン(GBのとか)とかも主人公がずっと画面の中心にいたので、そういうかんじです。
*1:ここらへんのやつをいいたい。https://github.com/libgdx/libgdx/wiki/Scene2d