我的图标集有一个 timer
可以为这些图标设置动画。基本上 - 我有一张世界地图作为背景和汽车,飞机等。图标“浮动”在这张地图上。我正在使用 swing timer
来执行此操作,但它会在 JPanel
呈现后立即显示所有图标并开始它们的运动。我希望他们随机出现/开始他们的动作,我想实现第二个 timer
并且每 10 秒创建一个随机数 - 1 或 2 - (例如,如果数字等于 1,则开始此特定图标的动画)。
Timer timer;
....
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(world_map,0,0, getWidth(), getHeight(), null);
for (Transportation item : transportations) {
item.drawTransportation(g);
g2d.drawLine(item.start_x+25,item.start_y+25,item.finish_x+25,item.finish_y+25);
}
}
@Override
public void actionPerformed(ActionEvent e) {
for (Transportation item : transportations) {
if (item.x > item.finish_x) {
item.x -= 1;
}
else if (item.x < item.finish_x) {
item.x += 1;
}
if (item.y > item.finish_y) {
item.y -= 1;
}
else if (item.y < item.finish_y) {
item.y += 1;
}
}
repaint();
}
public void startCoords() {
for (Transportation item : transportations) {
item.setMap_coords(map_coords);
item.setCountries(countries);
}
timer = new Timer(10,this);
timer.start();
}
答案 0 :(得分:2)
“一般来说”,多个 Swing Timer
不能很好地扩展。如果您正在尝试开发某种类型的游戏,将所有“更新”保持在一个“游戏循环”中会在控制事情方面增加很多好处。
所以,这是一个非常简单的概念。当 Timer
滴答作响时,它会检查已经过去的时间量,当达到某种增量时,它会生成一堆“随机内容”。
我还放了一个小计数器,这样你就可以看到沿途确实有一些事情正在发生。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Point> points = new ArrayList<>(25);
private Timer timer;
private Instant clock;
private Random rnd = new Random();
public TestPane() {
setBackground(Color.BLACK);
setForeground(Color.WHITE);
timer = new Timer(5, new ActionListener() {
private Instant anchorTime;
@Override
public void actionPerformed(ActionEvent arg0) {
if (anchorTime == null) {
anchorTime = Instant.now();
}
// You could just do a mod 10, but I'm feeling lazy
if (Duration.between(anchorTime, Instant.now()).getSeconds() >= 10) {
anchorTime = Instant.now();
generateRandomThing();
}
repaint();
}
});
timer.setInitialDelay(0);
clock = Instant.now();
}
protected void generateRandomThing() {
for (int index = 0; index < 10; index++) {
int x = 10 + (int) (rnd.nextDouble() * (getWidth() - 20));
int y = 10 + (int) (rnd.nextDouble() * (getHeight() - 20));
Point p = new Point(x, y);
points.add(p);
}
}
@Override
public void addNotify() {
super.addNotify();
clock = Instant.now();
timer.start();
}
@Override
public void removeNotify() {
super.removeNotify(); //To change body of generated methods, choose Tools | Templates.
timer.stop();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Duration runTime = Duration.between(clock, Instant.now());
g2d.setColor(Color.WHITE);
FontMetrics fm = g2d.getFontMetrics();
String text = Long.toString(runTime.getSeconds());
int x = 10;
int y = 10 + fm.getAscent();
g2d.drawString(text, x, y);
g2d.setColor(Color.RED);
for (Point p : points) {
g2d.fillOval(p.x - 5, p.y - 5, 10, 10);
}
g2d.dispose();
}
}
}
这绝不是您可以采取的唯一方法,这只是可扩展性和控制问题之一。