Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The better solution would be providing the <code>Circle</code> with some means to determine what it should do when it moves out of bounds, however, the code is so convoluted I used this instead...</p> <p>Start by adding a <code>getBounds</code> method to your <code>Circle</code> class...</p> <pre><code>public Rectangle getBounds() { int x = centerX - radius; int y = centerY - radius; return new Rectangle(x, y, radius * 2, radius * 2); } </code></pre> <p>This will provide information about how big and where the circle is...</p> <p>Next, in your <code>MoveListener</code>, add a <code>checkBounds</code> method...</p> <pre><code>public void checkBounds(Circle circle) { int height = getHeight(); Rectangle bounds = circle.getBounds(); if (bounds.y + bounds.height &gt; height) { circle.move(0, -(height) + bounds.height); } } </code></pre> <p>This will be used to determine if a given <code>Circle</code> has moved beyond the bounds of the viewable area...</p> <p>Next, in your <code>MoveListener</code>'s <code>actionPerformed</code> method, check each circle...</p> <pre><code>c1.move(0, s); checkBounds(c1); </code></pre> <p>As so on...</p> <p><strong>Updated with quick and fast example</strong></p> <p>So, this is quick and fast example of what I've being trying to get to...</p> <p><img src="https://i.stack.imgur.com/kgQM5.gif" alt="Drop Circles"></p> <p>This uses an <code>ArrayList</code> as the primary container for the <code>Circles</code>, but it wouldn't take much to change it to use an array (in fact, some parts would become easier)....</p> <pre><code>import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; 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.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class DropCircles { public static void main(String[] args) { new DropCircles(); } public DropCircles() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public static class TestPane extends JPanel { protected static final int MAX_CIRCLES = 7; private List&lt;Circle&gt; circles; private Random rnd = new Random(); public TestPane() { circles = new ArrayList&lt;&gt;(MAX_CIRCLES); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { while (circles.size() &lt; MAX_CIRCLES) { circles.add(createCircle()); } List&lt;Circle&gt; purge = new ArrayList&lt;&gt;(MAX_CIRCLES); for (Circle circle : circles) { Point p = circle.getLocation(); p.y += circle.getYDelta(); if (p.y &gt; getHeight()) { purge.add(circle); } else { circle.setLocation(p); } } circles.removeAll(purge); repaint(); } }); timer.start(); } protected Circle createCircle() { int x = rnd.nextInt(getWidth()); int radius = 5 + rnd.nextInt(45); int speed = 1 + rnd.nextInt(8); if (x + radius &gt; getWidth()) { x = getWidth() - radius; } Circle circle = new Circle(radius, new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255))); circle.setLocation(x, 0); circle.setYDelta(speed); return circle; } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); for (Circle circle : circles) { circle.paint(g); } g2d.dispose(); } } public static class Circle { private final int radius; private final Color color; private int x; private int y; private int yDelta; public Circle(int radius, Color color) { this.radius = radius; this.color = color; } public void setLocation(int x, int y) { this.x = x; this.y = y; } public void setLocation(Point p) { setLocation(p.x, p.y); } public Point getLocation() { return new Point(x, y); } public void setYDelta(int yDelta) { this.yDelta = yDelta; } public int getYDelta() { return yDelta; } public void paint(Graphics g) { g.setColor(color); g.fillOval(x, y, radius, radius); } } } </code></pre> <p>Basically what happens is, as a <code>Circle</code> leaves the viewable area, it is removed from the "list" and on the next tick (of the <code>Timer</code>), a new <code>Circle</code> is created to ensure that there is always seven circles on the screen (or there abouts).</p> <p>If you were to use an array. You could simply create a new <code>Circle</code> in the movement loop at the index position of the current <code>Circle</code>, effectivly replacing it...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload