我正在尝试制作一个以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;
}
}
答案 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
如此......
更新了快速而快速的示例
所以,这是我试图获得的快速而快速的例子......
这使用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
,有效地替换它......