java - 在 Java 的多线程应用程序中移动图像/形状

标签 java multithreading image shapes

大家好,我是 StackOverflow 和 Java 编程的新手。我目前有一个需要多线程的学校项目,我只需要您关于如何修复我的代码的建议。我花了太多时间寻找如何使用线程创建移动的多个图像的答案。我知道我快要找到解决方案了,但由于提交即将临近,我的时间已经不多了。我相信,如果我向更了解 Java 的人寻求帮助,我会更有效率。

提前非常感谢。

下面是我当前的代码,看起来图像在移动时闪烁。

// Bounce.java

import javax.swing.JFrame;
public class Bounce {

    public static void main(String args[]) {
        myBall s = new myBall(10, 20, 2, 2);
        myBall s1 = new myBall(100, 10, 2, 2);
        myBall s2 = new myBall(40, 10, 2, 2);
        JFrame f = new JFrame();
        f.add(s);
        f.add(s1);
        f.add(s2);
        f.setVisible(true);
        f.setSize(600, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Moving Ball");
    }   
}

下一个代码位于单独的文件中。

// myBall.java

import java.awt.*;
import java.awt.geom.Ellipse2D;    
import javax.swing.*;

public class myBall extends JPanel implements Runnable {
    private Thread animator;
    int x = 0, y = 0, velX = 2, velY = 2;
    Timer t;

    public myBall(int x, int y, int velX, int velY) {
        JFrame jf = new JFrame();
        jf.setSize(600,400);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(this);
        jf.setVisible(true);

        this.x = (int )(Math.random() * 560);
        this.y = (int )(Math.random() * 360);
        this.velX = velX;
        this.velY = velY;
    }

    @Override
    public void addNotify() {
        super.addNotify();
        animator = new Thread(this);
        animator.start();

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
        g2.fill(ellipse);       
    }

    public void cycle() {
        if(x < 0 || x > 560) {
            velX = -velX;
        }
        if(y < 0 || y > 360) {
            velY = -velY;
        }
        x += velX;
        y += velY;
        System.out.println(x);
    }

    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 600; i++) {
                cycle();
                repaint();

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


    }

}    

最佳答案

给你。我通常不会这样做,但你问得很好,而且你的代码也很干净,所以我认为你在这方面做了很多工作。

public class Start {

    public static void main(String args[]) {
        JFrame f = new JFrame();
        Gui gui = new Gui();
        gui.addBalls();
        f.add(gui);

        f.setSize(600, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Moving Ball");
        f.setVisible(true);
    }   
}

类 GUI:

public class Gui extends JPanel implements Runnable {
    private Thread animator;
    int x = 0, y = 0, velX = 2, velY = 2;
    Timer t;

    ArrayList<myBall> myBalls = new ArrayList<>();

    @Override
    public void addNotify() {
        super.addNotify();
        animator = new Thread(this);
        animator.start();

    }

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

        for (myBall ball: myBalls) {
            int x = ball.getX();
            int y = ball.getY();
            Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
            g2.fill(ellipse); 
        }
    }

    public void cycle() {
        for (myBall ball: myBalls) {
            int x = ball.getX();
            int y = ball.getY();

            if(x < 0 || x > 560) {
                ball.reverseX();
            }
            if(y < 0 || y > 360) {
                ball.reverseY();
            }

            ball.move();
            System.out.println(x);
        }
    }

    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 600; i++) {
                cycle();
                repaint();

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

    public void addBalls() {
        for (int i = 0; i < 4; i++) {
            int x = (int )(Math.random() * 560);
            int y = (int )(Math.random() * 360);
            int velX = -5;
            int velY = 5;
            myBalls.add(new myBall(x, y, velX, velY));
        }
    }
}

类球:

public class myBall {

    int x;
    int y;
    int velX;
    int velY;


    public myBall(int x, int y, int velX, int velY) {
        this.x = (int )(Math.random() * 560);
        this.y = (int )(Math.random() * 360);
        this.velX = velX;
        this.velY = velY;
    }

    public void move() {
        x+=velX;
        y+=velY;

    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void reverseX() {
        velX = -velX;
    }

    public void reverseY() {
        velY = -velY;
    }
}

关于java - 在 Java 的多线程应用程序中移动图像/形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43196690/

相关文章:

java - 如何使用java在Oracle sql中存储目录结构

java - 将 POJO 列表转换为 Map<String,Set<String>>

java - 如何检查电脑是否已连接到互联网?

multithreading - 同时在多个线程上运行的 TIdHttp 的访问冲突

java - 使用什么事务管理器? (JPA, Spring )

python - 如何在 Python 中分析多线程程序的内存?

c++ - 加入和终止 Windows 线程

azure - 如何在不同区域使用Azure VM Image

c - 在C中显示颜色数组

html - 无法让照片在 div 中彼此相邻对齐