如何在 JavaFX 中仅短时间显示某些内容?
How to show something in JavaFX for a brief time only?
我正在寻找一种简单的方法来在短时间内向 JavaFX 中的 ImageView 添加效果,但我还没有找到有效的方法。
这是一个游戏,玩家在平面上显示为 ImageView。当一个玩家攻击另一个玩家时,我想在被攻击的 ImageView 上显示效果,比如颜色叠加或类似的东西。
但是这样做的最佳方法是什么?有没有绕过计时器的方法或者我需要一个?
感谢您的帮助!
一般信息
有关此任务的一般信息位于:
- JavaFX periodic background task
只做一次,只是定期做的简单版本。
照明示例
一个简单的例子,使用灯光效果让 Smurfette 在你点击她时嫉妒地变成绿色。使用了 PauseTransition。
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class EnvyApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Image image = new Image(
"http://icons.iconarchive.com/icons/designbolts/smurfs-movie/128/smurfette-icon.png"
);
ImageView imageView = new ImageView(image);
PauseTransition hitAnimation = new PauseTransition(Duration.seconds(1));
hitAnimation.setOnFinished(e -> imageView.setEffect(null));
Light light = new Light.Distant();
light.setColor(Color.PALEGREEN);
Lighting lighting = new Lighting(light);
imageView.setOnMouseClicked(e -> {
imageView.setEffect(lighting);
hitAnimation.playFromStart();
});
stage.setScene(new Scene(new Group(imageView), Color.AQUA));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}
渐变色变化示例
单击 ImageView 时的渐变临时颜色叠加效果示例。效果展示使用时间线
颜色变化的示例基于此答案:
- How to change color of image in JavaFX
点击的图片变成红色,然后逐渐由红变灰,变回原来的颜色。可能有更简单的方法可以做到这一点,但这是我想出的方法。
效果的时间线存储在受影响节点的属性中,但如果愿意,它可以存储在某个实例变量(例如通用 Sprite class 的属性)中。时间线已存储,因此如果您在效果完成之前单击图像,则现有时间线可以从头开始重新启动。
应用不同的效果
效果仅为示例,您可以根据自己的需要进行调整。
通用原则可用于调整任何效果(或节点)属性。您可以根据需要调整效果的实际细节。例如,点击时除了颜色调整外,您还可以通过平移使节点反弹或应用发光效果或投影效果等。
示例代码
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Blush extends Application {
@Override
public void start(Stage stage) throws Exception {
HitEffectGenerator effectGenerator = new HitEffectGenerator();
Image image = new Image(
"http://icons.iconarchive.com/icons/designbolts/smurfs-movie/128/smurfette-icon.png"
);
ImageView imageView = new ImageView(image);
// try with clip on and off to see the difference . . .
imageView.setClip(new ImageView(image));
imageView.setOnMouseClicked(e -> effectGenerator.apply(imageView));
stage.setScene(new Scene(new Group(imageView), Color.AQUA));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}
class HitEffectGenerator {
public void apply(ImageView target) {
Timeline effectTimeline = (Timeline) target.getProperties().get(HitEffectGenerator.class);
if (effectTimeline == null) {
ColorAdjust monochrome = new ColorAdjust();
monochrome.setSaturation(-1.0);
ColorInput colorInput = new ColorInput(
0,
0,
target.getImage().getWidth(),
target.getImage().getHeight(),
Color.RED
);
Blend blush = new Blend(
BlendMode.MULTIPLY,
monochrome,
colorInput
);
target.setEffect(blush);
effectTimeline = new Timeline(
new KeyFrame(
Duration.ZERO,
new KeyValue(monochrome.saturationProperty(), -1.0),
new KeyValue(colorInput.paintProperty(), Color.RED)
),
new KeyFrame(
Duration.seconds(1),
new KeyValue(monochrome.saturationProperty(), 0.0),
new KeyValue(colorInput.paintProperty(), Color.TRANSPARENT)
)
);
effectTimeline.setOnFinished(e -> remove(target));
}
target.getProperties().put(HitEffectGenerator.class, effectTimeline);
effectTimeline.playFromStart();
}
public void remove(ImageView target) {
Timeline effectTimeline = (Timeline) target.getProperties().get(HitEffectGenerator.class);
if (effectTimeline != null) {
target.setEffect(null);
target.getProperties().remove(HitEffectGenerator.class);
effectTimeline.stop();
}
}
}
各种点击动画效果
参见:
- FXExperience canned animations, with blog post and example app.
这些示例很旧并且使用了已弃用的构建器 API,但很容易转换为使用构造函数和设置器而不是构建器的现代代码。
我正在寻找一种简单的方法来在短时间内向 JavaFX 中的 ImageView 添加效果,但我还没有找到有效的方法。
这是一个游戏,玩家在平面上显示为 ImageView。当一个玩家攻击另一个玩家时,我想在被攻击的 ImageView 上显示效果,比如颜色叠加或类似的东西。
但是这样做的最佳方法是什么?有没有绕过计时器的方法或者我需要一个?
感谢您的帮助!
一般信息
有关此任务的一般信息位于:
- JavaFX periodic background task
只做一次,只是定期做的简单版本。
照明示例
一个简单的例子,使用灯光效果让 Smurfette 在你点击她时嫉妒地变成绿色。使用了 PauseTransition。
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class EnvyApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Image image = new Image(
"http://icons.iconarchive.com/icons/designbolts/smurfs-movie/128/smurfette-icon.png"
);
ImageView imageView = new ImageView(image);
PauseTransition hitAnimation = new PauseTransition(Duration.seconds(1));
hitAnimation.setOnFinished(e -> imageView.setEffect(null));
Light light = new Light.Distant();
light.setColor(Color.PALEGREEN);
Lighting lighting = new Lighting(light);
imageView.setOnMouseClicked(e -> {
imageView.setEffect(lighting);
hitAnimation.playFromStart();
});
stage.setScene(new Scene(new Group(imageView), Color.AQUA));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}
渐变色变化示例
单击 ImageView 时的渐变临时颜色叠加效果示例。效果展示使用时间线
颜色变化的示例基于此答案:
- How to change color of image in JavaFX
点击的图片变成红色,然后逐渐由红变灰,变回原来的颜色。可能有更简单的方法可以做到这一点,但这是我想出的方法。
效果的时间线存储在受影响节点的属性中,但如果愿意,它可以存储在某个实例变量(例如通用 Sprite class 的属性)中。时间线已存储,因此如果您在效果完成之前单击图像,则现有时间线可以从头开始重新启动。
应用不同的效果
效果仅为示例,您可以根据自己的需要进行调整。
通用原则可用于调整任何效果(或节点)属性。您可以根据需要调整效果的实际细节。例如,点击时除了颜色调整外,您还可以通过平移使节点反弹或应用发光效果或投影效果等。
示例代码
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Blush extends Application {
@Override
public void start(Stage stage) throws Exception {
HitEffectGenerator effectGenerator = new HitEffectGenerator();
Image image = new Image(
"http://icons.iconarchive.com/icons/designbolts/smurfs-movie/128/smurfette-icon.png"
);
ImageView imageView = new ImageView(image);
// try with clip on and off to see the difference . . .
imageView.setClip(new ImageView(image));
imageView.setOnMouseClicked(e -> effectGenerator.apply(imageView));
stage.setScene(new Scene(new Group(imageView), Color.AQUA));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}
class HitEffectGenerator {
public void apply(ImageView target) {
Timeline effectTimeline = (Timeline) target.getProperties().get(HitEffectGenerator.class);
if (effectTimeline == null) {
ColorAdjust monochrome = new ColorAdjust();
monochrome.setSaturation(-1.0);
ColorInput colorInput = new ColorInput(
0,
0,
target.getImage().getWidth(),
target.getImage().getHeight(),
Color.RED
);
Blend blush = new Blend(
BlendMode.MULTIPLY,
monochrome,
colorInput
);
target.setEffect(blush);
effectTimeline = new Timeline(
new KeyFrame(
Duration.ZERO,
new KeyValue(monochrome.saturationProperty(), -1.0),
new KeyValue(colorInput.paintProperty(), Color.RED)
),
new KeyFrame(
Duration.seconds(1),
new KeyValue(monochrome.saturationProperty(), 0.0),
new KeyValue(colorInput.paintProperty(), Color.TRANSPARENT)
)
);
effectTimeline.setOnFinished(e -> remove(target));
}
target.getProperties().put(HitEffectGenerator.class, effectTimeline);
effectTimeline.playFromStart();
}
public void remove(ImageView target) {
Timeline effectTimeline = (Timeline) target.getProperties().get(HitEffectGenerator.class);
if (effectTimeline != null) {
target.setEffect(null);
target.getProperties().remove(HitEffectGenerator.class);
effectTimeline.stop();
}
}
}
各种点击动画效果
参见:
- FXExperience canned animations, with blog post and example app.
这些示例很旧并且使用了已弃用的构建器 API,但很容易转换为使用构造函数和设置器而不是构建器的现代代码。