libGDX. Урок 12. Обнаружение касаний и перемещение спрайтов

Обработка касаний

 

Двигаем корзину

Для обработки касаний пользователя добавим метод в классе Basket:

public void handleTouch(float x,float y){
    if(x-(basketSprite.getWidth()/2)>0.0){
        setPosition(x-(basketSprite.getWidth()/2), 0);
    }
    else{
        setPosition(0,0);
    }
}

Этим методом мы устанавливаем корзину по x координате туда, где пользователь произвел касание по экрану. Мы устанавливаем положение корзины таким образом, чтобы её центр совпадал с координатой (по x) касания. Но вдруг пользователь сделает касание слишком близко к левому краю экрана, то корзина будет нарисована за пределами видимой области. На этот случай мы просто устанавливаем позицию корзины в координаты (0, 0).

Теперь нужно создать класс InputManager, который будет отвечать за обработку касаний в нашей игре. В этой игре мы будем руководствоваться иной стратегии обработки касаний. В играх, которые мы создавали раньше мы использовали стратегию «опрос». Она работает следующим образом – на каждом кадре мы опрашивали процессор, коснулся ли пользователь экрана устройства. На это расходуется некоторое время.

Стратегия, которую мы собираемся использовать сейчас называется «обработка событий» (event handling). По сути мы настроим (переопределим) уже существующие методы различного вида касаний/нажатий, которые автоматически вызываются фреймворком.

В пакете com.mygdx.basketball.managers добавьте новый класс с именем InputManager. Отредактируйте код, как показано внизу:

package com.mygdx.basketball.managers;


        import com.badlogic.gdx.InputAdapter;
        import com.badlogic.gdx.graphics.OrthographicCamera;
        import com.badlogic.gdx.math.Vector3;

public class InputManager extends InputAdapter {

    OrthographicCamera camera;
    static Vector3 temp = new Vector3();

    public InputManager(OrthographicCamera camera) {
        this.camera = camera;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {

        temp.set(screenX,screenY, 0);
        // получаем координаты касания относительно области просмотра нашей камеры
        camera.unproject(temp);
        float touchX = temp.x;
        float touchY = temp.y;
        GameManager.basket.handleTouch(touchX, touchY);
        return false;

    }

}

В созданном нами классе InputManager мы наследуемся (extends) от класса InputAdapter, который в свою очередь наследует (implements) интерфейс InputProcessor, в котором описаны методы для обработки касаний/нажатий. В данном случае мы переопределяем (@Override) метод touchUp(…), который вызывается при событии «палец был поднят с экрана (то есть в тот момент, когда мы отрываем палец от экрана устройства)». В качестве параметров этот метод принимает четыре аргумента, их которых первые два – это координаты X и Y. Третий параметр – ID указателя, который используется при обработке множественных касаний (мультитач). Четвертый – определяет кнопку, которая была нажата на мышке.

Конструктор нашего класса получает в качестве аргумента экземпляр камеры (camera). Используем это для получения корректных координат касания. После того, как мы получим эти координаты в методе touchUp(…) мы передадим их в качестве аргументов методу handleTouch() класса Basket. Для того, чтобы получение данных о касаниях/нажатиях стало доступным в нашей игре необходимо добавить следующую строку в метод create() класса BasketBall:

Gdx.input.setInputProcessor(new InputManager(camera));// доступ класса InputManager для получения касаний/нажатий

Вот, что получилось на данный момент:

обработка касаний перемещение спрайта libGDX

 

Создаём мяч

Создадим класс с именем Ball для обозначения мяча. В папке com.mygdx.basketball.gameobjects создайте новый Java класс и отредактируйте его код, как показано внизу:

package com.mygdx.basketball.gameobjects;


import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;


public class Ball {

    public Sprite ballSprite;// спрайт для отображения мяча

    public void render(SpriteBatch batch){
        ballSprite.draw(batch);
    }

}

В классе GameManager мы создадим экземпляр класса Ball и инициализируем его, аналогично тому, как мы это сделали с корзиной. Добавим пару переменных:

private static float BASKET_RESIZE_FACTOR = 3000f; // переменная для масштабирования корзины
static Ball ball; // экземпляр мяча
static Texture ballTexture; // текстура для мяча
private static final float BALL_RESIZE_FACTOR = 2500f;

Теперь инициализируем наш мяч в методе initialize():

backgroundSprite.setSize(width, height); // устанавливаем размер заднего фона по размеру экрана предполагаемого устройства

ball = new Ball();
ballTexture = new Texture(Gdx.files.internal("ball.png"));
ball.ballSprite = new Sprite(ballTexture);
ball.ballSprite.setSize(ball.ballSprite.getWidth()* (width/BALL_RESIZE_FACTOR), ball.ballSprite.getHeight()*(width/BALL_RESIZE_FACTOR));
ball.ballSprite.setPosition(0.0f, height- ball.ballSprite.getHeight());

Отрисовка мяча будет происходить в методе render():

backgroundSprite.draw(batch);
basket.render(batch);
ball.render(batch);

И наконец избавимся от текстуры в методе dispose():

//избавляемся от текстур, чтобы не захламлять память устройства
backgroundTexture.dispose();
basketTexture.dispose();
ballTexture.dispose();

 

Добавим движение мячу. Перемещение спрайта

Для начала добавим пару переменных в класс Ball:

public Sprite ballSprite;// спрайт для отображения мяча
public Vector2 position = new Vector2(); // вектор для обозначения позиции
public Vector2 velocity = new Vector2(); // вектор для обозначения скорости

Переменная position будет хранить в себе текущие координаты x и y мяча. Переменная velocity будет определять скорость изменения смещения, то есть как быстро будет двигаться мяч. К примеру, если автомобиль движется со скоростью 100км/ч, то он проедет 100 километров за один час. Точно так же, если определить скорость мяча как 10 единиц в секунду, то мяч будет двигаться со скорость 10 игровых единиц за одну секунду.

Теперь нужно объявить метод update(), который мы будем вызывать при каждой смене кадра. Позиция мяча будет меняться в зависимости от скорости. Так что наш метод update() будет выглядеть следующим образом:

Поскольку мы опускаем мяч сверху, давайте установим скорость на 5 единиц/кадр по координатам Y. Сделаем это в методе initialize() класса GameManager (красным отмечена строка, которую нужно удалить):

ball = new Ball();
ballTexture = new Texture(Gdx.files.internal("ball.png"));
ball.ballSprite = new Sprite(ballTexture);
ball.ballSprite.setSize(ball.ballSprite.getWidth()* (width/BALL_RESIZE_FACTOR), ball.ballSprite.getHeight()*(width/BALL_RESIZE_FACTOR));
ball.ballSprite.setPosition(0.0f, height- ball.ballSprite.getHeight());
ball.position.set(0.0f, height-ball.ballSprite.getHeight());
ball.velocity.set(0, -5);

Вызывать метод update() будем в методе renderGame() перед его отрисовкой:

backgroundSprite.draw(batch);
basket.render(batch);
ball.update();
ball.render(batch);

Теперь, запустив игру вы можете наблюдать, как мяч будет плавно опускаться вниз:

перемещение движение спрайта libgdx android studio

Код для этого урока доступен для скачивания внизу:

Скачать исходники