簡體   English   中英

如果它在JPanel上走得太遠,我怎么能再畫一個圓圈

[英]how can i draw a circle again if it goes too far on a JPanel

我正在嘗試制作一個以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;
    }

}

更好的解決方案是為Circle提供一些方法來確定當它移出界限時它應該做什么,但是,代碼是如此復雜,我用它代替......

首先在Circle類中添加一個getBounds方法......

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是否已超出可視區域的范圍...

接下來,在MoveListeneractionPerformed方法中,檢查每個圓圈......

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在當前的指數位置在運動循環Circle ,用途不同取代它...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM