Статьи

libgdx и Kotlin — Классы [2D прототипирование платформера]

Этот пост является продолжением постов libgdx и Kotlin .

Я решил создать прототип простого 2D-платформера (по аналогии с Star Assault из моих ранних публикаций), но вместо Java я использую и изучаю Kotlin.

Для этого урока проект должен быть в своем первоначальном состоянии с предыдущего поста. Чистый Java-проект libGdx превратился в проект Kotlin. Мы будем глушить в нашем главном файле Game.kt , ранее Nemo.kt

Источник проекта для начального состояния можно найти здесь .

Kotlin не требует, чтобы имя файла совпадало с именем класса или даже находилось в структуре каталогов, эквивалентной объявленному пакету.

Без дальнейших церемоний, вот первое изменение в коде.

Основной класс был изменен с Nemo на Game , потому что мы будем использовать имя Nemo для персонажа.
Так что Nemo.kt -> Game.kt как первый шаг.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
...// imports omitted
class Game : ApplicationAdapter() {
    internal lateinit var batch: SpriteBatch
    internal lateinit var img: Texture
    internal lateinit var nemo: Nemo
 
    override fun create() {
        batch = SpriteBatch()
        img = Texture("images/nemo_01.png")
        nemo = Nemo()
    }
 
    override fun render() {
        Gdx.gl.glClearColor(0f, 0f, 0f, 1f)
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
        batch.begin()
        batch.draw(img, nemo.position.x, nemo.position.y)
        batch.end()
    }
 
    data class Nemo(val position: Vector2 = Vector2(0f, 0f))
}

Выделенные строки показывают изменения.

  • # 05 — Объявите атрибут nemo типа Nemo и отметьте его для поздней инициализации.
  • # 09 — загрузить другой gif для текстуры (посмотрите проект на github)
  • # 10 — создает экземпляр класса Nemo . Это эквивалент Java new Nemo();
  • # 21 — Эта строка создает класс данных с одним атрибутом, позицией типа Vector2 из libGdx, и по умолчанию этот вектор является новым Vector2 (0f, 0f), если мы его опускаем при инициализации.

Класс данных — это класс контейнера данных, в который setters сгенерированные getters , setters если атрибутом является var а не val , equals , hashCode , toString . Обратите внимание на квалификатор val для атрибута, означающий, что позиция является final и неизменной. Это означает, что если вектор назначен, он не может быть изменен. Однако значения вектора могут быть изменены . Хорошей практикой является сделать все неизменным, если не требуется иное, и Kotlin разработан для использования этого шаблона по умолчанию.

Это сокращение для:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Nemo {
    // val is the equivalent of final
    private final Vector2 position;
 
    // constructor with argument
    public Nemo(Vector2 position) {
        this.position = position;
    }
     
    // default constructor
    public Nemo() {
        this.position = new Vector2(0f, 0f);
    }
 
    // getter
    public Vector2 getPosition() {
        return position;
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        Nemo nemo = (Nemo) o;
 
        return position != null ? position.equals(nemo.position) : nemo.position == null;
 
    }
 
    @Override
    public int hashCode() {
        return position != null ? position.hashCode() : 0;
    }
 
    @Override
    public String toString() {
        return "Nemo{" +
                "position=" + position +
                '}';
    }
}

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

1
data class Nemo(val position: Vector2 = Vector2(0f, 0f))
  • # 17 — эта инструкция рисует загруженную ранее текстуру в позиции, занимаемой Nemo. Эквивалентный Java-код будет:
    1
    batch.draw(img, nemo.getPosition().getX(), nemo.getPosition().getY());

В Kotlin нам не нужно указывать метод получения или установки, мы используем точечную запись для атрибутов. Все это заботится компилятором, а методы доступа выводятся.

1
nemo.getPosition().getX()

становится

1
nemo.position.x

Попробуйте запустить проект, чтобы мы могли увидеть результат:

Экран игры в действии

Экран игры в действии

Это все на данный момент. Обязательно ознакомьтесь с документацией Kotlin о классах , чтобы узнать о них больше.

В следующей части мы будем превращать Немо в анимированного и подвижного персонажа.