我正在编写一个小烟花软件,用户可以选择颜色,爆炸时间,保险丝的持续时间,大小和形状,添加其他保险丝然后启动它们,这会创建一个新的框架,保险丝出现在他们给定的时间和给定的持续时间。
我将问题分为不同的类别,Etincelles用于火花,Fusee用于每个保险丝,然后动画创建框架,用户可以设置保险丝。他们每个人都有一个绘画功能:peindreEtincelle(图形g),然后是使用peindreEtincelle的peindreFusee(图形g),然后是使用peindreFusee的动画中的绘画。每个保险丝应该有自己的线程,以便我可以控制何时停用它,我已经在测试类中测试了peindreFusee和peindreEtincelle并且它们工作正常。由于Fusee类中有一个线程,我编写了一个使用peindreFusee的函数run(),如下所示:
每个线程的每个线程的run()类Fusee:
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);
}
}
现在我想通过手动设置然后启动线程来测试一个保险丝的动画;但只有一个涂成黑色的新框架出现,没有保险丝。我的测试类看起来像这样:
测试动画的类:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.math.*;
public class TestFusee extends Frame {
//ATTRIBUTS
public Fusee fus ;
public int w,h ;
//CONSTRUCTOR
public TestFuseeAnimee() {
this.setLocation(100, 100);
this.setSize(1200,700);
w = this.getSize().width ;
h = this.getSize().height ;
fus = new Fusee(1);
fus.active = true ;
fus.xf = w/2 ;
fus.yf = h/2 ;
fus.couleur = Color.red ;
fus.forme = "etoile" ;
fus.puissEtincelles = 2 ;
fus.tpsDepart = 10 ;
fus.duree = 20 ;
addWindowListener(new EcouteurPourFermetureFenetre());
}
//METHOD
public void paint(Graphics g){
w = this.getSize().width ;
h = this.getSize().height ;
g.setColor(Color.black);
g.fillRect(0, 0, w, h);
fus.g = g;
fus.anim.start();
}
//MAIN
public static void main(String [] abs){
TestFuseeAnimee fen = new TestFuseeAnimee();
fen.setVisible(true) ;
}
以下是peindreFusee()实际绘画的一个示例(此处为橙色圆点,表单和颜色由用户选择)
有谁能告诉我我的代码有什么问题?这将非常有帮助。
非常感谢:)
以下是测试程序的缺失类:
班级Etincelle:
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);
}
}
}
EcouteurPourFermetureFenetre课程:
import java.awt.event.*;
public void windowClosing(WindowEvent w) {
w.getWindow().dispose() ;
System.exit(0);
}
}
答案 0 :(得分:0)
所以...我觉得这很接近你想要的(没有延迟......无法解决这个问题),对不起切换任何法语和英语:)
第1步 - 定义可绘制界面
public interface Drawable {
void drawOn(Graphics g);
}
第2步 - 定义一个实现此Drawable
的抽象Etincelle
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的扩展,在这里我们做Point 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);
}
}
我也有一个Etoille forme,但我认为你明白了。
第4步 - 定义一个Fusee,在这里用于所有目的,只是一个非常大的Etincelle,所以我们将这样定义。这可能是最复杂的课程,但我做了一些反思魔法,以从#34; CROIX&#34;的字符串值中获取不同的表格。和#34; POINT&#34;,例如。这将让你以后很容易地添加不同的版本。注释掉的部分&#34;工作&#34; ...你可以玩它们取消注释它们,但它们可以清除&#34;清除&#34;离开旧的Etincelle基本上是通过重绘黑色的形状。我不确定Fusee是否应该“离开”#34;或不,所以我留下他们评论。
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);
}
}
第5步 - 定义用于绘制这些Drawables
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);
}
});
}
}