首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何控制线程(控制球速)?

如何控制线程(控制球速)?
EN

Stack Overflow用户
提问于 2021-11-22 02:16:21
回答 2查看 28关注 0票数 0

我有个问题。我在学java。在这段代码中,我想要减慢/加快我单击“更慢/更快”菜单按钮后创建的球。我的意思是,当我添加了球,当我添加的球在移动,然后我点击了慢或快按钮,正在移动的球具有相同的速度,而我点击按钮后创建的球,球的速度必须改变。

我在BallRunnable类中尝试了锁定和解锁方法,但它不起作用。你能给我一个建议吗?谢谢:)

代码语言:javascript
复制
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();
    }
}
EN

回答 2

Stack Overflow用户

发布于 2021-11-22 02:18:50

增加Thread.sleep()值(单位为毫秒)

票数 0
EN

Stack Overflow用户

发布于 2021-11-22 13:13:15

更改球的dx和/或dy (当满足特定条件时)。

如果我没记错,<dxdy>是球的速度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70060227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档