スマフォな入力処理
今までキーボードで動かしていたけど、一応スマフォで動くゲームを目指すので入力をそれっぽくしていってます。
https://github.com/libgdx/libgdx/wiki/Mouse%2C-touch-%26-keyboard
↑ここにある通り、PollingとEvent Handlingを使った場合をやります。
以前にやったClickLisnerがなぜここに入らない??っていうのがよくわからん。TODO
関連記事
http://snoopopo.hatenablog.com/entry/2015/08/04/030836
この記事の一番最後の「タッチで上下左右移動」は↑のサンプルを改変したやつ
Pollingを使った場合
https://github.com/libgdx/libgdx/wiki/Polling
/** * androidで動かすときに使えそうな入力処理関係 * pollingをつかった場合 */ public class InputSampleListener extends ApplicationAdapter { @Override public void render() { Gdx.gl.glClearColor( 1, 0, 0, 1 ); Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT ); //画面クリア if (Gdx.input.isTouched()) { //押されたとき touchdown System.out.println("isTouched"); } if (Gdx.input.justTouched()) { //押されて指を離したとき touchdown -> touchUp 長押ししている場合は呼ばれてない System.out.println("justTouched"); } if (Gdx.input.isTouched(0) && Gdx.input.isTouched(1)) { //マルチタップ System.out.println("isTouched multi"); } //画面の左上が(0,0)になっている。 System.out.println("input x pointer :" + Gdx.input.getX() + " : y pointer :" + Gdx.input.getY() ); } }
左上が原点になっている!!注意!
//画面の左上が(0,0)になっている。 System.out.println("input x pointer :" + Gdx.input.getX() + " : y pointer :" + Gdx.input.getY() );
Pollingを使った場合 スワイプ(ドラッグ)っぽい動き
/** * androidで動かすときに使いそうな入力処理関係 * スワイプしているときに画像が指にくっついてくるサンプル */ public class InputSwipeSampleListener extends ApplicationAdapter { private Stage stage = null; private Image image = null; @Override public void create() { stage = new Stage(); Gdx.input.setInputProcessor(stage); image = new Image(new Texture("./profile.gif")); stage.addActor(image); } @Override public void render() { Gdx.gl.glClearColor( 1, 0, 0, 1 ); Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT ); //画面クリア if (Gdx.input.isTouched()) { //押されたとき touchdown System.out.println( "isTouched" ); image.setPosition( Gdx.input.getX() - image.getWidth() / 2, Gdx.graphics.getHeight() - Gdx.input.getY() - image.getHeight() / 2 ); } stage.draw(); } @Override public void dispose() { stage.dispose(); } }
InputHandleを使った場合
https://github.com/libgdx/libgdx/wiki/Event-handling
/** * androidで動かすときに使いそうな入力処理関係 * InputProcessorを使った場合 */ class InputProcessorSampleListener extends ApplicationAdapter { @Override public void create() { //無名クラスで作成 Gdx.input.setInputProcessor( new InputAdapter (){ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { //これも左上が0,0になってる System.out.println("touchDown " + screenX + ":" + screenY); return true; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { System.out.println("touchUp " + screenX + ":" + screenY); return true; } @Override public boolean touchDragged(int screenX, int screenY, int pointer) { System.out.println("touchDragged " + screenX + ":" + screenY); return true; } }); } @Override public void render() { Gdx.gl.glClearColor( 1, 0, 0, 1 ); Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT ); //画面クリア } }
こちらも原点が左上だということがわかります。
Wikiにある通り、
Gdx.input.setInputProcessor(inputProcessor)
InputProccessorはsetしなくてはいけないです。↑↑
今まで、よく↓みたいにStageのインスタンスを渡していたけど、これはStageがInputProcessorの実装クラスだからでした。
Gdx.input.setInputProcessor(stage)
InputHandleを使った場合 タッチで上下左右移動
画面のどこタッチしてもOKな上下左右移動です!これはゲームに使う動きの想定(▽)ぱあ
/** * タッチで上下左右移動 */ public class InputProcessor2SampleListener extends ApplicationAdapter { private Stage stage = null; private OrthographicCamera cam; private int cnt = 1; private boolean preEnter = false; private Array<Image> imagelist = null; private Image player = null; private float startPositionWidth; private float startPositionHeight; private int originX = 0; private int originY = 0; private Direction direction = null; enum Direction { FORWARD(0, 0, 1), LEFT (1, -1, 0), RIGHT(2, 1, 0), BACKWARD(3, 0, -1), ; int no; int moveX; int moveY; Direction(int no, int moveX, int moveY){ this.no = no; this.moveX = moveX; this.moveY = moveY; } } @Override public void create() { stage = new Stage(){ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { //ここで最初に触ったところとっておいて originX = screenX; originY = screenY; return true; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { //上下左右判定 int defX = 0; if (originX < screenX) { defX = screenX - originX; direction = Direction.RIGHT; } else { defX = originX - screenX; direction = Direction.LEFT; } if (originY < screenY) { if (defX < (screenY - originY)){ direction = Direction.BACKWARD; } } else { if (defX < (originY - screenY)){ direction = Direction.FORWARD; } } for (Image image : imagelist) { image.addAction( Actions.moveBy( direction.moveX * 50, direction.moveY * 50, 1 ) ); //移動方向から移動アクションset } return true; } }; 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 (!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)); //攻撃っぽい動き } } 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(); System.out.println(null == direction ? "" : direction.toString()); stage.draw(); } @Override public void resize(int width, int height) { cam.update(); } @Override public void dispose() { stage.dispose(); } }
タッチされた最初の座標をとっておいて、
@Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { //ここで最初に触ったところとっておいて originX = screenX; originY = screenY; return true; }
指を離したタイミングで、差分をとって上下左右を判定しています。
例えば、右上方向に指をスライドさせて離した場合は、X座標とY座標で差分が大きい方の方向にしています。斜め移動する場合はいらないけど。
@Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { //上下左右判定 int defX = 0; if (originX < screenX) { defX = screenX - originX; direction = Direction.RIGHT; } else { defX = originX - screenX; direction = Direction.LEFT; } if (originY < screenY) { if (defX < (screenY - originY)){ direction = Direction.BACKWARD; } } else { if (defX < (originY - screenY)){ direction = Direction.FORWARD; } } for (Image image : imagelist) { image.addAction( Actions.moveBy( direction.moveX * 50, direction.moveY * 50, 1 ) ); //移動方向から移動アクションset } return true; }