2D игра на Java с использованием фреймворка FXGL.
Учебный проект для изучения разработки игр на Java.
- Java 17 или выше
- Gradle 8.x (включён в проект как
gradlew)
./gradlew run- W — вверх
- A — влево
- S — вниз
- D — вправо
Собирайте монеты, избегайте стен.
Этот проект создан поэтапно. Изучайте коммиты последовательно, чтобы понять процесс разработки.
Что сделано:
- Создан Gradle проект с плагинами
applicationиjava - Добавлен плагин
org.openjfx.javafxpluginдля JavaFX - Подключена зависимость FXGL 17.3
- Настроены Java 17 и репозитории
Файлы:
build.gradle— конфигурация сборкиsettings.gradle— имя проекта
Ключевые настройки в build.gradle:
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
javafx {
version = '17'
modules = ['javafx.controls', 'javafx.fxml', 'javafx.swing']
}
dependencies {
implementation 'com.github.almasb:fxgl:17.3'
}Что сделано:
- Создан класс
FxglGameApp, наследующийGameApplication - Реализованы методы жизненного цикла FXGL:
initSettings()— настройки окна (800x600, заголовок)initGame()— инициализация игрового мираinitInput()— обработка вводаinitPhysics()— коллизииinitUI()— отображение счёта
Файлы:
src/main/java/com/example/fxglgame/FxglGameApp.java
Жизненный цикл FXGL:
initSettings() → initGame() → initInput() → initPhysics() → initUI() → игровой цикл
Что сделано:
- Создан
EntityType— enum с типами сущностей (PLAYER, COIN, WALL) - Создан
GameEntityFactory— фабрика для создания сущностей - Реализованы методы создания:
newPlayer()— игрок (синий квадрат 40x40)newCoin()— монета (жёлтый круг)newWall()— стена (серый прямоугольник)
Файлы:
src/main/java/com/example/fxglgame/EntityType.javasrc/main/java/com/example/fxglgame/GameEntityFactory.java
Аннотация @Spawns:
@Spawns("player")
public Entity newPlayer(SpawnData data) {
return entityBuilder(data)
.type(EntityType.PLAYER)
.bbox(new HitBox(BoundingShape.box(40, 40)))
.view(new Rectangle(40, 40, Color.DODGERBLUE))
.with(new PlayerComponent())
.collidable()
.build();
}Что сделано:
- Создан
PlayerComponent— компонент управления игроком - Реализовано движение через
translateX/Y(без PhysicsComponent) - Добавлены флаги направления (up, down, left, right)
- Ограничение перемещения в пределах поля
Файлы:
src/main/java/com/example/fxglgame/PlayerComponent.java
Движение в onUpdate():
@Override
public void onUpdate(double tpf) {
double dx = 0, dy = 0;
if (left) dx -= SPEED;
if (right) dx += SPEED;
if (up) dy -= SPEED;
if (down) dy += SPEED;
entity.translateX(dx * tpf);
entity.translateY(dy * tpf);
}Что сделано:
- Использован
UserActionдля обработки клавиш onAction()вызывается каждый кадр при зажатой клавишеonActionEnd()вызывается при отпускании
Файлы:
FxglGameApp.java— методinitInput()
Пример:
getInput().addAction(new UserAction("Up") {
@Override protected void onAction() { pc().setUp(true); }
@Override protected void onActionEnd() { pc().setUp(false); }
}, KeyCode.W);Что сделано:
- Реализована коллизия PLAYER ↔ COIN в
initPhysics() - При столкновении монета удаляется, счёт увеличивается
- Добавлен спавн новых монет
Файлы:
FxglGameApp.java— методinitPhysics()
Коллизия:
onCollisionBegin(EntityType.PLAYER, EntityType.COIN, (p, coin) -> {
coin.removeFromWorld();
inc("score", +10);
spawnRandomCoin();
});Что сделано:
- Создан текстовый элемент счёта
- Реализовано绑定 с property через
textProperty().bind() - Счёт обновляется автоматически
Файлы:
FxglGameApp.java— методinitUI()
Binding:
Text scoreText = getUIFactoryService().newText("Score: 0", Color.OLIVEDRAB, 22.0);
scoreText.textProperty().bind(
getWorldProperties().intProperty("score").asString("Score: %d")
);
addUINode(scoreText);Что сделано:
- Добавлены стены по периметру поля
- Созданы внутренние препятствия
- Метод
spawnWall()для удобного создания стен
Файлы:
FxglGameApp.java— методinitGame()иspawnWall()
fxgl-game/
├── src/main/java/com/example/fxglgame/
│ ├── FxglGameApp.java # Точка входа, игровой цикл
│ ├── EntityType.java # Типы сущностей
│ ├── GameEntityFactory.java # Фабрика сущностей
│ └── PlayerComponent.java # Компонент игрока
├── build.gradle # Конфигурация Gradle
├── settings.gradle # Настройки проекта
├── .gitignore # Игнорируемые файлы
└── README.md # Эта документация
Последние 5 коммитов:
git log -n 5 --onelineПодробно с изменениями:
git show <commit-hash>История конкретного файла:
git log --follow src/main/java/com/example/fxglgame/FxglGameApp.javaРазница между коммитами:
git diff <commit1> <commit2>- Откройте репозиторий на GitHub
- Кнопка "Commits" над списком файлов — вся история
- Клик по коммиту — изменения с подсветкой
- Кнопка
<>(Browse files) — просмотр файлов на момент коммита
- Враги — добавить компонент преследования игрока
- Анимации — спрайты вместо геометрических фигур
- Звуки — музыка и эффекты (FXGL поддерживает)
- Уровни — загрузка карт из файлов
- Босс — большой враг с несколькими фазами
- Способности — ускорение, прыжки, атака
# Собрать JAR
./gradlew build
# Запустить JAR
java -jar build/libs/fxgl-game-1.0.0.jarУчебный проект. FXGL лицензируется под Apache 2.0.