# Blitz berechnen und zeichnen



## triple (17. Mrz 2008)

Hallo zusammen,

ich muss ein Java-Programm haben, welches einen Blitz zeichnet, von oben vom Fenster per Zufallsgenerator nach unten. Kann mir jemand helfen? Schön wäre noch ein Punkt Unten am Fenster, welchen den Blitz anzieht, d.h. dass der Blitz bei 10 mal ausführen etwa 7 mal in den Punkt einschlägt. Ich dachte mir irgendwie mit einem Koordinaten-System.
(P.S. über nicht all zu kompliziertes Java wäre ich sehr dankbar, da ich das Programm verstehen muss)

Herzlichen Dank,

Gruss triple


_L-ectron-X hat diesen Beitrag am 17.03.2008 um 16:39 Uhr editiert._
_Titel des Themas angepasst._


----------



## Quaxli (17. Mrz 2008)

Klar kein Problem. Zeige uns was Du schon selbst gemacht hast und beschreibe Dein aktuelles Problem genauer.  :bae:  :bae:  :bae:


----------



## triple (17. Mrz 2008)

Gemacht habe ich noch nichts, bin nicht der allerbeste Java-Programmierer und habe daher Probleme von Beginn an. Obwohl ich die Befehle zum Teil kenne zum zeichnen kann ich sie nicht zusammensetzen. Da ich das Programm sehr dringend brauche, bin ich ziemlich aufgeschmissen, ihr seid meine letzte Hoffnung, bitte helft mir.

Gruss triple


----------



## LordLuzifer (17. Mrz 2008)

Setze deinen Blitz aus einzelnen Punkten zusammen, zwischen denen eine Linie gezeichnet wird; die Punkte kannst du ja irgendwie selbst ermitteln. Dann melde dich nochmal und wir helfen dir beim Zeichnen.


----------



## triple (17. Mrz 2008)

```
public class Points {
	static int a;

	public static int NewX(int x1) {
		int x2 = 0, rand;
		rand = (int) ((Math.random() * 100) + 50);
		switch (a) {
		case 1:
			x2 = x2 + rand;
			a = 2;
			break;
		case 2:
			x2 = x2 - rand;
			a = 1;
			break;
		}
		return x2;
	}

	public static int NewY(int y1) {
		int y2 = 0, rand;
		rand = (int) ((Math.random() * 50) + 50);
		y2 = y2 + rand;
		return y2;
	}
}
```

Das wären meine Funktionen, mit NewX wird aus dem alten X-Koordinatenpunkt der neue berechnet, mit NewY das gleiche...

Mit der Variable a wird geschaut, dass der Blitz einmal nach links, einmal nach rechts geht.

Ich habe ein Koordinatensystem angenommen, in welchem x von links nach rechts grösser wird, und y von oben nach unten grösser wird.

Jeweils ein int als Parameter und ein int als Rückgabewert.

Die grössen wäre wohl etwa für ein Fenster 500x300 (breit) gedacht, kann man dann ja immer noch anpassen.

Wäre froh um den Code um diese Punkte zu zeichnen.

Gruss triple


----------



## Guest (17. Mrz 2008)

Was du brauchst ist ein Zeichenfläche, also eine paint()-Methode. Du schreibtst ein Klasse wo von JPanel erbt.

Das BufferedImage ist ein Objekt das eine Graphics speichert.

 Um die Leinwand sichtbar zu machen musst du sie nur mit einer add()-Methode einem JFrame mitteilen.


```
public class Leinwand extends JPanel {
 
 BufferedImage bi = new BufferedImage(500,300,BufferedImage.TYPE_INT_RGB); 

   public void paintComponent(Graphics g) {

           Graphics2D g2d = (Graphics2D) g;

           bi.setRGB(x,y,new Color(r,g,b).getRGB());
           
          g2d.drawImage(bi,0,0,bi.getWidth(),bi.getHeight(),this);
     
   }

}
```


----------



## triple (17. Mrz 2008)

Danke für die Antwort.

Jedoch ist dies zu hoch für mich, ich kann das irgendwie nirgens einbauen.

Könnte mir nicht bitte jemand eine Klasse geben, die für sich selber funktioniert? Ich weiss, es ist armselig, aber leider begreife ich das ganze Fenster-Handling nicht.

Danke für die Hilfe

Gruss triple


----------



## 0x7F800000 (17. Mrz 2008)

naja, mit der einstellung kommt man aber nicht allzuweit...  :roll: 
Lass erstma die ganzen blitze weg, und les dir zB in der FAQ allgemeine sachen zu graphik und gui durch.
Wenn du das gemacht hast, könntest du vielleicht versuchen, folgenden code grob nachzuvollziehen, und vielleicht etwas ähnliches zu schreiben, was mehr zu deinem problem passt

hier: blitz der andauernd auf den cursor einschlägt

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Lightning extends JPanel implements MouseMotionListener{
	
	//ScreenCoords (Point2D cannot be instantiated blah blah blah=no idea=wtf?)
	private static class ScreenCoords{
		public int x,y;
		public ScreenCoords(int _x, int _y){
			x=_x; y=_y;
		}
		public ScreenCoords add(ScreenCoords a){ return new ScreenCoords(x+a.x,y+a.y); }
		public ScreenCoords sub(ScreenCoords a){ return new ScreenCoords(x-a.x,y-a.y); }
		public ScreenCoords mul(int a){ return new ScreenCoords(x*a,y*a); }
		public ScreenCoords div(int a){ return new ScreenCoords(x/a,y/a); }
		public int getLength(){ return (int)Math.sqrt(x*x+y*y); }
		public ScreenCoords getOrtho(){ return new ScreenCoords(-y,x); }
	}
	
	
	//Node-struct
	private static class Node{
		//member vars
		private boolean isLeaf;
		private Node[] childNodes;
		private ScreenCoords[] vertices;
		
		//final static
		private final static int MIN_CHILDNODES=3, MAX_ADDITIONAL_CHILDNODES=4;
		private final static int MIN_BIFURCATION=0, MAX_ADDITIONAL_BIFURCATION=3;
		
		//constructor
		public Node(ScreenCoords start, ScreenCoords end, int level){
			if(level==0){
				//end of recursion, creating leaf node
				isLeaf=true;
				vertices=new ScreenCoords[2];
				vertices[0]=start; vertices[1]=end;
			}else{
				isLeaf=false;
				//decide how many child nodes to create
				int numberOfChildNodes=
					MIN_CHILDNODES+(int)(Math.random()*MAX_ADDITIONAL_CHILDNODES+1);
				int numberOfBifurcationNodes=
					level+(int)(Math.random()*(MAX_ADDITIONAL_BIFURCATION+1));
				
				//allocate space for all the nodes
				childNodes=new Node[numberOfChildNodes+numberOfBifurcationNodes];
				
				//create vertices for child nodes
				ScreenCoords[] childVertices=new ScreenCoords[numberOfChildNodes+1];
				
				
				
				//first and last vertices already exist: its start and end of parent node
				childVertices[0]=start; childVertices[childVertices.length-1]=end;
				
				//creating vertices for the child nodes
				//AN DIESER STELLE BELIEBIGES ANDERES VERFAHREN EINSETZEN, DAMITS HÜBSCHER AUSSIEHT!
				ScreenCoords connection=end.sub(start);
				ScreenCoords ortho=connection.getOrtho().div(8);
				double randomConnectionDistance;
				for(int i=1; i<numberOfChildNodes; i++){
					randomConnectionDistance=Math.random()*2-1d;
					childVertices[i]=
					start.add(connection.mul(i).div(numberOfChildNodes)
						 .add(new ScreenCoords((int)(ortho.x*randomConnectionDistance),
								 				(int)(ortho.y*randomConnectionDistance))));
				}
				
				//adding the child nodes to the list
				for(int i=0; i<numberOfChildNodes; i++){
					childNodes[i]=new Node(childVertices[i], childVertices[i+1], level-1);
				}
				
				//bifurcations: the first vertex is always "start"
				//and the second vertex is always random
				double randomRadius, randomAngle;
				int radius=connection.getLength()*3/numberOfChildNodes;
				for(int i=0; i<numberOfBifurcationNodes; i++){
					randomRadius=(1+Math.random())*radius/2;
					randomAngle=Math.random()*2*Math.PI;
					childNodes[i+numberOfChildNodes]=
						new Node(start,start.add(new ScreenCoords((int)(randomRadius*Math.cos(randomAngle)),
														(int)(randomRadius*Math.sin(randomAngle)))),
														level-1);
				}
			}
		}//end of constructor
		
		public void paint(Graphics g){
			if(isLeaf){
				g.setColor(Color.WHITE);
				g.drawLine(vertices[0].x, vertices[0].y, vertices[1].x, vertices[1].y);
			}else{
				for(int i=0; i<childNodes.length; i++){
					childNodes[i].paint(g);
				}
			}
		}
	}//end of Node-class definition
	
	//auto-repaint thread
	private static class RepaintThread extends Thread{
		private Lightning lightningPanel;
		public RepaintThread(Lightning _lightningPanel){
			lightningPanel=_lightningPanel;
		}
		public void run(){
			while(true){
				
				if(lightningPanel.lightningOn){
					if(Math.random()>0.975){
						lightningPanel.lightningOn=false;
					}
				}else{
					if(Math.random()>0.995){
						lightningPanel.lightningOn=true;
					}
				}
				if(Math.random()>0.95){
					lightningPanel.lightningOn=!lightningPanel.lightningOn;
				}
				lightningPanel.repaint();
				try{
					sleep(30);
				}catch(InterruptedException e){}
			}
		}
	}
	
	//member vars
	//root Node
	private Node root;
	private int mouseX,mouseY;
	public boolean lightningOn;
	
	//constructor
	public Lightning(){
		super();
		mouseX=mouseY=100;
		addMouseMotionListener(this);
		lightningOn=false;
		
		RepaintThread repaintThread=new RepaintThread(this);
		repaintThread.start();
	}
	
	//paint
	public void paint(Graphics g){
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, getWidth(), getHeight());
		if(lightningOn){
			root=new Node(new ScreenCoords(getWidth()/2,100), new ScreenCoords(mouseX, mouseY), 3);
			root.paint(g);
		}
	}
	
	//mouse motion listener
	public void mouseMoved(MouseEvent e){
		mouseX=e.getX(); mouseY=e.getY();
	}
	public void mouseDragged(MouseEvent e){}
	//main
	public static void main(String[] args){
		JFrame f=new JFrame("Lightning hits the cursor");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(500,500);
		f.getContentPane().add(new Lightning());
		f.setVisible(true);
	}
}
```

die idee ist:
-der blitz ist wie ein baum strukturiert, jeder knoten stellt eine strecke dar, die in weitere strecken unterteilt wird usw usw
-der blitz wird dementsprechend rekursiv gezeichnet (stellt eine eigene paint() funktion zur verfügung, hat aber an sich nix mit Component zu tun)
-nebenbei läuft ein thread und schaltet den blitz in regelmäßigen abständen ein und aus
-mouseMotionListener holt einfach nur die koordinaten der maus

höchstwahrscheinlich wirst du damit ohne grundlagen absolut gar nix anfangen können.
Für alle anderen gilt auch: Stilistisch gesehen ist das eine jämmerlich zusammengehackte katastrophe vollgestopft mit "magic numbers"


----------



## triple (17. Mrz 2008)

also gut, ich habe versucht, den code z verstehen und habe nun selber ein Programm versucht zu kreieren, welches eine Linie zeichnet. Das tut es aber leider nicht, 
hier mein Programm



```
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;




public class Points {



public void paint(Graphics g) {
		g.setColor(Color.BLACK);
		g.drawLine(100, 100, 300, 300);
}



public static void main(String[] args) {
JFrame f = new JFrame("Blitz");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(800, 600);
		f.setVisible(true);
}


}
```

Kann mir jemand helfen, dieses Programm so einfach wie möglich zum zeichnen der Linie zu bringen? Den rest könnte ich dann wohl (hoffentlich) allein.

Herzlichen Dank,

triple


----------



## 0x7F800000 (17. Mrz 2008)

```
import javax.swing.*;
import java.awt.*;

public class PaintingLine extends JComponent{

    public PaintingLine(){
        super();
        //...
    }

    public void paint(Graphics g){
        g.setColor(Color.RED);
        g.drawLine(0,0,100,100);
    }

    public static void main(String[] args){
        JFrame f=new JFrame("Linie Zeichnen");
        f.setSize(150,150);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new PaintingLine());
        f.setVisible(true);
    }
}
```

die paint methode wird nur bei Components automatisch aufgerufen, wenn du die in irgendeine strukturlose Klasse reinschreibst, wir die nie aufgerufen.


----------



## triple (17. Mrz 2008)

Herzlichen Dank,

nur noch eine Frage, wenn ich mehrmals eine Linie zeichnen will mit einer While schlaufe, wie muss ich das Anstellen? Wo muss ich die schleife setzen?

danke & gruss

triple

P.S. hier noch der code, Funktioniert so nicht


```
import javax.swing.*;
import java.awt.*;

public class PaintingLine extends JComponent {

	static int x, y, a = 1, xold, yold;

	public static void GetX() {
		int rand;
		xold = x;
		rand = (int) ((Math.random() * 100) + 50);
		if (x >= 650) {
			a = 2;
		} else if (x <= 150) {
			a = 1;
		}
		switch (a) {
		case 1:
			x = x + rand;
			a = 2;
			break;
		case 2:
			x = x - rand;
			a = 1;
			break;
		}
	}

	public static void GetY() {
		int rand;
		yold = y;
		rand = (int) ((Math.random() * 50) + 50);
		y = y + rand;
	}

	public PaintingLine() {
		super();
	}

	public void paint(Graphics g) {
		g.setColor(Color.BLACK);
		g.drawLine(xold, yold, x, y);
	}

	public static void main(String[] args) {
		x = 400;
		y = 0;
		JFrame f = new JFrame("Blitz");
		f.setSize(800, 600);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.getContentPane().add(new PaintingLine());
		f.setVisible(true);
		while (y <= 600) {
			GetX();
			GetY();
		}
	}
}
```


----------



## triple (17. Mrz 2008)

Herzlichen Dank,

nur noch eine Frage, wenn ich mehrmals eine Linie zeichnen will mit einer While schlaufe, wie muss ich das Anstellen? Wo muss ich die schleife setzen?

danke & gruss

triple

P.S. hier noch der code, Funktioniert so nicht


```
import javax.swing.*;
import java.awt.*;

public class PaintingLine extends JComponent {

	static int x, y, a = 1, xold, yold;

	public static void GetX() {
		int rand;
		xold = x;
		rand = (int) ((Math.random() * 100) + 50);
		if (x >= 650) {
			a = 2;
		} else if (x <= 150) {
			a = 1;
		}
		switch (a) {
		case 1:
			x = x + rand;
			a = 2;
			break;
		case 2:
			x = x - rand;
			a = 1;
			break;
		}
	}

	public static void GetY() {
		int rand;
		yold = y;
		rand = (int) ((Math.random() * 50) + 50);
		y = y + rand;
	}

	public PaintingLine() {
		super();
	}

	public void paint(Graphics g) {
		g.setColor(Color.BLACK);
		g.drawLine(xold, yold, x, y);
	}

	public static void main(String[] args) {
		x = 400;
		y = 0;
		JFrame f = new JFrame("Blitz");
		f.setSize(800, 600);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.getContentPane().add(new PaintingLine());
		f.setVisible(true);
		while (y <= 600) {
			GetX();
			GetY();
		}
	}
}
```


----------



## 0x7F800000 (17. Mrz 2008)

KÖNNTE JEMAND BITTE DEN DOPPELPOST LÖSCHEN? DANKE!

allgemein zu deinem code:
1) statische variablen oder funktionen haben in dem gesamten code momentan absolut gar nichts zu suchen
2) methodennamen schreibt man klein
3) mach die merkwürdigen "void Get()" funktionen weg, get ist ein feststehender ausdruck für getter, alles was mit "void" anfängt ist definitiv kein getter
4)while schleife benutzt man so:

```
while(bedingung){
    //alles hier drin wird ausgeführt, solange die bedingung true ergibt
}
```

in deinem fall also

```
public void paint(Graphics g){
    while(int i=0; i<anzahlDerLinienOderSonstirgendetwas; i++){
        //eckpunkte der aktuellen linie neuberechnen
        //linie zeichnen
    }
}
```


----------



## triple (17. Mrz 2008)

Ja danke, nun funktionierts, sogar mit Statischen Variablen, habe sogar noch ein paar Beginnerkomentare eingefügt für mich. hier noch my final code.

Herzlichen Dank für die Hilfe

gruss triple


```
package point;

import javax.swing.*;
import java.awt.*;

//Hauptklasse
public class PaintingLine extends JComponent {
	
	// x, y = Koordinate ; xold, yold = alte Koordinate ; a = Entscheidung ob links oder rechts
	static int x, y, a, xold, yold;

	// Festlegen ob links oder rechts am Anfabg
	public static void setA() {
		a = (int) (Math.random() * 2 + 1); //a wird auf 1 oder 2 gesetzt: 1: nach rechts ; 2: nach links
	}
	
	// x - Koordinate festlegen
	public static void setX() {
		int rand;
		xold = x;	// x wird in xold gespeichert (alte Koordinate)
		rand = (int) ((Math.random() * 100) + 25);	//Bereich der Zufallszahlen wird festgelget (25 - 125)
		//Es wird geschaut dass der Blitz nicht zu viel nach aussen geht
		if (x >= 850) {				//Wenn der Blitz zu viel rechts ist
			a = 2;					//wird a auf 2 gesetzt und geht nach links
		} else if (x <= 150) {		//wenn er jedoch zu viel links ist
			a = 1;					//wird a auf 1 gesetzt und geht nach rechts
		}
		switch (a) {				//Wenn a
		case 1:						//gleich 1 ist
			x = x + rand;			//geht der Blitz nach rechts
			a = 2;					//und a wird auf 2 gesetzt, damit er das nächste mal nach links geht 
			break;
		case 2:						//wenn a gleich 2 ist
			x = x - rand;			//geht der Blitz nach links
			a = 1;					//und a wird auf 1 gesetzt
			break;
		}
	}								//so wird geschaut, dass der Blitz sich (fast) immer links - rechts bewegt

	//y - Koordinate festlegen
	public static void setY() {	
		int rand;
		yold = y;					// y wird in xold gespeichert (alte Koordinate)
		rand = (int) ((Math.random() * 25) + 25);	//Bereich der Zufallszahlen wird festgelget (25 - 50)
		y = y + rand;				//Koordinate wird bestimmt
		if (y > 700) {				// Wenn y grösser ist als 700
			y = 700;				// wird y auf 700 gesetzt (Boden)
		}
	}

	public PaintingLine() {			//Konstruktor
		super();
	}

	//Blitz zeichnen
	public void paint(Graphics g) {
		g.setColor(Color.BLACK);	//Farbe des Blitzes: Schwarz
		while (y < 700) {			// solange y < 700, also Blitz nicht am Boden
			setX();					//wird ein neues x bestimmt
			setY();					//wird ein neues y bestimmt
			g.drawLine(xold, yold, x, y);	//und mit den vier Koordinaten wird die Linie gezeichnet
		}
		x = 500;					//danach werden x und y wieder auf die Startposition gesetzt
		y = 0;						
	}
	
	//Main-Methode
	public static void main(String[] args) {
		setA();				//a(Links-Rechts)-Methode wird ausgeführt
		x = 500;			//x wird auf die Startposition gesetzt
		y = 0;				//y wird auf die Startposition gesetzt
		JFrame f = new JFrame("Blitz");		//Fenster wird geöffnet mit dem Titel Blitz
		f.setSize(1000, 700);			//Grösse des Fensters: 1000 x 700
		f.setResizable(false);		//Fenstergrösse kann nicht mehr geändert werden
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	//Schliessen wird ermöglicht
		f.getContentPane().add(new PaintingLine());		//dem Fenster wird die Zeichnung hinzugefügt
		f.setVisible(true);			//und es wird sichtbar gemacht
	}
}					//Ende
```


----------

