Java中多线程程序中弹跳球的图形
我正在尝试调整我为在Java弹跳的程序而创建的程序。如果解决方案是显而易见的,我很抱歉。我使用以下代码创建了一系列弹跳球,然后随后创建了两个螺纹,而球弹跳。
我试图在没有数组的情况下实现这一目标。因此,每个线程只有1个球。 我觉得答案是盯着我的脸,但我无法解决问题。任何帮助将不胜感激。
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AClass implements Runnable {
private JFrame mainFrame;
private DrawPanel drawPanel;
// private java.util.List<Ball> balls;
private int windowWidth = 640;
private int windowHeight = 480;
private String windowLabel = "Multi-threaded ball application";
public void run() {
//balls = new ArrayList<>();
//Scanner sc = new Scanner(System.in);
//System.out.print("Enter the number of balls you would like to create:");
//int n = sc.nextInt();
//sc.close();
/* Generate balls */
//for (int i = 0; i < n; i++) {
Ball ball = new Ball(
/* Random positions from 0 to windowWidth or windowHeight */
(int) Math.floor(Math.random() * windowWidth),
(int) Math.floor(Math.random() * windowHeight),
/* Random size from 10 to 30 */
(int) Math.floor(Math.random() * 20) + 10,
/* Random RGB colors*/
new Color(
(int) Math.floor((Math.random() * 256)),
(int) Math.floor((Math.random() * 256)),
(int) Math.floor((Math.random() * 256))
),
/* Random velocities from -5 to 5 */
(int) Math.floor((Math.random() * 10) - 5),
(int) Math.floor((Math.random() * 10) - 5)
);
// balls.add(ball);
// }
/* Initialize program */
mainFrame = new JFrame();
drawPanel = new DrawPanel();
mainFrame.getContentPane().add(drawPanel);
mainFrame.setTitle(windowLabel);
mainFrame.setSize(windowWidth, windowHeight);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
//for (Ball b: balls) {
ball.update();
// }
/* Give Swing 10 milliseconds to see the update! */
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
mainFrame.repaint();
}
}
public class DrawPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
// for (Ball b: balls) {
ball.draw(graphics);
// }
}
}
class Ball {//ball class
private int posX, posY, size;
private Color color;
private int vx = 5;
private int vy = 5;
public Ball(int posX, int posY, int size, Color color, int vx, int vy) {
this.posX = posX;
this.posY = posY;
this.size = size;
this.color = color;
this.vx = vx;
this.vy = vy;
}
void update() {
if (posX > mainFrame.getWidth() || posX < 0) {
vx *= -1;
}
if (posY > mainFrame.getHeight() || posY < 0) {
vy *= -1;
}
if (posX > mainFrame.getWidth()) {
posX = mainFrame.getWidth();
}
if (posX < 0) {
posX = 0;
}
if (posY > mainFrame.getHeight()) {
posY = mainFrame.getHeight();
}
if (posY < 0) {
posY = 0;
}
this.posX += vx;
this.posY += vy;
}
void draw(Graphics g) {
g.setColor(color);
g.fillOval(posX, posY, size, size);
}
}
public static void main(String[] args) {
AClass ex = new AClass();
Thread t1= new Thread(ex);
Thread t2 = new Thread(ex);
t1.start();
t2.start();
//System.out.println("Hi");
}
}
I am trying to adapt a program I have created for bouncing a ball in Java. I am very new so apologies if the solution is obvious. I have used the following code to create an array of bouncing balls, and then subsequently create two threads with the balls bouncing.
I am trying to achieve this without the array. So, that each thread has only 1 ball.
I feel like the answer is staring me in the face but I just cannot solve the issue. Any help would be greatly appreciated.
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AClass implements Runnable {
private JFrame mainFrame;
private DrawPanel drawPanel;
// private java.util.List<Ball> balls;
private int windowWidth = 640;
private int windowHeight = 480;
private String windowLabel = "Multi-threaded ball application";
public void run() {
//balls = new ArrayList<>();
//Scanner sc = new Scanner(System.in);
//System.out.print("Enter the number of balls you would like to create:");
//int n = sc.nextInt();
//sc.close();
/* Generate balls */
//for (int i = 0; i < n; i++) {
Ball ball = new Ball(
/* Random positions from 0 to windowWidth or windowHeight */
(int) Math.floor(Math.random() * windowWidth),
(int) Math.floor(Math.random() * windowHeight),
/* Random size from 10 to 30 */
(int) Math.floor(Math.random() * 20) + 10,
/* Random RGB colors*/
new Color(
(int) Math.floor((Math.random() * 256)),
(int) Math.floor((Math.random() * 256)),
(int) Math.floor((Math.random() * 256))
),
/* Random velocities from -5 to 5 */
(int) Math.floor((Math.random() * 10) - 5),
(int) Math.floor((Math.random() * 10) - 5)
);
// balls.add(ball);
// }
/* Initialize program */
mainFrame = new JFrame();
drawPanel = new DrawPanel();
mainFrame.getContentPane().add(drawPanel);
mainFrame.setTitle(windowLabel);
mainFrame.setSize(windowWidth, windowHeight);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
//for (Ball b: balls) {
ball.update();
// }
/* Give Swing 10 milliseconds to see the update! */
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
mainFrame.repaint();
}
}
public class DrawPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
// for (Ball b: balls) {
ball.draw(graphics);
// }
}
}
class Ball {//ball class
private int posX, posY, size;
private Color color;
private int vx = 5;
private int vy = 5;
public Ball(int posX, int posY, int size, Color color, int vx, int vy) {
this.posX = posX;
this.posY = posY;
this.size = size;
this.color = color;
this.vx = vx;
this.vy = vy;
}
void update() {
if (posX > mainFrame.getWidth() || posX < 0) {
vx *= -1;
}
if (posY > mainFrame.getHeight() || posY < 0) {
vy *= -1;
}
if (posX > mainFrame.getWidth()) {
posX = mainFrame.getWidth();
}
if (posX < 0) {
posX = 0;
}
if (posY > mainFrame.getHeight()) {
posY = mainFrame.getHeight();
}
if (posY < 0) {
posY = 0;
}
this.posX += vx;
this.posY += vy;
}
void draw(Graphics g) {
g.setColor(color);
g.fillOval(posX, posY, size, size);
}
}
public static void main(String[] args) {
AClass ex = new AClass();
Thread t1= new Thread(ex);
Thread t2 = new Thread(ex);
t1.start();
t2.start();
//System.out.println("Hi");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,秋千不是线程安全。您不应从事件派遣线程的上下文之外更新UI(或UI所依赖的任何状态)。
参见 Swing 同意的同意。
我认为您的意图不是正确的方法(试图让每个球都是自己的
线程
),您将迅速遇到各种试图进行碰撞检测的问题每个球的状态总是彼此独立,它的缩放效果不佳。数组和秋千计时器
将是一个更合适的解决方案。这可能是我可以接近您想要的东西的问题,问题是,为了绘画,您需要参考
ball
,所以我扩展了ball 来自
JPANEL
而不是。这种方法的问题(甚至
螺纹
ed方法)是,它的扩展不是很好。例如,在我的实验中,在我开始遇到响应性问题之前,我只有大约5,000个球(调整窗口滞后的大小),而使用arraylist
(和大约20,000球)(和大约20,000球)一个单个计时器
) - 老实说,帧速率很糟糕,但是UI保持相对响应 - 我可以调整窗口大小,而无需滞后timer
,基于数组>例子...First, Swing is not thread safe. You should not be updating the UI (or any state the UI relies on) from outside the context of the Event Dispatching Thread.
See Concurrency in Swing for more details.
I don't think your intention is the correct approach (trying to have each ball be it's own
Thread
), you're going to quickly end up with all sorts of issues trying to do collision detection, as the state of each ball is always changing independent of each other and it won't scale well. The array and a SwingTimer
would be a more suitable solution.This is the probably the closes I can get to what you want, the problem is, in order to paint it, you'd need a reference to the
Ball
, so I extendedBall
fromJPanel
instead.The problem with this approach (and even the
Thread
ed approach) is, it's not going to scale well. For example, during my experimentation, I only got to about 5, 000 balls before I started have responsiveness issues (resizing the window lagged, alot), compared to roughly 20, 000 balls using anArrayList
(and a singleTimer
) - I'll be honest, the frame rate was terrible, but the UI remained relatively responsive - I could resize the window without lagSingle
Timer
, array based example...