Java 在焰火程序中启动线程

Java 在焰火程序中启动线程,java,multithreading,swing,graphics,Java,Multithreading,Swing,Graphics,我正在编写一个小的焰火软件,在这个软件中,用户可以选择保险丝的颜色、爆炸时间、持续时间、大小和形式,添加其他保险丝,然后启动它们,从而创建一个新的框架,保险丝在给定的时间和持续时间内出现 我将问题分为不同的类,分别为sparks、Fusee和动画创建框架,用户可以在其中设置保险丝。它们中的每一个都有一个绘制功能:peindreEtincelle(图形g),然后是使用peindreEtincelle的peindreFusee(图形g),然后是使用peindreFusee的动画绘制。每个fuse都应

我正在编写一个小的焰火软件,在这个软件中,用户可以选择保险丝的颜色、爆炸时间、持续时间、大小和形式,添加其他保险丝,然后启动它们,从而创建一个新的框架,保险丝在给定的时间和持续时间内出现

我将问题分为不同的类,分别为sparks、Fusee和动画创建框架,用户可以在其中设置保险丝。它们中的每一个都有一个绘制功能:peindreEtincelle(图形g),然后是使用peindreEtincelle的peindreFusee(图形g),然后是使用peindreFusee的动画绘制。每个fuse都应该有自己的线程,这样我就可以控制何时停用它,我已经在测试类中测试了peindreFusee和peindreEtincelle,它们工作得很好。由于Fusee类中有一个线程,我编写了一个函数run(),该函数使用PEINDREFUESEE,如下所示:

类Fusee与run()对应的每个线程=每个保险丝:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.math.*;


public class Fusee implements Runnable {
  //ATTRIBUTES
  public int num, puissEtincelles, nbEtincelles;
  public double xf, yf, duree, tpsDepart ;
  public boolean active = true ;
  public String forme ;
  public Thread anim ;
  public Color couleur ;
  public static double DIV = 1%(Math.sqrt(2)) ;
  public LinkedList<Etincelle> liste;
  public Graphics g;

  //CONSTRUCTOR
  public Fusee(int numero){
    num = numero ;
    couleur = Color.red ;
    nbEtincelles = 1 + 8^puissEtincelles; 
    anim = new Thread(this) ; 
    liste = new LinkedList<Etincelle>() ; /
    liste.add(new Etincelle(xf,yf));  
    for (int k =1 ; k<=puissEtincelles ;k++){
        liste.add(new Etincelle(xf+10*k,yf));
        liste.add(new Etincelle(xf-10*k,yf));
        liste.add(new Etincelle(xf,yf+10*k));
        liste.add(new Etincelle(xf,yf-5*k));
        liste.add(new Etincelle(xf+10*k*DIV,yf+10*k*DIV));
        liste.add(new Etincelle(xf+10*k*DIV,yf-10*k*DIV));
        liste.add(new Etincelle(xf-10*k*DIV,yf+10*k*DIV));
        liste.add(new Etincelle(xf-10*k*DIV,yf-10*k*DIV));
    }
}

//METHODS
public void run(){
    while(active == true){
        if (tpsDepart == 0) {
          if (duree>0){ 
             duree = duree-0.01 ;
             peindreFusee(g);
          }
          else if (duree == 0){
             active = false ; 
          }
        }
        else if (tpsDepart >0){
            tpsDepart = tpsDepart - 0.01 ; 
        }
    }
    try {
        Thread.sleep(10);//pause d'un centième seconde
      }
      catch(InterruptedException e) {
        System.out.println(e);
      }
}
下面是peindreFusee()实际绘制内容的示例(这里是橙色圆点,形式和颜色由用户选择)

谁能告诉我我的代码有什么问题吗?这将非常有帮助

非常感谢:)

以下是测试程序所缺少的类:

该类细胞:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;


public class Etincelle {
//ATTRIBUTS
public Color couleur ;
public double duree, x, y ;
public String forme ;

//CONSTRUCTOR
public Etincelle(double a, double b) {
    x=a;
    y=b;
    forme = "croix";
    couleur=Color.red ;
}

//METHODES
public void peindreEtincelle(Graphics g) {
    g.setColor(couleur);
    if (forme == "croix") {
        g.drawLine((int)x-5, (int)y, (int)x+5, (int)y);
        g.drawLine((int)x, (int)y-5, (int)x, (int)y+5); 
    }
    else if (forme == "point"){
        g.fillOval((int)x, (int)y, 8, 8);
    }
    else if (forme=="etoile"){
        g.drawLine((int)x-5, (int)y, (int)x+5, (int)y);
        g.drawLine((int)x, (int)y-5, (int)x, (int)y+5); 
        g.drawLine((int)x-5, (int)y-5, (int)x+5, (int)y+5);//pose les points de l'étoile, qui ici ressemble plus à un carré car plus facile à coder et peu visible (petit)
        g.drawLine((int)x-5, (int)y+5, (int)x+5, (int)y-5); 
    }
}
}

ECOUTURPOURFERFENETRE类:

import java.awt.event.*;

public void windowClosing(WindowEvent w) {
w.getWindow().dispose() ;  
System.exit(0);  
}


}所以。。。我想这已经接近你想要的了(没有延迟…无法理解),很抱歉换了法语和英语:)

步骤1-定义可绘制的界面

public interface Drawable {
    void drawOn(Graphics g);
}
步骤2-定义一个实现此
可绘制的

public abstract class Etincelle implements Drawable {

    public double x, y;
    public Color couleur;

    public Etincelle(double x, double y, Color couleur) {
        this.x = x;
        this.y = y;
        this.couleur = couleur;
    }

    public Etincelle(double x, double y) {
        this(x, y, Color.red);
    }

    protected abstract void peindreEtincelle(Graphics g);

    @Override
    public void drawOn(Graphics g) {
        Color previous = g.getColor();

        g.setColor(couleur);
        peindreEtincelle(g);

        g.setColor(previous);
    }
}
步骤3定义Etincelle的扩展,这里我们做点forme

public class PointEtincelle extends Etincelle {

    public static final String FORME = "POINT";
    private int radius = 8;

    public PointEtincelle(double a, double b) {
        super(a, b);
    }

    public PointEtincelle(double x, double y, Color couleur) {
        super(x, y, couleur);
    }

    @Override
    protected void peindreEtincelle(Graphics g) {
        g.fillOval((int) x - radius / 2, (int) y - radius / 2, radius, radius);
    }
}
和Croix forme

public class CroixEtincelle extends Etincelle {

    public static final String FORME = "CROIX";

    public CroixEtincelle(double a, double b) {
        super(a, b);
    }

    public CroixEtincelle(double x, double y, Color couleur) {
        super(x, y, couleur);
    }

    @Override
    protected void peindreEtincelle(Graphics g) {
        g.drawLine((int) x - 5, (int) y, (int) x + 5, (int) y);
        g.drawLine((int) x, (int) y - 5, (int) x, (int) y + 5);
    }

}
我也有一个用于埃托维尔forme的,但我想你明白了

步骤4-定义一个Fusee,在这里,它只是一个非常大的Etincelle,因此我们将这样定义它。这可能是最复杂的类,但我做了一些反射魔法,以从字符串值“CROIX”和“POINT”中获得不同的形式。这将让你以后很容易地添加不同的表单。注释掉的部分“工作”。。。你可以随意取消它们的注释,但它们基本上是通过在它们上面重新绘制一个黑色形状来“清除”旧的Etincelle。我不确定Fusee是否应该“离开”,所以我留下了评论

public class Fusee extends Etincelle {

    private static final HashMap<String, Class<? extends Etincelle>> ETINCELLE_MAP = new HashMap<String, Class<? extends Etincelle>>() {{
        put(CroixEtincelle.FORME, CroixEtincelle.class);
        put(PointEtincelle.FORME, PointEtincelle.class);
        put(EtoileEtincelle.FORME, EtoileEtincelle.class);
    }};

    //ATTRIBUTES
    public int size;
    public long duree;
    public String forme;

    //CONSTRUCTOR
    public Fusee(double x, double y, String forme, Color couleur, int size, long duree) {
        super(x, y, couleur);
        this.size = size;
        this.forme = forme;
        this.duree = duree;
    }

    private static LinkedList<Drawable> getPattern(double xf, double yf, Color couleur, String forme, int puissEtincelles) {
        LinkedList<Drawable> liste = new LinkedList<Drawable>();

        if (ETINCELLE_MAP.containsKey(forme)) {
            Class<? extends Etincelle> clz = ETINCELLE_MAP.get(forme);

            Class[] params = new Class[]{double.class, double.class, Color.class};

            try {
                Constructor ctor = clz.getConstructor(params);

                liste.add((Drawable) ctor.newInstance(xf, yf, couleur));

                for (int k = 1; k <= puissEtincelles; k++) {
                    int mult = 10 * k;
                    liste.add((Drawable) ctor.newInstance(xf + mult, yf, couleur));
                    liste.add((Drawable) ctor.newInstance(xf - mult, yf, couleur));
                    liste.add((Drawable) ctor.newInstance(xf, yf + mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf, yf - mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf + mult, yf + mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf + mult, yf - mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf - mult, yf + mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf - mult, yf - mult, couleur));
                }

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
                e.printStackTrace();
            }
        } else {
            System.err.printf("Forme \"%s\" is not supported\n", forme);
        }

        return liste;
    }

    @Override
    protected void peindreEtincelle(Graphics g) {

        LinkedList<Drawable> liste;

        int mult = 10 * size;

        for (int gen = 0; gen < size; gen++) {

//            clearGraphics(g, (int) x - mult, (int) y - mult, 2 * mult, 2 * mult, Color.black);

            liste = getPattern(x, y, couleur, forme, gen);

            if (gen == 0) {
                Drawable d = liste.get(0);
                d.drawOn(g);
            } else {

                for (int i = 0; i < liste.size(); i++) {
                    Drawable d = liste.get(i);
                    if (i >= 8 * (gen - 1) + 1 && i <= 8 * gen) {
                        d.drawOn(g);
                    }
                    // else {
                    //    g.setColor(Color.black);
                    //    ((Etincelle) d).peindreEtincelle(g);
                    // }
                }

                try {
                    Thread.sleep(duree);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

//        clearGraphics(g, (int) x - mult, (int) y - mult, 2 * mult, 2 * mult, Color.black);
    }

    private void clearGraphics(Graphics g, int x, int y, int width, int height, Color background) {
        Color prevColor = g.getColor();

        g.setColor(background);
        g.fillRect(x, y, width, height);

        g.setColor(prevColor);
    }
}

你能添加完整的代码吗
addWindowListener
用于swing对象,但您没有扩展代码中的任何内容。您在绘制什么?有图像或图纸要显示吗?另外,您正在paint()中开始一个线程-如果您了解paint()在屏幕上每次发生变化时都会被调用-因此每次有东西移动时开始拍摄线程是非常糟糕的-您需要返回并了解paint()!!为了更快地得到更好的帮助,发布一个or。我添加了一张图片作为PEINDRUESEE绘画的示例!否则,谢谢gpasch,这可能就是问题所在。这不是我在我的真实代码中做的事情,只是在我的测试类中,我将尝试重写它并再次测试它!“我还编辑了代码,并将我的全部代码输入到cricket_007中,谢谢你的帮助!”提示:添加@cricket_007(或任何人,
@
很重要)以通知此人新的评论。这看起来很不错@cricket_007谢谢!在接下来的几天里,我会仔细看一看,如果有任何问题,我会回来问你,但非常感谢你的帮助:)
public class Fusee extends Etincelle {

    private static final HashMap<String, Class<? extends Etincelle>> ETINCELLE_MAP = new HashMap<String, Class<? extends Etincelle>>() {{
        put(CroixEtincelle.FORME, CroixEtincelle.class);
        put(PointEtincelle.FORME, PointEtincelle.class);
        put(EtoileEtincelle.FORME, EtoileEtincelle.class);
    }};

    //ATTRIBUTES
    public int size;
    public long duree;
    public String forme;

    //CONSTRUCTOR
    public Fusee(double x, double y, String forme, Color couleur, int size, long duree) {
        super(x, y, couleur);
        this.size = size;
        this.forme = forme;
        this.duree = duree;
    }

    private static LinkedList<Drawable> getPattern(double xf, double yf, Color couleur, String forme, int puissEtincelles) {
        LinkedList<Drawable> liste = new LinkedList<Drawable>();

        if (ETINCELLE_MAP.containsKey(forme)) {
            Class<? extends Etincelle> clz = ETINCELLE_MAP.get(forme);

            Class[] params = new Class[]{double.class, double.class, Color.class};

            try {
                Constructor ctor = clz.getConstructor(params);

                liste.add((Drawable) ctor.newInstance(xf, yf, couleur));

                for (int k = 1; k <= puissEtincelles; k++) {
                    int mult = 10 * k;
                    liste.add((Drawable) ctor.newInstance(xf + mult, yf, couleur));
                    liste.add((Drawable) ctor.newInstance(xf - mult, yf, couleur));
                    liste.add((Drawable) ctor.newInstance(xf, yf + mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf, yf - mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf + mult, yf + mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf + mult, yf - mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf - mult, yf + mult, couleur));
                    liste.add((Drawable) ctor.newInstance(xf - mult, yf - mult, couleur));
                }

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
                e.printStackTrace();
            }
        } else {
            System.err.printf("Forme \"%s\" is not supported\n", forme);
        }

        return liste;
    }

    @Override
    protected void peindreEtincelle(Graphics g) {

        LinkedList<Drawable> liste;

        int mult = 10 * size;

        for (int gen = 0; gen < size; gen++) {

//            clearGraphics(g, (int) x - mult, (int) y - mult, 2 * mult, 2 * mult, Color.black);

            liste = getPattern(x, y, couleur, forme, gen);

            if (gen == 0) {
                Drawable d = liste.get(0);
                d.drawOn(g);
            } else {

                for (int i = 0; i < liste.size(); i++) {
                    Drawable d = liste.get(i);
                    if (i >= 8 * (gen - 1) + 1 && i <= 8 * gen) {
                        d.drawOn(g);
                    }
                    // else {
                    //    g.setColor(Color.black);
                    //    ((Etincelle) d).peindreEtincelle(g);
                    // }
                }

                try {
                    Thread.sleep(duree);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

//        clearGraphics(g, (int) x - mult, (int) y - mult, 2 * mult, 2 * mult, Color.black);
    }

    private void clearGraphics(Graphics g, int x, int y, int width, int height, Color background) {
        Color prevColor = g.getColor();

        g.setColor(background);
        g.fillRect(x, y, width, height);

        g.setColor(prevColor);
    }
}
public class FuseePanel extends Panel {

    //CONSTRUCTOR
    public FuseePanel() { }

    //METHOD
    @Override
    public void paint(Graphics g) {
        int w = this.getSize().width;
        int h = this.getSize().height;

        Color defaultColor = g.getColor();
        g.setColor(Color.black);
        g.fillRect(0, 0, w, h);
        g.setColor(defaultColor);

        java.util.List<Drawable> shapes = new ArrayList<Drawable>();
        shapes.add(new PointEtincelle(40, 40));
        shapes.add(new CroixEtincelle(70, 89));

        int fuseeDuree = 100;
        shapes.add(new Fusee(234, 264, PointEtincelle.FORME, Color.blue, 8, 2*fuseeDuree));
        shapes.add(new Fusee(500, 264, CroixEtincelle.FORME, Color.yellow, 20, fuseeDuree/2));
        shapes.add(new Fusee(400, 400, EtoileEtincelle.FORME, Color.red, 8, 5*fuseeDuree));

        for (Drawable d : shapes) {
            d.drawOn(g);
        }
    }

    //MAIN
    public static void main(String[] args) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                final Frame f = new Frame();
                f.setLocation(100, 100);
                f.add(new FuseePanel());
                f.setSize(1200, 700);

                f.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        super.windowClosing(e);
                        f.dispose();
                        System.exit(0);
                    }
                });

                f.setVisible(true);
            }
        });
    }
}