gpt4 book ai didi

Java 弹跳球

转载 作者:太空狗 更新时间:2023-10-29 23:01:13 25 4
gpt4 key购买 nike

我正在尝试编写一个 Java 应用程序,它在屏幕上绘制多个球,这些球会从框架的边缘反弹。我可以成功抽到一个球。但是,当我添加第二个球时,它会覆盖我绘制的初始球。代码是:

import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

public class Ball extends JPanel implements Runnable {

List<Ball> balls = new ArrayList<Ball>();
Color color;
int diameter;
long delay;
private int x;
private int y;
private int vx;
private int vy;

public Ball(String ballcolor, int xvelocity, int yvelocity) {
if(ballcolor == "red") {
color = Color.red;
}
else if(ballcolor == "blue") {
color = Color.blue;
}
else if(ballcolor == "black") {
color = Color.black;
}
else if(ballcolor == "cyan") {
color = Color.cyan;
}
else if(ballcolor == "darkGray") {
color = Color.darkGray;
}
else if(ballcolor == "gray") {
color = Color.gray;
}
else if(ballcolor == "green") {
color = Color.green;
}
else if(ballcolor == "yellow") {
color = Color.yellow;
}
else if(ballcolor == "lightGray") {
color = Color.lightGray;
}
else if(ballcolor == "magenta") {
color = Color.magenta;
}
else if(ballcolor == "orange") {
color = Color.orange;
}
else if(ballcolor == "pink") {
color = Color.pink;
}
else if(ballcolor == "white") {
color = Color.white;
}
diameter = 30;
delay = 40;
x = 1;
y = 1;
vx = xvelocity;
vy = yvelocity;
}

protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(color);
g.fillOval(x,y,30,30); //adds color to circle
g.setColor(Color.black);
g2.drawOval(x,y,30,30); //draws circle
}

public void run() {
while(isVisible()) {
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
System.out.println("interrupted");
}
move();
repaint();
}
}

public void move() {
if(x + vx < 0 || x + diameter + vx > getWidth()) {
vx *= -1;
}
if(y + vy < 0 || y + diameter + vy > getHeight()) {
vy *= -1;
}
x += vx;
y += vy;
}

private void start() {
while(!isVisible()) {
try {
Thread.sleep(25);
} catch(InterruptedException e) {
System.exit(1);
}
}
Thread thread = new Thread(this);
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
}

public static void main(String[] args) {
Ball ball1 = new Ball("red",3,2);
Ball ball2 = new Ball("blue",6,2);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(ball1);
f.getContentPane().add(ball2);
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
new Thread(ball1).start();
new Thread(ball2).start();
}
}

我想创建一个球列表,然后循环绘制每个球,但我仍然无法将两个球添加到内容 Pane 。

感谢您的帮助。

最佳答案

根据您当前的方法...

  • 我能看到的主要问题是您将两个不透明组件放在彼此之上...实际上您可能会发现您正在绕过其中一个组件...
  • 您应该使用 null 布局管理器,否则它将接管并按照它认为合适的方式布局您的球。
  • 您需要确保控制球形 Pane 的大小和位置。这意味着您已经接管了布局管理器的角色...
  • 您需要随机化球的速度和位置,以减少它们从同一位置开始并移动到同一位置的机会...
  • 仅在 EDT 的上下文中更新 Ball
  • 您实际上并不需要 X/Y 值,您可以使用面板。

.

public class AnimatedBalls {

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

public AnimatedBalls() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Balls());
frame.setSize(400, 400);
frame.setVisible(true);
}
});
}

public class Balls extends JPanel {

public Balls() {
setLayout(null);
// Randomize the speed and direction...
add(new Ball("red", 10 - (int) Math.round((Math.random() * 20)), 10 - (int) Math.round((Math.random() * 20))));
add(new Ball("blue", 10 - (int) Math.round((Math.random() * 20)), 10 - (int) Math.round((Math.random() * 20))));
}
}

public class Ball extends JPanel implements Runnable {

Color color;
int diameter;
long delay;
private int vx;
private int vy;

public Ball(String ballcolor, int xvelocity, int yvelocity) {
if (ballcolor == "red") {
color = Color.red;
} else if (ballcolor == "blue") {
color = Color.blue;
} else if (ballcolor == "black") {
color = Color.black;
} else if (ballcolor == "cyan") {
color = Color.cyan;
} else if (ballcolor == "darkGray") {
color = Color.darkGray;
} else if (ballcolor == "gray") {
color = Color.gray;
} else if (ballcolor == "green") {
color = Color.green;
} else if (ballcolor == "yellow") {
color = Color.yellow;
} else if (ballcolor == "lightGray") {
color = Color.lightGray;
} else if (ballcolor == "magenta") {
color = Color.magenta;
} else if (ballcolor == "orange") {
color = Color.orange;
} else if (ballcolor == "pink") {
color = Color.pink;
} else if (ballcolor == "white") {
color = Color.white;
}
diameter = 30;
delay = 100;

vx = xvelocity;
vy = yvelocity;

new Thread(this).start();

}

protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;

int x = getX();
int y = getY();

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(color);
g.fillOval(0, 0, 30, 30); //adds color to circle
g.setColor(Color.black);
g2.drawOval(0, 0, 30, 30); //draws circle
}

@Override
public Dimension getPreferredSize() {
return new Dimension(30, 30);
}

public void run() {

try {
// Randamize the location...
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
int x = (int) (Math.round(Math.random() * getParent().getWidth()));
int y = (int) (Math.round(Math.random() * getParent().getHeight()));

setLocation(x, y);
}
});
} catch (InterruptedException exp) {
exp.printStackTrace();
} catch (InvocationTargetException exp) {
exp.printStackTrace();
}

while (isVisible()) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
System.out.println("interrupted");
}

try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
move();
repaint();
}
});
} catch (InterruptedException exp) {
exp.printStackTrace();
} catch (InvocationTargetException exp) {
exp.printStackTrace();
}
}
}

public void move() {

int x = getX();
int y = getY();

if (x + vx < 0 || x + diameter + vx > getParent().getWidth()) {
vx *= -1;
}
if (y + vy < 0 || y + diameter + vy > getParent().getHeight()) {
vy *= -1;
}
x += vx;
y += vy;

// Update the size and location...
setSize(getPreferredSize());
setLocation(x, y);

}
}
}

这种方法的“主要”问题是每个 Ball 都有自己的 Thread。当你增加球的数量时,这将很快消耗你的系统资源......

不同的方法

从 Hovercraft 开始,您最好为球创建一个容器,其中球不是组件,而是球的“虚拟”概念,包含足够的信息,可以将它们弹开墙壁……

enter image description here

public class SimpleBalls {

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

public SimpleBalls() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame("Spot");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
Balls balls = new Balls();
frame.add(balls);
frame.setSize(400, 400);
frame.setVisible(true);

new Thread(new BounceEngine(balls)).start();

}
});
}

public static int random(int maxRange) {
return (int) Math.round((Math.random() * maxRange));
}

public class Balls extends JPanel {

private List<Ball> ballsUp;

public Balls() {
ballsUp = new ArrayList<Ball>(25);

for (int index = 0; index < 10 + random(90); index++) {
ballsUp.add(new Ball(new Color(random(255), random(255), random(255))));
}
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Ball ball : ballsUp) {
ball.paint(g2d);
}
g2d.dispose();
}

public List<Ball> getBalls() {
return ballsUp;
}
}

public class BounceEngine implements Runnable {

private Balls parent;

public BounceEngine(Balls parent) {
this.parent = parent;
}

@Override
public void run() {

int width = getParent().getWidth();
int height = getParent().getHeight();

// Randomize the starting position...
for (Ball ball : getParent().getBalls()) {
int x = random(width);
int y = random(height);

Dimension size = ball.getSize();

if (x + size.width > width) {
x = width - size.width;
}
if (y + size.height > height) {
y = height - size.height;
}

ball.setLocation(new Point(x, y));

}

while (getParent().isVisible()) {

// Repaint the balls pen...
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getParent().repaint();
}
});

// This is a little dangrous, as it's possible
// for a repaint to occur while we're updating...
for (Ball ball : getParent().getBalls()) {
move(ball);
}

// Some small delay...
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}

}

}

public Balls getParent() {
return parent;
}

public void move(Ball ball) {

Point p = ball.getLocation();
Point speed = ball.getSpeed();
Dimension size = ball.getSize();

int vx = speed.x;
int vy = speed.y;

int x = p.x;
int y = p.y;

if (x + vx < 0 || x + size.width + vx > getParent().getWidth()) {
vx *= -1;
}
if (y + vy < 0 || y + size.height + vy > getParent().getHeight()) {
vy *= -1;
}
x += vx;
y += vy;

ball.setSpeed(new Point(vx, vy));
ball.setLocation(new Point(x, y));

}
}

public class Ball {

private Color color;
private Point location;
private Dimension size;
private Point speed;

public Ball(Color color) {

setColor(color);

speed = new Point(10 - random(20), 10 - random(20));
size = new Dimension(30, 30);

}

public Dimension getSize() {
return size;
}

public void setColor(Color color) {
this.color = color;
}

public void setLocation(Point location) {
this.location = location;
}

public Color getColor() {
return color;
}

public Point getLocation() {
return location;
}

public Point getSpeed() {
return speed;
}

public void setSpeed(Point speed) {
this.speed = speed;
}

protected void paint(Graphics2D g2d) {

Point p = getLocation();
if (p != null) {
g2d.setColor(getColor());
Dimension size = getSize();
g2d.fillOval(p.x, p.y, size.width, size.height);
}

}
}
}

因为这是由单线程驱动的,所以它的可扩展性要高得多。

您还可以查看 the images are not loading这是一个类似的问题;)

关于Java 弹跳球,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13022754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com