Java – moving objects and timers
I have a 500 width and 400 height screen, and I have a vector with a bunch of shapes Suppose the vector has two different shapes, for example I hope the random pop-up object from the bottom of the screen will rise to a certain level and then fall again (similar to the game fruit ninja, where the fruit is my shape)
In my home view, I have a shape vector. I instantiate the timer, add it to the array, and use the translate function to put them at the bottom of the screen My timer receives an action listener that basically changes the shape conversion until it rises and then moves down, but my problem is that all shapes start at the same time
Something like this:
Shape f = new Shape(new Area(new Ellipse2D.Double(0,50,50))); f.translate(0,400); f.timer = new Timer( 10,taskPerformer); f.timer.start(); vector.add(f); Shape f2 = new Shape(new Area(new Rectangle2D.Double(0,50))); f2.translate(200,400); f2.timer = new Timer( 10,taskPerformer); f2.timer.setInitialDelay(5000); f2.timer.start(); vector.add(f2);
And my action audience:
Random generator = new Random(); ActionListener taskPerformer = new ActionListener() { public void actionPerformed(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 } };
The problem I encountered was that all shapes followed the same timer and began to pop up at the same time (without delay)
Suggestions on how to avoid this situation, or I should try different methods
Solution
See the runnable example below What I did was pass radomdelayedstart to shape For each tick of the timer, randomdelayedstart decreases until it reaches 0, that is, when the drawn flag is raised Most logic is in the Shape class method, which is invoked in Timers Actionlistener. Everything is done in a timer For rise, I only used hard coded 50, but you can also pass random rise to shape If you have any questions, please let me know I try to make the code as clear as possible
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<Shape> shapes; private List<Color> colors; private Timer timer = null; public RandomShape() { colors = createColorList(); shapes = createShapeList(); timer = new Timer(30,new ActionListener() { public void actionPerformed(ActionEvent e) { for (Shape shape : shapes) { shape.move(); shape.decreaseDelay(); repaint(); } } }); JButton start = new JButton("Start"); start.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { timer.start(); } }); JButton reset = new JButton("Reset"); reset.addActionListener(new ActionListener(){ public void actionPerformed(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<Color> createColorList() { List<Color> 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<Shape> createShapeList() { List<Shape> 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); } }); } }