↑の状態、
プレイヤーの歩く動きに合わせてカメラが移動しているように見えるが、
カメラがマス単位(このゲームだと32dot)移動→そのあとにプレイヤーがドット単位で移動 という風になってしまっています。(カメラの動きがかくかくしてるかんじする。)
今回はこれを改善します。
関連記事
http://snoopopo.hatenablog.com/entry/2015/07/26/145013
http://snoopopo.hatenablog.com/entry/2015/07/16/170043
今回は、上記の内容で出来てなかった、アクション実行時もカメラをプレイヤーに合わせることです。
プレイヤーの動きに合わせてカメラを移動させる
移動と攻撃はどちらも、scene2dのActionクラスを使って移動させています。
/** * アクションの動きごと追跡するカメラ */ public class TrackActionCameraSampleListener extends ApplicationAdapter { private Stage stage = null; private OrthographicCamera cam; private int cnt = 1; private boolean preEnter = false; private boolean preDown = false; private Array<Image> imagelist = null; private Image player = null; private float startPositionWidth; private float startPositionHeight; @Override public void create() { stage = new Stage(); Gdx.input.setInputProcessor(stage); float w = Gdx.graphics.getWidth(); float h = Gdx.graphics.getHeight(); cam = (OrthographicCamera) stage.getViewport().getCamera(); cam.setToOrtho(false, w/2, h/2); //カメラのサイズを画面サイズの半分にしてる imagelist = new Array<>(); Texture p = new Texture("player_x0_y0.png"); player = new Image(p); imagelist.add(player); //ひとつ目 imagelist.add(new Image(new Texture("player_x1_y0.png"))); //2つ目 imagelist.add(new Image(new Texture("player_x2_y0.png"))); //3つ目 startPositionWidth = cam.viewportWidth/2 - p.getWidth()/2; startPositionHeight = cam.viewportHeight - p.getHeight(); for (Image image : imagelist) { image.setPosition(startPositionWidth, startPositionHeight); stage.addActor(image); } //移動したのがわかりにくいので、適当に表示 Texture c = new Texture("enemy2_x0_y0.png"); Image cat1 = new Image(c); cat1.setPosition(startPositionWidth + c.getWidth(), startPositionHeight); stage.addActor(cat1); Texture c2 = new Texture("enemy2_x0_y1.png"); Image cat2 = new Image(c2); cat2.setPosition(startPositionWidth - c2.getWidth(), startPositionHeight - 120); stage.addActor(cat2); Texture c3 = new Texture("enemy2_x0_y2.png"); Image cat3 = new Image(c3); cat3.setPosition(startPositionWidth + c3.getWidth(), startPositionHeight - 180); stage.addActor(cat3); } @Override public void render() { Gdx.gl.glClearColor(0, 1, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); //画面クリア stage.act(Gdx.graphics.getDeltaTime()); //よばないとアクションが実行されなかった if (!preDown && Gdx.input.isKeyPressed(Keys.DOWN)) { for (Image image : imagelist) { image.addAction(Actions.moveBy(0, -100, 2)); //2秒間で100px前に前進 } } if (!preEnter && Gdx.input.isKeyPressed(Keys.ENTER)) { for (Image image : imagelist) { SequenceAction seqAct = Actions.sequence(); seqAct.addAction(Actions.moveBy( 0, player.getHeight() /2 * -1, 0.2F )); seqAct.addAction(Actions.moveBy( 0, player.getHeight() /2, 0.2F )); image.addAction(Actions.repeat(2, seqAct)); //攻撃っぽい動き } } preDown = Gdx.input.isKeyPressed(Keys.DOWN); preEnter = Gdx.input.isKeyPressed(Keys.ENTER); for (Image image : imagelist) { image.setVisible(false); //いったん全部を非表示にして } //今のフレームで表示させる画像だけ表示する int rest = cnt % 10; if (rest <= 2) { imagelist.get(0).setVisible(true); } else if (rest <= 6) { imagelist.get(1).setVisible(true); } else { imagelist.get(2).setVisible(true); } cnt++; //カメラの中心をプレイヤーに合わせる cam.position.x = player.getX(); cam.position.y = player.getY(); stage.draw(); } @Override public void resize(int width, int height) { cam.update(); } @Override public void dispose() { stage.dispose(); } }
カメラのポジションにプレイヤーの位置をそのまま設定してあげればよい
カメラのポジションにプレイヤーの位置をそのまま設定してあげればよいだけでした。
//カメラの中心をプレイヤーに合わせる
cam.position.x = player.getX();
cam.position.y = player.getY();
アクションが実行された際に、Actor#getX, Actor#getY でとれる値がちゃんと変わってくれてるわかるので、 この値を直接指定してあげればいきます。
というわけで
上記の内容を作っているゲームに反映させるとこのようになります。
歩行はよさそうですが、攻撃のときもカメラが動いているのでせわしない気もします。(SFC風來のシレンでは、攻撃時にはカメラが動いてないように見える)
歩行のときだけカメラを動かすとか、そのあたりの調整は必要なかんじ。