about 6 years ago

入力イベントを調べたり制御するには Gdx.input クラスを使用する。 Gdx.input には、どのキーが押されたか、タッチされているか、などの入力イベントを調べるメソッドが用意されている。より複雑な入力イベントを制御するには InputProcessor をセットすることで、ドラッグなどを扱うことができる。

オリジナルの SimpleApp は水玉を受け取るバケットを isTouched メソッドとgetX, getYによって制御していた。この一連のメソッドでは、どの座標がタッチされているかまでしか分からないので、バケットをドラッグして移動することはできない。ドラッグさせるには、InputProcessorを実装し、touchDragged で処理を記述する必要になる。

なお、Gdx.input で扱うy座標は、通常のy座標(上から下へ値が増加)になる。

package com.badlogic.drop;

import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;

public class GameLoopScreen extends DropScreen implements InputProcessor {
    TextureAtlas atlas;
    Sprite drop;
    Sprite bucket;
    Sound dropSound;
    Music rainMusic;
    SpriteBatch batch;
    OrthographicCamera camera;
    Array<Sprite> raindrops;
    long lastDropTime;

    public GameLoopScreen() {
        atlas = new TextureAtlas(Gdx.files.internal("images.atlas"));
        drop = atlas.createSprite("droplet");
        bucket = atlas.createSprite("bucket");

        dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
        rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));

        rainMusic.setLooping(true);
        rainMusic.play();

        camera = new OrthographicCamera();
        camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        batch = new SpriteBatch();

        bucket.setX(Gdx.graphics.getWidth() / 2 - 48 / 2);
        bucket.setY(20);
        bucket.setSize(48, 48);

        raindrops = new Array<Sprite>();
        spawnRaindrop();

        Gdx.input.setInputProcessor(this);
    }

    private void spawnRaindrop() {
        Sprite raindrop = new Sprite();
        raindrop.setX(MathUtils.random(0, Gdx.graphics.getWidth() - 48));
        raindrop.setY(Gdx.graphics.getHeight());
        raindrop.setSize(48, 48);
        raindrops.add(raindrop);
        lastDropTime = TimeUtils.nanoTime();
    }

    @Override
    public void update(float delta) {

        if (Gdx.input.isKeyPressed(Keys.LEFT))
            bucket.setX(bucket.getX() - 200 * Gdx.graphics.getDeltaTime());
        if (Gdx.input.isKeyPressed(Keys.RIGHT))
            bucket.setX(bucket.getX() + 200 * Gdx.graphics.getDeltaTime());

        if (bucket.getX() < 0)
            bucket.setX(0);
        if (bucket.getX() > Gdx.graphics.getWidth() - 48)
            bucket.setX(Gdx.graphics.getWidth() - 48);

        if (TimeUtils.nanoTime() - lastDropTime > 1000000000 / 2)
            spawnRaindrop();

        Iterator<Sprite> iter = raindrops.iterator();
        while (iter.hasNext()) {
            Sprite raindrop = iter.next();
            raindrop.setY(raindrop.getY() - 500 * Gdx.graphics.getDeltaTime());
            if (raindrop.getY() + 48 < 0)
                iter.remove();
            if (raindrop.getBoundingRectangle().overlaps(bucket.getBoundingRectangle())) {
                dropSound.play();
                iter.remove();
            }
        }
    }

    @Override
    public void draw(float delta) {
        Gdx.gl.glClearColor(0, 0, 0.2f, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        camera.update();
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        batch.draw(bucket, bucket.getX(), bucket.getY());
        for (Sprite raindrop : raindrops) {
            batch.draw(drop, raindrop.getX(), raindrop.getY());
        }
        batch.end();
    }

    @Override
    public void dispose() {
        atlas.dispose();
        dropSound.dispose();
        rainMusic.dispose();
        batch.dispose();
    }

    @Override
    public boolean touchUp(int arg0, int arg1, int arg2, int arg3) {
        return false;
    }

    @Override
    public boolean touchDragged(int x, int y, int pointer) {
        if (bucket.getBoundingRectangle().contains(x, Gdx.graphics.getHeight() - y )) {
            Vector3 touchPos = new Vector3();
            touchPos.set(x, y, 0);
            camera.unproject(touchPos);
            bucket.setX(touchPos.x - 48 / 2);
            return true;
        }
        return false;
    }

    @Override
    public boolean touchDown(int arg0, int arg1, int arg2, int arg3) {
        return false;
    }

    @Override
    public boolean scrolled(int arg0) {
        return false;
    }

    @Override
    public boolean mouseMoved(int arg0, int arg1) {
        return false;
    }

    @Override
    public boolean keyUp(int arg0) {
        return false;
    }

    @Override
    public boolean keyTyped(char arg0) {
        return false;
    }

    @Override
    public boolean keyDown(int arg0) {
        return false;
    }
}
← libGDX - スプライトとテクスチャアトラス MapView へのピンの表示 →