Java弹跳球。每次制作新线程时,为什么球的速度加倍?

时间:2015-11-20 17:46:10

标签: java multithreading

我想制作一个Java弹跳球程序,可以通过单击“开始按钮”添加多个球。每个球都在自己的线程中,这意味着10个球实例= 10个线程! 但是当我尝试这样做时,每次制作一个新线程时,球的速度都会翻倍。

我的问题: 1.为什么速度加倍? 2.如何让每个球在一个单独的线程(10个球,10个线程)中运行

    package test3;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test2 extends JFrame{
    int width = 1000;
    int height = 500;
    BallPanel ballPanel = new BallPanel();

    public Test2() {
        setLayout(new FlowLayout(FlowLayout.CENTER, 0, 10));
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));

        JButton start = new JButton("Start");
        start.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                ballPanel.start();
            }
        });
        buttonPanel.add(start);

        add(buttonPanel);
        add(ballPanel);
        ini();
    }

    private void ini(){
        setTitle("Test");
        setSize(width, height);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    class BallPanel extends JPanel implements Runnable{
        int panelWidth = 900;
        int panelHeight = 370;
        ArrayList<Ball> ball = new ArrayList<Ball>();

         public BallPanel() {
            setBackground(Color.WHITE);
            setPreferredSize(new Dimension(panelWidth, panelHeight));
        }

        public void start(){
            if (ball.size() < 10) {
                ball.add(new Ball());
            }

            new Thread(this).start();
        }

        public synchronized ArrayList<Ball> movement(ArrayList<Ball> ball){
            for (int i = 0; i < ball.size(); i++) {
                if (ball.get(i).getCurrentX() < 0 || ball.get(i).getCurrentX() > panelWidth - 10) {
                    ball.get(i).setIncrementX(ball.get(i).getIncrementX() * -1);
                } else if (ball.get(i).getCurrentY() < 0 || ball.get(i).getCurrentY() > panelHeight - 10) {
                    ball.get(i).setIncrementY(ball.get(i).getIncrementY() * -1);
                }

                ball.get(i).setCurrentX(ball.get(i).getCurrentX() + ball.get(i).getIncrementX());
                ball.get(i).setCurrentY(ball.get(i).getCurrentY() + ball.get(i).getIncrementY());
            }
            return ball;
        }


        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (ball != null) {
                for (int i = 0; i < ball.size(); i++) {
                    g.setColor(ball.get(i).color);
                    g.fillOval(ball.get(i).getCurrentX(), ball.get(i).getCurrentY(), ball.get(i).getRadius(), ball.get(i).getRadius());
                } 
            }
        }

        @Override
        public void run() {
            while (true) {
                movement(ball);
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {}

                repaint();

            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test2();
            }
        });
    }

}

球类

package test3;

import java.awt.Color;

public class Ball {
    int currentX;
    int currentY;
    int incrementX;
    int incrementY;
    int radius;
    Color color;



    public Ball() {
        this.currentX = 7;
        this.currentY = 0;
        this.incrementX = 1;
        this.incrementY = 1;
        this.radius = 10;
        this.color = Color.red;
    }

    public int getRadius() {
        return radius;
    }

    public int getIncrementX() {
        return incrementX;
    }

    public void setIncrementX(int incrementX) {
        this.incrementX = incrementX;
    }

    public int getIncrementY() {
        return incrementY;
    }

    public void setIncrementY(int incrementY) {
        this.incrementY = incrementY;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    public int getCurrentX() {
        return currentX;
    }

    public void setCurrentX(int currentX) {
        this.currentX = currentX;
    }

    public int getCurrentY() {
        return currentY;
    }

    public void setCurrentY(int currentY) {
        this.currentY = currentY;
    }

    public Color getColor() {
        return color;
    }

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

1 个答案:

答案 0 :(得分:1)

stop()正在设置app = null并中断线程,但是在run()方法中吞下了InterruptedException,因此线程一直在运行。然后当再次运行start()时,会创建另一个Thread,这会导致两个线程调用moving()方法,使移动速度加倍。