如果它在JPanel上走得太远,我怎么能再画一个圆圈

时间:2013-12-09 02:31:52

标签: java swing jpanel paintcomponent

我正在尝试制作一个以JPanel顶部的7个圆圈开头的程序。所有圆圈都有随机的大小和颜色。圆圈从屏幕顶部开始,一旦到达JPanel的底部就向下移动,它们应该重新出现在JPanel的顶部并再次向下移动。我已经可以让圆圈向下移动,但我不确定如何再次将它们拉回到顶部。我创建了一个名为replaceCircle的方法,用于在JPanel的顶部绘制圆圈,但它不起作用。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;

public class keyExample extends JPanel implements ActionListener, KeyListener {

    private Circle[] circles = new Circle[7];

    Timer t = new Timer(5, this);
//current x and y
    double x = 150, y = 200;
    double changeX = 0, changeY = 0;
    private Circle c1, c2, c3, c4, c5, c6, c7, circleone;
    private int circlex = 10, circley = 0; // makes initial starting point of circles 0
    private int newCirclex = 0, newCircley = 0;
    private javax.swing.Timer timer2;
    private Random num = new Random();
    private int s = num.nextInt(8);

    public keyExample() {

        t.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        Random num = new Random();
        Random colors = new Random();

        Color color1 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        Color color2 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        Color color3 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        Color color4 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        Color color5 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        Color color6 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        Color color7 = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));

        int radius1 = num.nextInt(40);
        int radius2 = num.nextInt(20);
        int radius3 = num.nextInt(25);
        int radius4 = num.nextInt(45);
        int radius5 = num.nextInt(15);
        int radius6 = num.nextInt(40);
        int radius7 = num.nextInt(50);

        if (radius1 < 5) {
            radius1 = 10;
        } else if (radius2 < 5) {
            radius2 = 10;
        } else if (radius3 < 5) {
            radius3 = 10;
        } else if (radius4 < 5) {
            radius4 = 10;
        } else if (radius5 < 5) {
            radius5 = 10;
        } else if (radius6 < 5) {
            radius6 = 10;
        } else if (radius7 < 5) {
            radius7 = 10;
        } else {
        }
        c1 = new Circle(circlex, circley, radius1, color1);
        c2 = new Circle(circlex + 70, circley, radius2, color2);
        c3 = new Circle(circlex + 150, circley, radius3, color3);
        c4 = new Circle(circlex + 220, circley, radius4, color4);
        c5 = new Circle(circlex + 270, circley, radius5, color5);
        c6 = new Circle(circlex + 340, circley, radius6, color6);
        c7 = new Circle(circley + 410, circley, radius7, color7);

        circles[0] = c1;
        circles[1] = c2;
        circles[2] = c3;
        circles[3] = c4;
        circles[4] = c5;
        circles[5] = c6;
        circles[6] = c7;

        timer2 = new javax.swing.Timer(33, new MoveListener());
        timer2.start();

    }

    public void NewCircle() {
        for (int i = 0; i < circles.length; i++) {
            Random num = new Random();
            Random colors = new Random();
            Color color = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
            int radius = num.nextInt(40);
            if (radius < 5) {
                radius = radius + 10;
            } else {
            }
            circles[i] = new Circle(circlex, circley, radius, color);

        }

    }

    public void replaceCircle() {
        int height = getHeight();
        newCircley = newCircley + s;
        circley = newCircley;
        Random num = new Random();
        int radius = num.nextInt(34);
        Random colors = new Random();
        Color color = new Color(colors.nextInt(256), colors.nextInt(256), colors.nextInt(256));
        if (circley > height) {
            c1 = new Circle(10, 0, radius, color);
        } else {
        }

    }

    public void createCircle() {

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLUE);
        g2.fill(new Rectangle2D.Double(x, y, 40, 40));
        for (int i = 0; i < circles.length; i++) {
            circles[i].fill(g);
        }

    }

    public void actionPerformed(ActionEvent e) {
        repaint();
        x += changeX;
        y += changeY;
        changeX = 0;
        changeY = 0;

    }

    public void up() {
        if (y != 0) {
            changeY = -3.5;
            changeX = 0;
        }
    }

    public void down() {
        if (y <= 350) {
            changeY = 3.5;
            changeX = 0;

        }
    }

    public void left() {
        if (x >= 0) {
            changeX = -3.5;
            changeY = 0;
        }
    }

    public void right() {
        if (x <= 550) {
            changeX = 3.5;
            changeY = 0;
        }
    }

    private class MoveListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            Random speed = new Random();

            int s2 = speed.nextInt(12);
            int s3 = speed.nextInt(4);
            int s4 = speed.nextInt(20);
            int s5 = speed.nextInt(7);
            int s6 = speed.nextInt(5);
            int s7 = speed.nextInt(8);

            c1.move(0, s);
            c2.move(0, s2);
            c3.move(0, s3);
            c4.move(0, s4);
            c5.move(0, s5);
            c6.move(0, s6);
            c7.move(0, s7);

            repaint();

        }
    }

    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP) {
            up();
        }
        if (code == KeyEvent.VK_DOWN) {
            down();
        }
        if (code == KeyEvent.VK_RIGHT) {
            right();
        }
        if (code == KeyEvent.VK_LEFT) {
            left();

        }
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public static void main(String[] args) {
        new keyExample();
    }
}

圆圈类

import java.awt.*;

公共班圈{

    private int centerX, centerY, radius, coord;
    private Color color;

    public Circle(int x, int y, int r, Color c) {
        centerX = x;
        centerY = y;
        radius = r;
        color = c;

    }

    public void draw(Graphics g) {
        Color oldColor = g.getColor();
        g.setColor(color);
        g.drawOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
        g.setColor(oldColor);

    }

    public void fill(Graphics g) {
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
        g.setColor(oldColor);
    }

    public boolean containsPoint(int x, int y) {
        int xSquared = (x - centerX) * (x - centerX);
        int ySquared = (y - centerY) * (y - centerY);
        int RadiusSquared = radius * radius;
        return xSquared + ySquared - RadiusSquared <= 0;
    }

    public void move(int xAmount, int yAmount) {
        centerX = centerX + xAmount;
        centerY = centerY + yAmount;
    }

}

1 个答案:

答案 0 :(得分:2)

更好的解决方案是为Circle提供一些方法来确定当它移出界限时它应该做什么,但是,代码是如此复杂,我用它代替...

首先在您的getBounds课程中添加Circle方法......

public Rectangle getBounds() {
    int x = centerX - radius;
    int y = centerY - radius;
    return new Rectangle(x, y, radius * 2, radius * 2);
}

这将提供有关圆圈大小和位置的信息......

接下来,在MoveListener中,添加checkBounds方法...

public void checkBounds(Circle circle) {
    int height = getHeight();
    Rectangle bounds = circle.getBounds();

    if (bounds.y + bounds.height > height) {
        circle.move(0, -(height) + bounds.height);
    }
}

这将用于确定给定的Circle是否超出了可视区域的界限......

接下来,在您的MoveListener的{​​{1}}方法中,检查每个圈子......

actionPerformed

如此......

更新了快速而快速的示例

所以,这是我试图获得的快速而快速的例子......

Drop Circles

这使用c1.move(0, s); checkBounds(c1); 作为ArrayList的主要容器,但更改它以使用数组并不需要太多(实际上,某些部分会变得更容易)......

Circles

基本上发生的事情是,当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<Circle> circles; private Random rnd = new Random(); public TestPane() { circles = new ArrayList<>(MAX_CIRCLES); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { while (circles.size() < MAX_CIRCLES) { circles.add(createCircle()); } List<Circle> purge = new ArrayList<>(MAX_CIRCLES); for (Circle circle : circles) { Point p = circle.getLocation(); p.y += circle.getYDelta(); if (p.y > 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 > 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); } } } 离开可见区域时,它会从“列表”中删除,并在下一个勾号(Circle)中删除,新Timer创建是为了确保屏幕上总共有七个圆圈(或那里有)。

如果您要使用数组。你可以在当前Circle的索引位置的移动循环中创建一个新的Circle,有效地替换它......