Java 在焰火程序中启动线程
我正在编写一个小的焰火软件,在这个软件中,用户可以选择保险丝的颜色、爆炸时间、持续时间、大小和形式,添加其他保险丝,然后启动它们,从而创建一个新的框架,保险丝在给定的时间和持续时间内出现 我将问题分为不同的类,分别为sparks、Fusee和动画创建框架,用户可以在其中设置保险丝。它们中的每一个都有一个绘制功能:peindreEtincelle(图形g),然后是使用peindreEtincelle的peindreFusee(图形g),然后是使用peindreFusee的动画绘制。每个fuse都应该有自己的线程,这样我就可以控制何时停用它,我已经在测试类中测试了peindreFusee和peindreEtincelle,它们工作得很好。由于Fusee类中有一个线程,我编写了一个函数run(),该函数使用PEINDREFUESEE,如下所示: 类Fusee与run()对应的每个线程=每个保险丝:Java 在焰火程序中启动线程,java,multithreading,swing,graphics,Java,Multithreading,Swing,Graphics,我正在编写一个小的焰火软件,在这个软件中,用户可以选择保险丝的颜色、爆炸时间、持续时间、大小和形式,添加其他保险丝,然后启动它们,从而创建一个新的框架,保险丝在给定的时间和持续时间内出现 我将问题分为不同的类,分别为sparks、Fusee和动画创建框架,用户可以在其中设置保险丝。它们中的每一个都有一个绘制功能:peindreEtincelle(图形g),然后是使用peindreEtincelle的peindreFusee(图形g),然后是使用peindreFusee的动画绘制。每个fuse都应
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);
}
});
}
}