スマフォな入力処理

スマフォな入力処理

今までキーボードで動かしていたけど、一応スマフォで動くゲームを目指すので入力をそれっぽくしていってます。

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;
            }