【问题标题】:Moving images/shape in a muti threading apps in Java在 Java 中的多线程应用程序中移动图像/形状
【发布时间】:2017-04-04 01:03:32
【问题描述】:

您好,我是 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");
                }
            }   
        }


    }

}    

【问题讨论】:

  • 首先要意识到,每次创建一个新球时,您也在创建一个新的 JFrame。这就是您运行 3 帧的原因。您的 gui 类违反了单一职责原则 - 它控制 GUI 并创建新球。我会创建一个 Gui 类,然后创建一个 ball 类。

标签: java multithreading image shape


【解决方案1】:

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

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,你真的拯救了我的一天。多谢! =)
猜你喜欢
  • 1970-01-01
  • 2016-06-10
  • 2011-12-20
  • 2016-02-21
  • 2012-05-29
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
相关资源
最近更新 更多