- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这就是我在paintComponent中所拥有的(省略了其他大部分内容,只是与一个名为Item的对象对象有关,该对象带有多边形字段,if语句的显式参数对该问题并不重要)
目前,它显示为纯白色,因为我将颜色设置为全部255,但是我想使其逐渐平滑地过渡为不同的颜色,而不是频闪,更像是脉动,但我真的不知道该怎么称呼。我当时正在考虑将Color的显式参数替换为可循环通过该数组中的数字的数组,并以某种方式将其链接到TimerListener,但是我对图形是陌生的,因此我不确定这是否是实现此目的的最佳方法。
public void paintComponent(Graphics g) {
Graphics2D sprite = (Graphics2D) g;
if (chalice.getHolding() == true || roomID == chalice.getRoomDroppedIn()) {
sprite.setColor(new Color(255, 255, 255));
sprite.fill(chalice.getPoly());
}
}
最佳答案
一些基本概念...
脉动效果需要沿两个方向移动,它需要淡入和淡出
为了知道应该应用多少“效果”,需要知道两件事。首先,整个效果要花多长时间(从完全不透明到完全透明再返回),动画要经过多长时间。
这不是一件容易的事情,有很多“状态”信息需要管理和维护,通常,与其他效果或实体分开进行。
在我看来,最简单的解决方案是设计某种“时间线”,该时间线沿时间线管理关键点(关键帧),计算每个点与其表示的值之间的距离。
退后一步。我们知道:
0%我们要完全不透明
50%我们希望完全透明
100%我们想完全不透明
上面考虑了我们要“自动反转”动画的情况。
使用百分比的原因是,它允许我们定义任何给定持续时间的时间轴,该时间轴将处理其余部分。在可能的情况下,始终使用这样的归一化值,这会使整个过程变得更加简单。TimeLine
以下是一个非常简单的“时间轴”概念。它具有Duration
,播放时间线的时间,关键帧和关键帧,这些关键帧在时间线的持续时间内提供关键值,并提供在时间线的整个生命周期中的特定点计算特定值的方法。
此实现还提供“自动”重播功能。也就是说,如果时间轴“结束”播放时指定了Duration
,而不是停止播放,它将自动重置并在下一个周期(整整)中考虑“结束”的时间量
public class TimeLine {
private Map<Float, KeyFrame> mapEvents;
private Duration duration;
private LocalDateTime startedAt;
public TimeLine(Duration duration) {
mapEvents = new TreeMap<>();
this.duration = duration;
}
public void start() {
startedAt = LocalDateTime.now();
}
public boolean isRunning() {
return startedAt != null;
}
public float getValue() {
if (startedAt == null) {
return getValueAt(0.0f);
}
Duration runningTime = Duration.between(startedAt, LocalDateTime.now());
if (runningTime.compareTo(duration) > 0) {
runningTime = runningTime.minus(duration);
startedAt = LocalDateTime.now().minus(runningTime);
}
long total = duration.toMillis();
long remaining = duration.minus(runningTime).toMillis();
float progress = remaining / (float) total;
return getValueAt(progress);
}
public void add(float progress, float value) {
mapEvents.put(progress, new KeyFrame(progress, value));
}
public float getValueAt(float progress) {
if (progress < 0) {
progress = 0;
} else if (progress > 1) {
progress = 1;
}
KeyFrame[] keyFrames = getKeyFramesBetween(progress);
float max = keyFrames[1].progress - keyFrames[0].progress;
float value = progress - keyFrames[0].progress;
float weight = value / max;
float blend = blend(keyFrames[0].getValue(), keyFrames[1].getValue(), 1f - weight);
return blend;
}
public KeyFrame[] getKeyFramesBetween(float progress) {
KeyFrame[] frames = new KeyFrame[2];
int startAt = 0;
Float[] keyFrames = mapEvents.keySet().toArray(new Float[mapEvents.size()]);
while (startAt < keyFrames.length && keyFrames[startAt] <= progress) {
startAt++;
}
if (startAt >= keyFrames.length) {
startAt = keyFrames.length - 1;
}
frames[0] = mapEvents.get(keyFrames[startAt - 1]);
frames[1] = mapEvents.get(keyFrames[startAt]);
return frames;
}
protected float blend(float start, float end, float ratio) {
float ir = (float) 1.0 - ratio;
return (float) (start * ratio + end * ir);
}
public class KeyFrame {
private float progress;
private float value;
public KeyFrame(float progress, float value) {
this.progress = progress;
this.value = value;
}
public float getProgress() {
return progress;
}
public float getValue() {
return value;
}
@Override
public String toString() {
return "KeyFrame progress = " + getProgress() + "; value = " + getValue();
}
}
}
timeLine = new TimeLine(Duration.ofSeconds(5));
timeLine.add(0.0f, 1.0f);
timeLine.add(0.5f, 0.0f);
timeLine.add(1.0f, 1.0f);
Duration
并设置关键帧值。之后,我们只需要“启动”它,并根据播放的时间从
value
中获取当前的
TimeLine
。
Duration
,从而更改速度,它可以“正常工作”并且可重复使用,因为您可以为多个实体生成多个实例,并且可以对其进行独立管理。
Timer
充当动画的“主循环”。在每个循环中,它都会向
TimeLine
询问“当前”值,该值仅充当“脉冲”效应的
alpha
值。
TimeLine
类本身已足够解耦,因此无论您如何建立“主循环”都无关紧要,只需启动它并在可能的情况下从中提取“当前”值即可。
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private TimeLine timeLine;
private float alpha = 0;
public TestPane() {
timeLine = new TimeLine(Duration.ofSeconds(5));
timeLine.add(0.0f, 1.0f);
timeLine.add(0.5f, 0.0f);
timeLine.add(1.0f, 1.0f);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!timeLine.isRunning()) {
timeLine.start();
}
alpha = timeLine.getValue();
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
g2d.setColor(Color.RED);
g2d.fill(new Rectangle(45, 45, 110, 110));
g2d.dispose();
g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
g2d.fill(new Rectangle(50, 50, 100, 100));
g2d.setColor(Color.BLACK);
g2d.draw(new Rectangle(50, 50, 100, 100));
g2d.dispose();
}
}
}
TimeLine
绑定为指定实体的效果的一部分。这会将
TimeLine
绑定到特定实体,这意味着许多实体都可以拥有自己的
TimeLine
来计算不同值和效果的验证
TimeLine
泛型的想法,因此可以将其用于根据所需结果生成不同值的真实性,从而使其成为更加灵活和可重复使用的解决方案。
TimeLine
在这里也可以为您提供帮助(您不需要那么长的时间)。您可以设置一系列颜色(用作关键帧),并根据动画的进度计算要使用的颜色。
关于java - 如何使Java中的多边形对象脉动(例如Atari游戏“冒险”中的 chalice ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50539835/
更新与总结 我觉得有义务让这个问题更清楚,现在有悬赏。 (另外,我很确定当 calc() CSS3 单位值被支持时,这将是 child 的游戏,做类似 width: calc(25% - 5px) 的
我已经对此进行了搜索,但仍然无法弄清楚我做错了什么。调用save()后域对象 id是 null . 我已经阅读了如果保存对象时出现问题会发生这种情况,并且 save(flush:true)如果是这种情
我正在使用 g:datePicker name="date1"id="date1"value="${program?.startDate}"> 在 Controller 中,当使用 params.da
有以下实体: class Letter { String email String subject String content List attac
更新。检查这些 benchmarks自己测试一下。 我是否应该将对象集合存储在某些服务的变量中,如下所示: ConfigService{ private def countries = Coun
谁能告诉我: 和 在“$”之前使用“\”的真实例子是: 谢谢。 最佳答案 \${...} 会将文字美元大括号放入输出中,而不是将内容作为表达式求值。我很少需要在普通 GSP 中使用它,但它在脚手
例如,我在书中读到,如果我们创建关系 1:m,Grails 会自动添加方法 addTo* 和 removeTo* 现在我想,我如何才能看到我的域类的所有方法? 例如,有些像这样:Domain.getA
我有这个非常复杂的表格。必须填写所有字段,但可以保存填充过程并继续进行。所以我需要的是,当最终确认被按下时,所有数据都会得到验证。但是因为它已经保存到数据库,所以调用validate()无效。我通过加
我在 windows xp 和 centos 上使用 grails 1.3.4。 centos上的Tomcat 5。 我在一个应用程序(以及我放在一起的测试应用程序)上进行了“grails dev w
我正在尝试从 xml 创建一些域对象。 class A { String name } class B { A a int something } 我首先创建了一个 A 的实例,然后刷新。
我有一个标准的 GSP,我正在尝试包含 scriptaculous ajax 搜索。 Search Entry Search
在我看到的文章中,作者似乎只是在讨论创建自定义属性编辑器并注册它们。我如何实际使用它们?它们是否仅在数据绑定(bind)期间自动使用? 最佳答案 属性编辑器在数据绑定(bind)期间自动使用,但 da
有人以前见过这个问题吗?这是什么原因? Error executing script War: loader constraint violation in interface itable init
我正在与 chalice 一起工作 Chalice (编写python rest api)和cashfree sdk Cashfree SDK (转账)。 我有一个 public_key.pem 文件
我正在玩弄 Chalice这是我第一次尝试将其评估为可能的替代框架,以将我现有的 Python Flask API 从 EC2 迁移到 Lambda。 我从一个 Amazon Linux EC2 实例
如何向我的数据库 mySql 发送请求,然后检查是否有更改,以便在有更改时可以刷新 div? -编辑- 这是我的代码。它只是每 5 秒自动刷新一次加载函数,以便将新的更改应用到表中。我不知道如何向我的
我一直在努力弄清楚我右边的 div 是什么漂浮了。 .header{ background:red; height:100px; width:100%; } .left{ background:whi
我正在使用这样的 g:select 标签: 它呈现以下 HTML: Select City... A B C- D 但是,我希望我的 HTML 看起来像这样;因为我正在做一些 javasc
我的 GSP 页面有多个表格以及一些其他 HTML 元素,例如输入文本字段和标题 文本。 我希望在生成的文本中捕获所有这些信息。 到目前为止,我所看到的示例仅适用于生成一张表。 是否有一种从 GSP
我们正在实现 Plone CMS 作为 ISO9001 文档的存储库。 ISO 要求一定量的日志记录,任何熟悉该标准的人都可能知道:-) 为了灵 active ,我们希望合并(不按特定顺序): 新内容
我是一名优秀的程序员,十分优秀!