我有个问题。我在学java。在这段代码中,我想要减慢/加快我单击“更慢/更快”菜单按钮后创建的球。我的意思是,当我添加了球,当我添加的球在移动,然后我点击了慢或快按钮,正在移动的球具有相同的速度,而我点击按钮后创建的球,球的速度必须改变。
我在BallRunnable类中尝试了锁定和解锁方法,但它不起作用。你能给我一个建议吗?谢谢:)
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
import java.util.List;
import java.util.concurrent.locks.*;
public class BallBounce {
public static void main(String[] args) {
JFrame frame = new BounceFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
/**
A runnable that animates a bouncing ball.
*/
class BallRunnable implements Runnable {
public BallRunnable(Ball aBall, JPanel ballPanel) {
ball = aBall; this.ballPanel = ballPanel;
ballLock = new ReentrantLock();
}
public void run() {
ballLock.lock();
try {
for (int i = 1; i <= STEPS; i++) {
ball.move(ballPanel.getBounds()); // update the location of the ball
ballPanel.paint(ballPanel.getGraphics());
Thread.sleep((long)(DELAY * change));
}
} catch (InterruptedException e) { System.out.println("what"); }
finally { ballLock.unlock(); }
}
public static void print() { System.out.println(DELAY * change); }
public static void setdoublechange() {
change = change * 2;
}
public static void sethalfchange() {
change = change / 2;
}
private Ball ball;
private JPanel ballPanel;
public static final int STEPS = 1000;
public static final int DELAY = 3;
private static double change = 1;
private static Lock ballLock;
}
class BallRunnable2 implements Runnable {
public BallRunnable2(Ball aBall, JPanel ballPanel) {
ball = aBall; this.ballPanel = ballPanel;
}
public void run() {
ballLock.lock();
try {
Thread.sleep(100);
for (int i = 1; i <= STEPS; i++) {
ball.move(ballPanel.getBounds()); // update the location of the ball
ballPanel.paint(ballPanel.getGraphics());
Thread.sleep(DELAY * change);
}
} catch (InterruptedException e) { }
finally { ballLock.unlock(); }
}
public static void setdoublechange() {
change = change * 2;
}
public static void sethalfchange() {
change = change / 2;
}
private Ball ball;
private JPanel ballPanel;
public static final int STEPS = 1000;
public static final int DELAY = 3;
public static int change = 1;
private Lock ballLock;
}
/**
A ball that moves and bounces off the edges of a rectangle
*/
class Ball {
/**
Moves the ball to the next position, reversing direction if it hits one of the edges
*/
public void move(Rectangle2D bounds) { // java.awt.geom.Rectangle2D
x += dx; y += dy;
if (x < bounds.getMinX()) { x = bounds.getMinX(); dx = -dx; }
if (x + XSIZE >= bounds.getMaxX()) { x = bounds.getMaxX() - XSIZE; dx= -dx; }
if (y < bounds.getMinY()) { y = bounds.getMinY(); dy = -dy; }
if (y + YSIZE >= bounds.getMaxY()) { y = bounds.getMaxY() - YSIZE; dy = -dy; }
}
/**
Gets the shape of the ball at its current position.
*/
public Ellipse2D getShape() { return new Ellipse2D.Double(x, y, XSIZE, YSIZE); }
private static final int XSIZE = 15;
private static final int YSIZE = 15;
private double x = 0;
private double y = 0;
private double dx = 1;
private double dy = 1;
}
/**
The panel that draws the balls.
*/
class BallPanel extends JPanel {
/**
Add a ball to the panel.
@param b the ball to add
*/
public void add(Ball b) {
balls.add(b);
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Ball b : balls) { g2.fill(b.getShape()); }
}
private List<Ball> balls = new ArrayList<>();
}
class BounceFrame extends JFrame {
public BounceFrame() {
setTitle("BounceThread");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
ballPanel = new BallPanel(); add(ballPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
addButton(buttonPanel, "Add 1", new ActionListener() {
public void actionPerformed(ActionEvent event) { addBall1(); }
});
addButton(buttonPanel, "Add 2", new ActionListener() {
public void actionPerformed(ActionEvent event) { addBall2(); }
});
addButton(buttonPanel, "Close", new ActionListener() {
public void actionPerformed(ActionEvent event) { System.exit(0); }
});
// addButton(buttonPanel, "Close", (ActionEvent event) -> System.exit(0));
add(buttonPanel, BorderLayout.SOUTH);
JMenu speedMenu = new JMenu("Speed");
JMenuItem fasterItem = speedMenu.add(new fasterAction("Faster"));
JMenuItem slowerItem = speedMenu.add(new slowerAction("Slower"));
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
menuBar.add(speedMenu);
}
private void addButton(Container container, String title, ActionListener listener) {
JButton button = new JButton(title);
container.add(button);
button.addActionListener(listener);
}
/**
Adds a bouncing ball to the canvas and starts a thread to make it bounce
*/
public void addBall1() {
Ball b = new Ball();
ballPanel.add(b);
Runnable r = new BallRunnable(b, ballPanel);
Thread t = new Thread(r);
t.start();
}
public void addBall2() {
Ball b1 = new Ball();
Ball b2 = new Ball();
ballPanel.add(b1);
ballPanel.add(b2);
Runnable r1 = new BallRunnable(b1, ballPanel);
Runnable r2 = new BallRunnable2(b2, ballPanel);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
private BallPanel ballPanel;
public static final int DEFAULT_WIDTH = 450;
public static final int DEFAULT_HEIGHT = 350;
}
class fasterAction extends AbstractAction {
public fasterAction(String name) { super(name); }
public void actionPerformed(ActionEvent event) {
BallRunnable.sethalfchange();
BallRunnable2.sethalfchange();
}
}
class slowerAction extends AbstractAction {
public slowerAction(String name) { super(name); }
public void actionPerformed(ActionEvent event) {
BallRunnable.setdoublechange();
BallRunnable2.setdoublechange();
}
}发布于 2021-11-22 02:18:50
增加Thread.sleep()值(单位为毫秒)
发布于 2021-11-22 13:13:15
更改球的dx和/或dy (当满足特定条件时)。
如果我没记错,<dx,dy>是球的速度。
https://stackoverflow.com/questions/70060227
复制相似问题