Как стать автором
Обновить

Конкурс JavaFX Tower Defence: Световые башни

Время на прочтение5 мин
Количество просмотров1.1K
Прочитав про конкурс Tower Defence, у меня сразу возникла идея создать мир вечной темноты.
Чтобы хоть что-то увидеть, нужно построить световую башню для освещения проползающих мимо существ.

Под катом описана реализация этой идеи на JavaFX.




Башни и снаряды


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

Для начала создадим световую башню, в которой переопределим скорострельность, радиус поражения, а в методе fire() зададим тип выстреливаемого снаряда.
public class LightTower extends Tower {
 
    override var fireRate = 10s;
    override var fireRadius = 100;
 
    override function fire(start: Point2D, end: Point2D): Void {
        LightBall { field: field damage: damage start: start end: end }
    }
}
 
Затем определим световой снаряд, в методе explode() которого нужно указать, что случается со снарядом при взрыве.
public class LightBall extends Bullet {
 
    override var damageRadius: Number = 120;
 
    override function explode() {
        // explosion algorithm
    }
 
}
 

Компонент ShapeSubtract


JavaFX предоставляет компонент ShapeSubtract, который позволяет отрисовывать геометрические фигуры с вырезанными областями.

Все игровое пространство будет закрыто черным квадратом. В качестве области освещаемой световым снарядом будем использовать окружность.
ShapeSubtract {
    a: Rectangle { width: 200 height: 200 fill: Color.BLACK }
    b: Circle {
        radius: 75
        centerX: 100
        centerY: 100
    }
}
 
Для анимации освещаемой области воспользуемся классом Timeline, который будет измненять переменную radius от ее начального значения до конечного. А также свяжем атрибут radius окружности с переменной radius с помощью оператора bind.
var radius = 5.0;
 
Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames:  at (5s) {radius  => 75.0 tween Interpolator.LINEAR }
}.play();
 
ShapeSubtract {
    a: Rectangle { width: 200 height: 200 fill: Color.BLACK }
    b: Circle {
        radius: bind radius
        centerX: 100
        centerY: 100
    }
}
 

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



Добится желаемого результата можно поставив оператор bind перед вычитаемой окружностью. В этом случае мы связываем вычитаемую фигуру с выражением справа, и при изменении любой переменной, входящей в выражение, будет также изменяться компонент ShapeSubtract.
var radius = 5.0;
 
Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames:  at (5s) {radius  => 75.0 tween Interpolator.LINEAR }
}.play();
 
ShapeSubtract {
    a: Rectangle { width: 200 height: 200 fill: Color.BLACK }
    b: bind Circle {
        radius: radius
        centerX: 100
        centerY: 100
    }
}
 



Отрисовка освещаемой области


Зададим класс LightElem, который будет содержать атрибуты освещаемой области. При взрыве снаряда будем создавать LightElem, задавать его координаты и анимировать радиус освещаемой области.
public class LightElem {
 
    public var radius: Number;
    public var centerX: Number;
    public var centerY: Number;
}
 
Вся графики определяется в методе create() класса Field.
Для отрисовки освещаемой области теперь нужно пройтись по последовательности элементов LightElem и создать окружности, которые будут вычитаться из затемненной области.
public class Field extends CustomNode {
 
    public var lights: LightElem[];
 
    override function create() {
        Group {
            content: [
                // Other components
                ShapeSubtract {
                    a: Rectangle { width: 550 height: 550 fill: Color.BLACK }
                    b: bind for (elem in lights) Circle {
                            centerX: elem.centerX
                            centerY: elem.centerY
                            radius: elem.radius
                        }
                }
            ]
         }
     }
}
 
Теги:
Хабы:
+5
Комментарии3

Публикации

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн