[英]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
是否已超出可視區域的范圍...
接下來,在MoveListener
的actionPerformed
方法中,檢查每個圓圈......
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.