Spostamento di oggetti e timer

Ho uno schermo con 500 larghezze e 400 di altezza, e ho un vettore con un mucchio di forms. diciamo che il vettore ha 2 forms diverse per esempio. Voglio che l’object si apra in modo casuale dalla parte inferiore dello schermo, raggiunga una certa salita e poi ricada giù (simile al ninja della frutta del gioco, dove i frutti sono le mie forms).

Nella mia vista principale (vista) ho un vettore di forms di cui istanziare i timer, aggiungere alla matrice e posizionarli nel fondo dello schermo usando la funzione di traduzione. Il mio timer acquisisce un ascoltatore di azioni che sostanzialmente modifica la traslazione della forma per spostarsi verso l’alto e poi verso il basso, ma il mio problema è che tutte le forms iniziano contemporaneamente alla stessa ora.

Qualcosa come questo:

Shape f = new Shape(new Area(new Ellipse2D.Double(0, 50, 50, 50))); f.translate(0, 400); f.timer = new Timer( 10 , taskPerformsr); f.timer.start(); vector.add(f); Shape f2 = new Shape(new Area(new Rectangle2D.Double(0, 50, 50, 50))); f2.translate(200, 400); f2.timer = new Timer( 10 , taskPerformsr); f2.timer.setInitialDelay(5000); f2.timer.start(); vector.add(f2); 

e il mio ascoltatore di azioni:

  Random generator = new Random(); ActionListener taskPerformsr = new ActionListener() { public void actionPerformsd(ActionEvent evt) { //...Perform a task... for (Shape s : model.getShapes()) { // Scale object using translate // once reached ascent drop down // translate to diffrenet part of the bottom of the screen // delay its timer } update(); //basically repaints } }; 

Sto incontrando problemi che tutte le forms seguono lo stesso timer e iniziano a comparire contemporaneamente (nessun ritardo) …

Qualche suggerimento su come evitare questo o se c’è un approccio diverso dovrei provare

“Voglio che l’object saltato in modo casuale dalla parte inferiore dello schermo raggiunga una certa salita e poi ricada giù”

Vedere l’esempio eseguibile di seguito. Quello che faccio è passare un radomDelayedStart alla Shape . Ogni ticchettio del timer, il randomDelayedStart diminuisce fino a raggiungere 0, che è quando la bandiera deve essere disegnata in rilievo. La maggior parte della logica è nei metodi della class Shape , che sono chiamati nel Actionlistener del Timer . Tutto è fatto in un unico Timer . Per la salita, ho usato solo un hard 50 codificato, ma puoi anche passare un’ascensione casuale alla Shape . Fatemi sapere se avete domande. Ho provato a rendere il codice il più chiaro ansible.

inserisci la descrizione dell'immagine qui

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; public class RandomShape extends JPanel { private static final int D_HEIGHT = 500; private static final int D_WIDTH = 400; private static final int INCREMENT = 8; private List shapes; private List colors; private Timer timer = null; public RandomShape() { colors = createColorList(); shapes = createShapeList(); timer = new Timer(30, new ActionListener() { public void actionPerformsd(ActionEvent e) { for (Shape shape : shapes) { shape.move(); shape.decreaseDelay(); repaint(); } } }); JButton start = new JButton("Start"); start.addActionListener(new ActionListener(){ public void actionPerformsd(ActionEvent e) { timer.start(); } }); JButton reset = new JButton("Reset"); reset.addActionListener(new ActionListener(){ public void actionPerformsd(ActionEvent e) { shapes = createShapeList(); timer.restart(); } }); JPanel panel = new JPanel(); panel.add(start); panel.add(reset); setLayout(new BorderLayout()); add(panel, BorderLayout.PAGE_START); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); for (Shape shape : shapes) { shape.drawShape(g); } } @Override public Dimension getPreferredSize() { return new Dimension(D_WIDTH, D_HEIGHT); } private List createColorList() { List list = new ArrayList<>(); list.add(Color.BLUE); list.add(Color.GREEN); list.add(Color.ORANGE); list.add(Color.MAGENTA); list.add(Color.CYAN); list.add(Color.PINK); return list; } private List createShapeList() { List list = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < 20; i++) { int randXLoc = random.nextInt(D_WIDTH); int randomDelayedStart = random.nextInt(100); int colorIndex = random.nextInt(colors.size()); Color color = colors.get(colorIndex); list.add(new Shape(randXLoc, randomDelayedStart, color)); } return list; } class Shape { int randXLoc; int y = D_HEIGHT; int randomDelayedStart; boolean draw = false; boolean down = false; Color color; public Shape(int randXLoc, int randomDelayedStart, Color color) { this.randXLoc = randXLoc; this.randomDelayedStart = randomDelayedStart; this.color = color; } public void drawShape(Graphics g) { if (draw) { g.setColor(color); g.fillOval(randXLoc, y, 30, 30); } } public void move() { if (draw) { if (y <= 50) { down = true; } if (down) { y += INCREMENT; } else { y -= INCREMENT; } } } public void decreaseDelay() { if (randomDelayedStart <= 0) { draw = true; } else { randomDelayedStart -= 1; } } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); frame.add(new RandomShape()); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } }