Skip to content
Open
12 changes: 11 additions & 1 deletion fxgl-entity/src/main/java/com/almasb/fxgl/particle/Particle.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,19 @@ boolean update(double tpf) {

// From https://stackoverflow.com/questions/17113234/affine-transform-scale-around-a-point
// x = S(x – c) + c = Sx + (c – Sc)
var sx = (scaleOrigin.x + x - entityScale.x * (scaleOrigin.x + x)) + entityScale.y * x;

//scale origin and entity scale are 2d points, when referencing the x and y values these are
//the corresponding points
var sx = (scaleOrigin.x + x - entityScale.x * (scaleOrigin.x + x)) + entityScale.x * x;
//sx = (x plus the scale of x from origin - center of where particle comes from) + scaled centre of particle
//sx = (x on the page, including origin - center of where particle comes from + sc

var sy = (scaleOrigin.y + y - entityScale.y * (scaleOrigin.y + y)) + entityScale.y * y;

//x = sx + (c - Sc)
//sx = x - (c - Sc) = x - c + Sc
//S is the scaling transformation, and c is the center in coordinates relative to the top left.

getView().setLayoutX(sx);
getView().setLayoutY(sy);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package intermediate.particles;

import com.almasb.fxgl.animation.Interpolators;
import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.dsl.components.ExpireCleanComponent;
import com.almasb.fxgl.dsl.components.ProjectileComponent;
import com.almasb.fxgl.particle.ParticleComponent;
import com.almasb.fxgl.particle.ParticleEmitters;
import javafx.geometry.Point2D;
import javafx.scene.effect.BlendMode;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.util.Duration;

import java.util.function.Supplier;

import static com.almasb.fxgl.dsl.FXGL.*;
import static com.almasb.fxgl.dsl.FXGL.entityBuilder;
import static com.almasb.fxgl.dsl.FXGL.random;
import static com.almasb.fxgl.dsl.FXGL.runOnce;
import static com.almasb.fxgl.dsl.FXGL.texture;

public class ParticleScaleSample2 extends GameApplication{
@Override
protected void initSettings(GameSettings settings) {
settings.setWidth(1280);
settings.setHeight(720);
}

@Override
protected void initGame() {
getGameScene().setBackgroundColor(Color.BLACK);

//this circle has a difference in the x and the y points in the scale
spawnMinor(new Point2D(450, 300), false);

//this cricle has the same x and y points in the scale
spawnMinor(new Point2D(450, 300), true);

//both of their locations are the same, they should spawn in the same space. but because the x point is affected by the scale, the circles appear in different locations.
//this shows the biggest issue with this bug, the x value is being affected by the y scale, when it should not be.
}

private void spawnMinor(Point2D p, Boolean pointsTheSame) {
var emitter = ParticleEmitters.newExplosionEmitter(17);

//this sets the new points to be either the same or different
if (pointsTheSame) {
emitter.setEntityScaleFunction(() -> new Point2D(1, 1));
} else {
emitter.setEntityScaleFunction(() -> new Point2D(1, 2));
}
emitter.setExpireFunction(i -> Duration.seconds(10));
emitter.setSize(10, 20);
entityBuilder()
.at(p)
.with(new ParticleComponent(emitter))
.with(new ExpireCleanComponent(Duration.seconds(3)).animateOpacity())
.zIndex(100)
.buildAndAttach();
}

public static void main(String[] args) {
launch(args);
}
}