Verständnisprobleme bei Java Applet

Status
Nicht offen für weitere Antworten.

1one

Mitglied
Hallo,

ich habe mich etwas mit Netbeans und Java befasst und ein paar Tutorials und Beispielaufgaben auf dem Inet durchgearbeitet. Bei einer Aufgabe komme ich leider in stocken. Bei der Aufgabe handelt es sich um das Erstellen von Raketen zb. Sylversterraketen. Als ich Probleme hatte, diese bunten Funken nach der Explosion zu erstellen habe ich mir das fertig Program aus dem Inet gesaugt und angeschaut. Doch was dort steht, zu den bunten Funken, is mehr mehr oder minder ein Rätsel. Ich poste es mal...

[HIGHLIGHT="Java"] partikel[] p= new partikel[100];
int r_vx=(r_ziel_x-r_start_x)/40;
int r_vy=(r_ziel_y-r_start_x)/60;
int r_x=(r_ziel_x);
int r_y=(r_ziel_y);
int t_x;
int t_y;
int t_r;
Color t_c;
double ent=Math.random();
if (ent<0.33) {
t_c=new Color(205+(int)(Math.random()*50),0,0);
} else if (ent>0.67){
t_c=new Color(0,205+(int) (Math.random()*50),0,0);
} else {
t_c = new Color (0,0,205+(int)(Math.random()*50));
}


for (int i=0; i<100; i++) {
p = new partikel(r_x, r_y, r_vx, r_vy,
Math.random()*10,
Math.random()*2*Math.PI,
t_c);
g.setColor(p.c);
t_x=(int)(p.x-p.r);
t_y=(int)(p.y-p.r);
t_r=(int)(2*p.r);
g.fillOval(t_x, t_y, t_r, t_r);

}
for(int i=0; i<50; i++) {
for(int j=0; j<100; j++) {
g.setColor(Color.BLACK);
t_x=(int)(p[j].x-p[j].r);
t_y=(int)(p[j].y-p[j].r);
t_r=(int)(2*p[j].r);
g.fillOval(t_x, t_y, t_r, t_r);
p[j].move();
g.setColor(p[j].c);
t_x=(int)(p[j].x-p[j].r);
t_y=(int)(p[j].y-p[j].r);
t_r=(int)(2*p[j].r);
g.fillOval(t_x, t_y, t_r, t_r);
}
pause(50);
}[/HIGHLIGHT]

Diese Partikel sollen wohl diese Funken darstellen. Im großen und ganzen habe ich das ja verstanden, nur ich würde gerne im Detail wissen, was da jetzt genau abläft und welcher Befehl genau was aussagt. So wie ich das verstanden habe, handelt es sich bei dem ersten Absatz um die einfache initialisierung der Variablen und das errechnen der Farbe der Partikel. Doch ich verstehe nich was die Variable "r_" vor den anderen zu bedeutet hat. Ganz zu schweigen von den beiden Absätzen die folgen. Ich würde mich freuen, wenn mir jemand etwas unter die Arme greifen könnte...

gruß
1one
 
Zuletzt bearbeitet von einem Moderator:
sieht nach nicht kompilierbaren Murks aus. Ohne codetags (etwa [HlGHLIGHT][/HlGHLIGHT] ) dazu absolut unleserlich.

Klassennamen ("partikel") schreibt man groß.

Kannst du bitte zumindest mal den vollständigen code posten?

[edit: thx @ L-ectron-X, aber der code wird deshalb nicht vollständiger 😕 ]
[edit von L-ectron-X: Das kann ich auch nicht ändern. 😉 ]
 
Zuletzt bearbeitet von einem Moderator:
Ach du scheisse, woher hast du denn diese Aufgabe?
Was auch immer das für ein Buch ist: Schmeiss es weg!
Klassennamen klein geschrieben, Variablen haben bescheuerte Namen.
Kein Wunder, dass du nicht durchblickst.

Irgendwie werden hier Partikel-Objekte erstellt, deren Position geändert
und im Endeffekt per

g.fillOval()

ein kleiner Funken gezeichnet, und zwar an der Stelle, wo sich das Partikel gerade
befindet, in der Farbe, die ihm zugewiesen wurde.

Irgendwo muss es eine Klasse "partikel" geben, schau dir im Konstruktor davon an
was genau die Werte bedeuten.

Das scheint aber ziemlich dämlich und kompliziert gemacht zu sein.

Was du machen musst ist eigentlich nix anderes als bei jedem Durchlauf
neue Partikel zu erstellen, und sie nach der Zeit verblassen zu lassen:

PSEUDO-CODE:
[HIGHLIGHT="Java"]List Partikel liste;
while(rakete.isFlying()){
// neuer Partikel
liste.add(new Partikel(rakete.x, rakete.y, new RandomColor()));

// existierende partikel zeichnen
for( Partikel p : liste ){
Color alt = p.getColor();
Color neu = alt.setAlpha++; // Farbe "verblassen" / transparenter machen
p.setColor(neu);
if( p.getColor().getAlpha() > 0){
g.setColor( p.getColor() );
g.fillOval(p.x, p.y, p.size, p.size);
}
}
rakete.moveUp();
sleep(20);
}[/HIGHLIGHT]

edit: Das zeichnet jetzt immer nur einen Partikel und sieht nicht wirklich wie ein
Sprüheffekt aus.
Dafür müsstest du mehr als 1 Partikel zur Liste adden pro Durchlauf, und
rakete.x sowie rakete.y halt etwas per Zufall abändern, damit sich die Partikel
um diesne Punkt rum zufällig verteilen.
 
Zuletzt bearbeitet:
hier der vollständige code, der auch funktioniert, es harpert wie gesagt nur an dem verständnis, bei den partikeln bzw den funken!! kann mir da wer weiterhelfen ?

[HIGHLIGHT="Java"]import java.awt.*;

public class feuerwerk extends javax.swing.JFrame {

public feuerwerk() {
initComponents();
this.setSize(800, 600);
}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

schuss = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(null);

schuss.setText("Schuss!");
schuss.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
schussActionPerformed(evt);
}
});
getContentPane().add(schuss);
schuss.setBounds(20, 10, 130, 23);

pack();
}// </editor-fold>


public void paint (Graphics g) {
g.setColor(Color.black);
g.fillRect(0,70,800,600);
}

public void pause (long zeit) {
try {
Thread.sleep(zeit);
} catch(InterruptedException e) {}
}


private void schussActionPerformed(java.awt.event.ActionEvent evt) {
Graphics g = getGraphics();
g.fillRect(0,70,800,600);
int r_start_x=(int) (Math.random()*400+200);
int r_start_y=600;
int r_ziel_x=(int) (Math.random()*400+200);
int r_ziel_y=(int) (Math.random()*50+100);
for(int i=0; i<=95; i++) {
g.setColor(Color.LIGHT_GRAY);
g.drawLine((r_ziel_x-r_start_x)*i/100+r_start_x,
(r_ziel_y-r_start_y)*i/100+r_start_y,
(r_ziel_x-r_start_x)*(i+5)/100+r_start_x,
(r_ziel_y-r_start_y)*(i+5)/100+r_start_y);
g.setColor(Color.BLACK);
g.drawLine((r_ziel_x-r_start_x)*i/100+r_start_x,
(r_ziel_y-r_start_y)*i/100+r_start_y,
(r_ziel_x-r_start_x )*(i-5)/100+r_start_x,
(r_ziel_y-r_start_y)*(i-5)/100+r_start_y);


pause(10);
}
g.setColor(Color.BLACK);
g.drawLine((r_ziel_x-r_start_x)*94/100+r_start_x,
(r_ziel_y-r_start_y)*94/100+r_start_y,
(r_ziel_x-r_start_x)*99/100+r_start_x,
(r_ziel_y-r_start_y)*99/100+r_start_y);

partikel[] p= new partikel[100];
int r_vx=(r_ziel_x-r_start_x)/40;
int r_vy=(r_ziel_y-r_start_x)/60;
int r_x=(r_ziel_x);
int r_y=(r_ziel_y);
int t_x;
int t_y;
int t_r;
Color t_c;
double ent=Math.random();
if (ent<0.33) {
t_c=new Color(205+(int)(Math.random()*50),0,0);
} else if (ent>0.67){
t_c=new Color(0,205+(int) (Math.random()*50),0,0);
} else {
t_c = new Color (0,0,205+(int)(Math.random()*50));
}


for (int i=0; i<100; i++) {
p = new partikel(r_x, r_y, r_vx, r_vy,
Math.random()*10,
Math.random()*2*Math.PI,
t_c);
g.setColor(p.c);
t_x=(int)(p.x-p.r);
t_y=(int)(p.y-p.r);
t_r=(int)(2*p.r);
g.fillOval(t_x, t_y, t_r, t_r);

}
for(int i=0; i<50; i++) {
for(int j=0; j<100; j++) {
g.setColor(Color.BLACK);
t_x=(int)(p[j].x-p[j].r);
t_y=(int)(p[j].y-p[j].r);
t_r=(int)(2*p[j].r);
g.fillOval(t_x, t_y, t_r, t_r);
p[j].move();
g.setColor(p[j].c);
t_x=(int)(p[j].x-p[j].r);
t_y=(int)(p[j].y-p[j].r);
t_r=(int)(2*p[j].r);
g.fillOval(t_x, t_y, t_r, t_r);
}
pause(50);
}

}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new feuerwerk().setVisible(true);
}
});
}

// Variables declaration - do not modify
private javax.swing.JButton schuss;
// End of variables declaration

}

class partikel {
double x,y; // momentane Position
double vx,vy; //momentane Geschendigkeit
double ax,ay; // momentane Beschleunigung
double r; // momentaner Radius
double s; //Anzahl der Lebenszyklen
Color c; //gegenwärtige Farbe



public partikel(int x, int y, int vx, int vy, double kraft,
double richtung, Color c){
this.x=x;
this.y=y;
this.vx=vx;
this.vy=vy;
this.c=c;
this.r=1;
this.s=0;
this.ax=(Math.cos(richtung)*kraft);
this.ay=(Math.sin(richtung)*kraft);

}

public void move() {
x=x+vx/40;
y=y+vy/40;
vy=vy+ay;
vx=vx+ax;
s++;
if(s%5==0){
int rot=c.getRed();
int gruen=c.getGreen();
int blau=c.getBlue();
rot=90*rot/100;
gruen=90*gruen/100;
blau=90*blau/100;
c=new Color(rot,gruen,blau);
if(s>25) {
r--;
} else {
r++;
}

}
ay=ay+1;
ax=ax*0.99;

}
}[/HIGHLIGHT]
 
wie ich schon sagte: Der Code ist Trash! Versuch erst gar nicht das zu verstehen.
Versuch das zu verstehen, was ich gepostet habe, und dann programmier es selber.
Das ganze Programm kann man locker in 50 Zeilen inkl. Darstellung schreiben.
 
Mal wieder "getGraphics" auf einer Component (ohne active Rendering und so...). Scuh mal nach "Zeichnen in Swing Tutorial" - hab's geade eben schon in einem anderen Thread gepostet....
 
lol zeig mal 🙂

Okay, etwas drüber aber ich bleib lieber korrekt als jetzt hier übliche Dinge wegzulassen. (Frame settings usw.)

[HIGHLIGHT="Java"]import java.awt.*;
import java.util.List;
import java.util.*;
import javax.swing.*;

public class RocketDemo extends JFrame {
private int rocketX = 250, rocketY = 500;
private List<Particle> particles = new ArrayList<Particle>();
private static final Random r = new Random();

public RocketDemo() {
super("Rocket Demo");
JPanel panel = new JPanel() {
@Override
protected synchronized void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(rocketX, rocketY, 10, 50);
for (Particle p : particles) {
g.setColor(p.c);
g.fillOval(p.x, p.y, 5, 5);
}
}
};
panel.setPreferredSize(new Dimension(500, 500));
add(panel);
pack();
setResizable(false);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
while (rocketY-- > -150) {
for (int i = 0; i < particles.size(); i++) {
Particle p = particles.get(i);
if (p.c.getAlpha() > 0) {
p.c = new Color(p.c.getRed(), p.c.getGreen(),p.c.getBlue(), p.c.getAlpha() - 3);
} else {
particles.remove(i--);
}
}
int mod = r.nextInt(2) == 0 ? 1 : -1;
particles.add(new Particle(rocketX + r.nextInt(5) * mod, rocketY+ 50 + r.nextInt(10) * mod));
repaint();
try { Thread.sleep(5); } catch (InterruptedException e) {
}
}
}
class Particle {
int x, y;
Color c;
public Particle(int x, int y) {
this.x = x;
this.y = y;
c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255), 255);
}
}
public static void main(String[] args) {
new RocketDemo();
}
}[/HIGHLIGHT]

hdi spricht gerne mit vollem Mund...
🙁

edit: hat sich erledigt, danke fenzy
 
Zuletzt bearbeitet:
Moin,

Muss ich speziell auf die Liste synchronisieren?

genau, z.B. einfach ein

[HIGHLIGHT="Java"]private List<Particle> particles = Collections.synchronizedList(new ArrayList<Particle>());[/HIGHLIGHT]

rein und den Zugriff jeweils mit

[HIGHLIGHT="Java"]synchronized(particles) { ... }[/HIGHLIGHT]

synchronisieren. Dann geht’s.

Gruß,
Michael
 
Aha, diese synchronizedList Methode kannte ich gar nicht.
Ich dachte man kann mittels synchronized() auf jedes Java-Objekt synchronisieren?
Geht das denn nur mit manchen Objekten?
 
Moin,

edit: hat sich erledigt, danke fenzy

lol, immerhin 60% Trefferquote 😉

Aha, diese synchronizedList Methode kannte ich gar nicht.
Ich dachte man kann mittels synchronized() auf jedes Java-Objekt synchronisieren?
Geht das denn nur mit manchen Objekten?

Nein, synchronized() geht schon auf allen Objekten. Ganz konkret in Deinem Beispiel oben würde es auch reichen wenn jeder Zugriff auf die Liste (und insbesondere die Iterationen darüber) mit jeweils einem synchronized() Block eingefasst würde.

Andererseits bietet die API aber auch Warpper um z.B. ArrayList() thread-safe zu machen. Damit sind dann direkte Listenoperationen atomar. Allerdings beinhaltet dies nicht die Iteration über die einzelnen Elemente der Liste, deswegen müssen Deine Schleifen trotzdem mit synchronized() abgesichert werden.

Synchronization Wrappers

Man könnte jetzt argumentieren das der synchronization Warpper im konkreten Fall unnötig sei, ich persönlich stehe jedoch auf dem Standpunkt, das dies bei einer Collection auf der aus mehreren Threads zugegriffen wird die saubere Lösung ist.

In dem Zusammenhang ist auch ein Blick auf java.util.concurrent.* lohnenswert, den damit geht vieles auch ohne explizites synchronized().

Gruß,
Michael
 
Zuletzt bearbeitet:
Moin,

vielleicht noch als Nachschlag für 1one, falls Du dich gerade wunderst worum es in den letzten 3 Postings eigentlich ging. Im Beispiel von hdi wurde von 2 verschiedenen Threads auf die particles Liste zugegriffen, damit kommt es zu einer regelmäßigen ConcurrentModificationException.

Um dies zu verhindern muss der Zugriff auf die particles Liste synchronisiert werden (dann greifen die einzelnen Threads nur noch nacheinander auf die Liste zu). Die bekannteste Möglichkeit dazu ist der synchronized() Block, evtl. im Zusammenhang mit Collections.synchronized*(). Alternativ dazu gibt es das java.util.concurrent.* package.

Der Vollständigkeit halber, mal das Beispiel von hdi mit ConcurrentLinkedQueue<>() und ohne explizite synchronized() Blöcke (und gepresst auf 50 Zeilen 😉 ):

[HIGHLIGHT="Java"]import java.awt.*;
import java.util.*;
import java.util.concurrent.*;
import javax.swing.*;

public class RocketDemo extends JFrame {
private static final Random r = new Random();
private final Queue<Particle> particles = new ConcurrentLinkedQueue<Particle>();
private final int rocketX = 250;
private int rocketY = 500;

public RocketDemo() {
super("Rocket Demo");
final JPanel panel = new JPanel() {
@Override protected void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(rocketX, rocketY, 10, 50);
for (final Particle p : particles) {
g.setColor(p.c);
g.fillOval(p.x, p.y, 5, 5);
}
}
};
panel.setPreferredSize(new Dimension(500, 500)); add(panel); pack();
setResizable(false);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
while (rocketY-- > -150) {
for (final Particle p : particles) {
if (p.c.getAlpha() > 0) p.c = new Color(p.c.getRed(), p.c.getGreen(), p.c.getBlue(), p.c.getAlpha() - 3);
else particles.remove(p);
}
final int mod = r.nextInt(2) == 0 ? 1 : -1;
particles.add(new Particle(rocketX + r.nextInt(5) * mod, rocketY + 50 + r.nextInt(10) * mod));
repaint();
try { Thread.sleep(5); } catch (final InterruptedException e) {}
}
}
class Particle {
int x, y;
Color c;
public Particle(final int x, final int y) {
this.x = x;
this.y = y;
c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255), 255);
}
}
public static void main(final String[] args) { new RocketDemo(); }
}[/HIGHLIGHT]

(In Eclipse bitte einmal Ctrl+Shift+F, dann sieht's auch wieder ordentlich aus 😉 )

Gruß,
Michael
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben