From 3ded671fcd1dac4df2e06bff7a63dc6658e31937 Mon Sep 17 00:00:00 2001 From: Andrew Dey Date: Sat, 7 May 2022 03:41:41 -0400 Subject: [PATCH] Add static lighting game object (#202) * (#68) add light2d --- .../tech/fastj/graphics/game/Light2D.java | 58 +++++++++++++++++ .../fastj/graphics/game/Light2DBuilder.java | 63 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 src/main/java/tech/fastj/graphics/game/Light2D.java create mode 100644 src/main/java/tech/fastj/graphics/game/Light2DBuilder.java diff --git a/src/main/java/tech/fastj/graphics/game/Light2D.java b/src/main/java/tech/fastj/graphics/game/Light2D.java new file mode 100644 index 00000000..eaea3706 --- /dev/null +++ b/src/main/java/tech/fastj/graphics/game/Light2D.java @@ -0,0 +1,58 @@ +package tech.fastj.graphics.game; + +import tech.fastj.math.Pointf; + +import tech.fastj.graphics.Drawable; +import tech.fastj.graphics.util.DrawUtil; + +import tech.fastj.systems.control.Scene; +import tech.fastj.systems.control.SimpleManager; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.RadialGradientPaint; + +public class Light2D extends GameObject { + + private final AlphaComposite alphaComposite; + private final RadialGradientPaint gradient; + + protected Light2D(Pointf location, Pointf size, RadialGradientPaint gradient, AlphaComposite alphaComposite) { + this.alphaComposite = alphaComposite; + this.gradient = gradient; + setCollisionPath(DrawUtil.createPath(DrawUtil.createBox(location, size))); + } + + public static Light2DBuilder create(Pointf location, Pointf size) { + return new Light2DBuilder(location, size, Drawable.DefaultShouldRender); + } + + public static Light2DBuilder create(Pointf location, Pointf size, boolean shouldRender) { + return new Light2DBuilder(location, size, shouldRender); + } + + @Override + public void destroy(Scene origin) { + super.destroyTheRest(origin); + } + + @Override + public void destroy(SimpleManager origin) { + super.destroyTheRest(origin); + } + + @Override + public void render(Graphics2D g) { + Composite oldComposite = g.getComposite(); + Paint oldPaint = g.getPaint(); + + g.setComposite(alphaComposite); + g.setPaint(gradient); + g.fill(getCollisionPath()); + + g.setComposite(oldComposite); + g.setPaint(oldPaint); + } +} diff --git a/src/main/java/tech/fastj/graphics/game/Light2DBuilder.java b/src/main/java/tech/fastj/graphics/game/Light2DBuilder.java new file mode 100644 index 00000000..f01546ff --- /dev/null +++ b/src/main/java/tech/fastj/graphics/game/Light2DBuilder.java @@ -0,0 +1,63 @@ +package tech.fastj.graphics.game; + +import tech.fastj.math.Pointf; + +import tech.fastj.graphics.gradients.Gradients; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.RadialGradientPaint; +import java.util.Objects; + +/** A builder class for creating {@link Light2D} objects. */ +public class Light2DBuilder { + private final boolean shouldRender; + private final Pointf location; + private final Pointf size; + + private AlphaComposite alphaComposite = AlphaComposite.SrcOver; + private RadialGradientPaint gradientPaint; + + Light2DBuilder(Pointf location, Pointf size, boolean shouldRender) { + this.location = location; + this.size = size; + this.shouldRender = shouldRender; + } + + public Light2DBuilder withGradient(RadialGradientPaint gradientPaint) { + this.gradientPaint = Objects.requireNonNull(gradientPaint, "The radial gradient paint should not be null."); + return this; + } + + public Light2DBuilder withGradient(Color centerColor, Color outerColor) { + Objects.requireNonNull(centerColor, "The center color should not be null."); + Objects.requireNonNull(outerColor, "The outer color should not be null."); + this.gradientPaint = Gradients.radialGradient(Pointf.add(location, size.copy().divide(2f)), evaluateRadius()) + .withColors(centerColor, outerColor) + .build(); + return this; + } + + public Light2DBuilder withAlphaComposite(AlphaComposite alphaComposite) { + this.alphaComposite = Objects.requireNonNull(alphaComposite, "The alpha composite should not be null."); + return this; + } + + /** + * Creates a new {@link Light2D} object, using the data provided by earlier method calls. + * + * @return The resulting {@code Light2D}. + */ + public Light2D build() { + return (Light2D) new Light2D(location, size, gradientPaint, alphaComposite) + .setShouldRender(shouldRender); + } + + private float evaluateRadius() { + Pointf horizontalSide = Pointf.subtract(Pointf.add(location, size.x, 0f), location); + Pointf verticalSide = Pointf.subtract(Pointf.add(location, 0f, size.y), location); + + Pointf smallestSide = horizontalSide.squareMagnitude() < verticalSide.squareMagnitude() ? horizontalSide : verticalSide; + return smallestSide.magnitude() / 2.0f; + } +}