Случилось так, что мне нужно было написать 2D приложение — игру на Java. Пришлось искать готовый движок, который умеет загружать спрайты, обрабатывать коллизию объектов, работать с тайлами и фонами. Это был минимальный набор нужных мне функций. Выбор пал на "Golden T Game Engine (GTGE)". Отчетливо разобравшись в нем, хотелось бы поделиться с Хаброюзерами своим опытом.
После того, как скачали движок с официального сайта, подключим его к нашему проекту. Теперь создадим основной класс приложения. У меня он называется Main. После этого, напишем минимальное приложение, для движка.
Теперь, можно запустить. Появляется окно с логотипом GTGE и счетчиком FPS. Но картинка не обновляется. Проще говоря, накладывается друг на друга. Это можно увидеть, посмотрев на счетчик FPS. Далее, нужно инициализировать игровое поле с фоном. В качестве фона, может быть любой RGB цвет, картинка. Что такое игровое поле? Игровое поле — это площадка для рендеринга на ней графики. Чтобы создать игровое поле и впоследствии фон к нему, нужно подключить ещё пару файлов:
Игровое поле (Play Field) — является классом. Но перед тем, как создать объект, мы должны инициализировать фон. В данном случае это будет сплошной белый цвет. В начало класса Main напишем:
Теперь, самое время создавать игровое поле. Сразу после инициализации фона пишем:
Одним из аргументов конструктора класса PlayField является фон, который будет установлен по умолчанию. И наконец, самое главное — обновление и рендеринг игровой площадки.
В функцию рендеринга графики напишем следующее:
А в функцию обновления —
Можно запускать. Что мы видим? Белое пустое игровое поле. Чего-то не хватает. Далее будем создавать игровой объект, который управляется с помощью стрелок.
Чтобы нарисовать спрайт на игровой площадке, нужно его сначала загрузить и поместить в группу спрайтов. Этим сейчас и займемся. Нам понадобятся три переменные, отвечающие за группу спрайта, загруженную картинку и, собственно, за сам спрайт.
Объявим эти переменные в самом начале класса:
Далее, подключим файл для загрузки картинок:
Все, теперь полная боевая готовность для загрузки спрайта. В качестве «главного героя» я выбрал вот эту картинку:
Как же загрузить спрайт и поместить его на игровую площадку? Для начала, нужна группа для спрайтов. Группа нужна для удобного хранения всех спрайтов. Для каждой группы может быть задано N-ое кол-во спрайтов. Гораздо удобнее манипулировать группой, чем каждым спрайтом в отдельности. После создания группы, нужно загрузить картинку. Потом, создать объект спрайта и назначить ему загруженную картинку. Затем, этот спрайт добавить в группу и группу разместить на игровой площадке.
Вот код, с помощью которого можно проделать описанное выше (загрузка картинки должна быть только в функции инициализации ресурсов! Поэтому, я перенес создание спрайта и подобные функции в эту функцю):
Теперь, можно запустить игру и посмотреть, что же там вышло? У нас имеется спрайт на игровом поле. Было бы неплохо, «научиться» им управлять. Что же делаем для этого?
Мы имеем ссылку на объект спрайта. У этого объекта, есть функции moveX и moveY. Вот ими мы и будем манипулировать.
Для обработки нажатий клавиш мы должны подключить следующий файл:
В функции обновления напишем следующее:
Теперь, мы можем управлять нашим главным героем.
Для того, чтобы создать анимированный спрайт, нужно загрузить картинку специальной функцией getImages. Можно загрузить как и картинку состоящую из нескольких кадров, так и каждый кадр по отдельности. Вот два небольших примера:
Пример 1:
Пример 2:
В первом примере, мы загружаем одну картинку и функция уже режет ее на отдельные кадры. Первый аргумент функции — путь к картинке. Второй — кол-во кадров по горизонтали, третий аргумент — кол-во кадров по вертикали. Тут все просто. По сути, функция из первого примера делает то же самое, что и во втором примере.
Во втором примере, мы создаем массив и загружаем в него по одной картинке.
Чтобы создать спрайт для этой картинки, нужно создать объект для анимированного спрайта:
Этот объект имеет ряд функций. Основные из них, я сейчас подробно опишу.
Для того, чтобы изменить скорость анимации, нам нужно обратиться к таймеру. Делается это функцией выше. Затем, вызываем функцию setDelay, аргументом которой является число — кол-во мс между сменами кадром спрайта.
Каждый кадр будет сменяться через 100мс.
Чтобы изменить кол-во кадров анимированного спрайта, нужно вызвать функцию setAnimationFrame
Пример:
Первый аргумент — первый кадр, второй — последний. Последний кадр - кол-во элементов в массиве с загруженными картинками — 1. Таким образом, можно менять последовательность кадров в спрайте.
С помощью функции setAnimate можно включить/выключить анимацию спрайта.
А с помощью функции setLoopAnim можно изменить «зацикленность» кадров. Т.е. после окончания анимации, она не будет остановлена, а автоматически начнется сначала.
Вернемся к нашему основному примеру.
Изменим код загрузки картинок и создания спрайтов на
И в начале класса, объявим несколько переменных:
А так же, изменим движение спрайта на
Теперь можно запустить и посмотреть. На игровой площадке имеется спрайт самолета с «крутящейся лопастью».
На этом, я закончу первое знакомство с Golden T Game Engine. Это далеко не все, о чем хотелось бы рассказать, но пост и так получился довольно большой. Большое спасибо за прочтение статьи.
Для написания статьи использовал информацию с официального сайта движка.
Ссылка на пример.
После того, как скачали движок с официального сайта, подключим его к нашему проекту. Теперь создадим основной класс приложения. У меня он называется Main. После этого, напишем минимальное приложение, для движка.
import java.awt.*;
import com.golden.gamedev.*;
public class Main extends Game{
public static void main(String[] args) {
GameLoader game = new GameLoader(); // Класс, управляющий инициализацией приложения
game.setup(new Main(), new Dimension(640,480), false);//Инициализация графического движка
game.start();
}
@Override
public void initResources() {
//Инициализация игровых переменных и ресурсов
}
@Override
public void render(Graphics2D g) {
//Рендеринг графики
}
@Override
public void update(long elapsedTime) {
//Обновления переменных и ресурсов
}
}
Теперь, можно запустить. Появляется окно с логотипом GTGE и счетчиком FPS. Но картинка не обновляется. Проще говоря, накладывается друг на друга. Это можно увидеть, посмотрев на счетчик FPS. Далее, нужно инициализировать игровое поле с фоном. В качестве фона, может быть любой RGB цвет, картинка. Что такое игровое поле? Игровое поле — это площадка для рендеринга на ней графики. Чтобы создать игровое поле и впоследствии фон к нему, нужно подключить ещё пару файлов:
import com.golden.gamedev.object.*;
import com.golden.gamedev.object.background.*;
Игровое поле (Play Field) — является классом. Но перед тем, как создать объект, мы должны инициализировать фон. В данном случае это будет сплошной белый цвет. В начало класса Main напишем:
Background back = new ColorBackground(new Color(255, 255, 255));
Теперь, самое время создавать игровое поле. Сразу после инициализации фона пишем:
PlayField pf = new PlayField(back);
Одним из аргументов конструктора класса PlayField является фон, который будет установлен по умолчанию. И наконец, самое главное — обновление и рендеринг игровой площадки.
В функцию рендеринга графики напишем следующее:
pf.render(g);
А в функцию обновления —
pf.update(elapsedTime);
Можно запускать. Что мы видим? Белое пустое игровое поле. Чего-то не хватает. Далее будем создавать игровой объект, который управляется с помощью стрелок.
Чтобы нарисовать спрайт на игровой площадке, нужно его сначала загрузить и поместить в группу спрайтов. Этим сейчас и займемся. Нам понадобятся три переменные, отвечающие за группу спрайта, загруженную картинку и, собственно, за сам спрайт.
Объявим эти переменные в самом начале класса:
SpriteGroup spr_group;
BufferedImage spr_buffer;
Sprite spr_player;
Далее, подключим файл для загрузки картинок:
import java.awt.image.BufferedImage;
Все, теперь полная боевая готовность для загрузки спрайта. В качестве «главного героя» я выбрал вот эту картинку:
Как же загрузить спрайт и поместить его на игровую площадку? Для начала, нужна группа для спрайтов. Группа нужна для удобного хранения всех спрайтов. Для каждой группы может быть задано N-ое кол-во спрайтов. Гораздо удобнее манипулировать группой, чем каждым спрайтом в отдельности. После создания группы, нужно загрузить картинку. Потом, создать объект спрайта и назначить ему загруженную картинку. Затем, этот спрайт добавить в группу и группу разместить на игровой площадке.
Вот код, с помощью которого можно проделать описанное выше (загрузка картинки должна быть только в функции инициализации ресурсов! Поэтому, я перенес создание спрайта и подобные функции в эту функцю):
// Создаем группу спрайтов
spr_group = new SpriteGroup("grp_player");
//Загружаем картинку
spr_buffer = getImage("plane1.png");
// Создаем спрайт игрока
spr_player = new Sprite(spr_buffer, 100,100);
// Добавляем к группе спрайт игрока
spr_group.add(spr_player);
// Помещаем группу спрайтов на игровую площадку
pf.addGroup(spr_group);
Теперь, можно запустить игру и посмотреть, что же там вышло? У нас имеется спрайт на игровом поле. Было бы неплохо, «научиться» им управлять. Что же делаем для этого?
Мы имеем ссылку на объект спрайта. У этого объекта, есть функции moveX и moveY. Вот ими мы и будем манипулировать.
Для обработки нажатий клавиш мы должны подключить следующий файл:
import java.awt.event.KeyEvent;
В функции обновления напишем следующее:
if (keyDown(KeyEvent.VK_W)) spr_player.moveY(-3);
if (keyDown(KeyEvent.VK_S)) spr_player.moveY(3);
if (keyDown(KeyEvent.VK_A)) spr_player.moveX(-3);
if (keyDown(KeyEvent.VK_D)) spr_player.moveX(3);
Теперь, мы можем управлять нашим главным героем.
Анимация
Далее, хотелось бы рассказать о загрузке анимации. Для анимации, я буду использовать следующий спрайт:Для того, чтобы создать анимированный спрайт, нужно загрузить картинку специальной функцией getImages. Можно загрузить как и картинку состоящую из нескольких кадров, так и каждый кадр по отдельности. Вот два небольших примера:
Пример 1:
BufferedImage[] aspr_buffer = getImages("plane2.png", 3, 1);
Пример 2:
BufferedImage[] aspr_buffer = {
getImage("plane1.png"),
getImage("plane2.png"),
getImage("plane3.png")
};
В первом примере, мы загружаем одну картинку и функция уже режет ее на отдельные кадры. Первый аргумент функции — путь к картинке. Второй — кол-во кадров по горизонтали, третий аргумент — кол-во кадров по вертикали. Тут все просто. По сути, функция из первого примера делает то же самое, что и во втором примере.
Во втором примере, мы создаем массив и загружаем в него по одной картинке.
Чтобы создать спрайт для этой картинки, нужно создать объект для анимированного спрайта:
aspr_player = new AnimatedSprite(aspr_buffer, 100, 100);
Этот объект имеет ряд функций. Основные из них, я сейчас подробно опишу.
// Функция возвращает ссылку на объект таймера
aspr_player.getAnimationTimer();
Для того, чтобы изменить скорость анимации, нам нужно обратиться к таймеру. Делается это функцией выше. Затем, вызываем функцию setDelay, аргументом которой является число — кол-во мс между сменами кадром спрайта.
aspr_player.getAnimationTimer().setDelay(100);
Каждый кадр будет сменяться через 100мс.
Чтобы изменить кол-во кадров анимированного спрайта, нужно вызвать функцию setAnimationFrame
Пример:
aspr_player.setAnimationFrame(0, aspr_buffer.length-1);
Первый аргумент — первый кадр, второй — последний. Последний кадр - кол-во элементов в массиве с загруженными картинками — 1. Таким образом, можно менять последовательность кадров в спрайте.
С помощью функции setAnimate можно включить/выключить анимацию спрайта.
// Анимация включена
aspr_player.setAnimate(true);
А с помощью функции setLoopAnim можно изменить «зацикленность» кадров. Т.е. после окончания анимации, она не будет остановлена, а автоматически начнется сначала.
aspr_player.setLoopAnim(true);
Вернемся к нашему основному примеру.
Изменим код загрузки картинок и создания спрайтов на
aspr_buffer = getImages("plane2.png", 3, 1);
aspr_player = new AnimatedSprite(aspr_buffer, 100, 100);
aspr_player.getAnimationTimer().setDelay(80);
aspr_player.setAnimationFrame(0, aspr_buffer.length-1);
aspr_player.setAnimate(true);
aspr_player.setLoopAnim(true);
spr_group.add(aspr_player);
И в начале класса, объявим несколько переменных:
BufferedImage[] aspr_buffer;
AnimatedSprite aspr_player;
А так же, изменим движение спрайта на
if (keyDown(KeyEvent.VK_W)) aspr_player.moveY(-2);
if (keyDown(KeyEvent.VK_S)) aspr_player.moveY(2);
if (keyDown(KeyEvent.VK_A)) aspr_player.moveX(-2);
if (keyDown(KeyEvent.VK_D)) aspr_player.moveX(2);
Теперь можно запустить и посмотреть. На игровой площадке имеется спрайт самолета с «крутящейся лопастью».
На этом, я закончу первое знакомство с Golden T Game Engine. Это далеко не все, о чем хотелось бы рассказать, но пост и так получился довольно большой. Большое спасибо за прочтение статьи.
Для написания статьи использовал информацию с официального сайта движка.
Ссылка на пример.