control

Table of Contents

Добавляем управление

Управление координатами

Теперь, когда мы можем определить, когда игрок нажимает на кнопки, мы могли бы попробовать дать ему возможность двигать картинку внутри окна. Будем следить за нажатиями кнопок "вверх", "вниз", "влево" и "вправо" и изменять координату, где будет выводиться картинка.

Чтобы удобно хранить координату нам потребуется переменная совершенно особого типа Vector2. Эта переменная хранит в себе координату "икс" и координату "игрек" и определена в пакете com.badlogic.gdx.math.Vector2, который мы должны подключить вслед за всем импортами, которые у нас есть:

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;

public class MyGdxGame extends ApplicationAdapter {

Теперь мы можем объявлять переменные типа Vector2. Объявим такую в начале нашего класса:

Texture img;
Vector2 pos = new Vector2(10,0);

@Override

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

// input
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
    pos.y += 10;
}
if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
    pos.y -= 10;
}
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
    pos.x += 10;
}
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
    pos.x -= 10;
}
batch.begin();

Теперь нам осталось только выводить картинку в те координаты, которые лежат в переменной:

// render
batch.begin();
batch.draw(img, pos.x, pos.y);
batch.end();

Попробуйте понажимать на стрелки и вы увидите, что наш злобный смайлик двигается по экрану.

Добавляем физику

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

Добавим еще один Vector2 для того чтобы хранить в нем ускорения назовем его acc от "acceleration":

Vector2 pos = new Vector2(10,0);
Vector2 acc = new Vector2(2,3);

@Override

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

// input
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
    acc.y += 10;
}
if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
    acc.y -= 10;
}
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
    acc.x += 10;
}
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
    acc.x -= 10;
}
batch.begin();

А теперь добавим кусок кода, который по предыдущим координатам и ускорению вычисляет новые координаты:

// update coords ball
pos.x = pos.x + 2 * acc.x;
pos.y = pos.y + 2 * acc.y;

Чтобы ускорение не было слишком большим добавим ограничитель:

// braking ball
if (acc.x > 7) {
    acc.x = 7;
}
if (acc.y > 7) {
    acc.y = 7;
}
if (acc.x < -7) {
    acc.x = -7;
}
if (acc.y < -7) {
    acc.y = -7;
}

Посмотрите, как изменилось поведение картинки. Правда она стремиться улететь за границы окна, поэтому…

Добавляем границы

Чтобы добавить границы, за которые картинка не должна улетать, нам нужно узнать ширину и высоту окна. В библиотеке есть специальные функции для этого, задействуем их, но сначала объявим еще одну переменную для хранения максимальных значений:

Vector2 acc = new Vector2(0,0);
Vector2 max = new Vector2(0,0);

@Override

А теперь присвоим ей правильное значение:

public void create () {
    batch = new SpriteBatch();
    img = new Texture("badlogic.jpg");
    max.x = Gdx.graphics.getWidth();
    max.y = Gdx.graphics.getHeight();
}

Теперь можно добавить кусок кода, который будет изменять направление скорости при столкновении со стенками - это вызовет эффект отражения картинки от краев окна:

// bounce
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
    acc.x -= 1;
}
if (pos.x < 0) {
    acc.x = -acc.x;
}
if (pos.y < 0) {
    acc.y = -acc.y;
}
if (pos.x + img.getWidth() > max.x) {
    acc.x = -acc.x;
}
if (pos.y + img.getHeight() > max.y) {
    acc.y = -acc.y;
}
pos.x = pos.x + 2 * acc.x;

Теперь картинка ведет себя так как мы ожидаем - отскакивает от краев окна и имеет некоторую инерцию. Убедившись, что все работает нормально, можно заменить большую картинку на какой-нибудь маленький шарик. Я выбрал тенисный мячик:

nil

Эту картинку надо положить в папку core/assets и изменить строчку, которая ее загружает:

batch = new SpriteBatch();
img = new Texture("ball.png");
max.x = Gdx.graphics.getWidth();

Еще я сделал фон радикально черным - так смотрится лучше:

Gdx.gl.glClearColor(0, 0, 0, 1);
Яндекс.Метрика
Home