Katapult

Status
Nicht offen für weitere Antworten.

BlubBlub

Bekanntes Mitglied
ich versuche grad ein kleines spiel zu programmieren, aber es tritt irgendwo ein fehler auf den ich nicht verstehe. hier mein quellcode, das spiel ist aber noch nicht fertig,
da sind noch einige sachen zu korigieren und hinzuzufügen. es geht mir
lediglich um die zeilen 67-82.

wenn ich das spiel starte dann ist mein katapult plötzlich weg und das versteh ich nicht, denn wenn ich die paint methode (zeile 67 -82) durch die paint methode ersetze die im zweiten hier eingefügten javaquellcode ist, sowie die zeile 131 dem neuen methodenkopf anpasse, dann ist das katapult da wo es sein sollte, woran liegt das?


Java:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	VersuchePanel versuchsPanel = new VersuchePanel();
	KatapultCanvas katapultArea = new KatapultCanvas();
	
	MyFrame()
	{
		super("Ballistischer Wurf"); //Fenstername
		setSize(1000, 600); //Fenstergröße
		setResizable(false); //Größenänderung des Fensters nicht möglich
	
		getContentPane().setLayout(new BorderLayout());  //Layout wird gesetzt
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); //Fügt das VersuchePanel in den ContentPane im oberen Bereich ein
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(new SteuerPanel(versuchsPanel, katapultArea), BorderLayout.SOUTH);
		
		setVisible(true); //Fenster soll angezeigt werden
		setDefaultCloseOperation(EXIT_ON_CLOSE); //Fenster soll geschlossen und Programm beender werden beim drücken des Kreuzes
	}
}

class VersuchePanel extends JPanel
{
	int versucheAnzahl = 5;
	JLabel kraft = new JLabel("Versuche: " + versucheAnzahl);
		 
	VersuchePanel()
	{
		add(kraft);
	}
		
	public void set(int versucheAnzahl)
	{
		this.versucheAnzahl = versucheAnzahl;
		repaint();
	}
	public int get()
	{
		return versucheAnzahl;
	}
}
	
class KatapultCanvas extends Canvas
{		
	KatapultCanvas()
	{
		super();
		setBackground(Color.black); 
	}
	
	public void paint(Graphics g, int x, int eingegebeneKraft, int eingegebenerWinkel)
	{
		int posX = 50;
		int posY = getSize().height/2;
		Image img = getToolkit().getImage("katapult.gif");
		g.drawImage(img,posX, posY, this);
		
		x = 0;
		int y = (int)((-10*(Math.pow(x, 2)/100))/(2*Math.pow(eingegebeneKraft, 2)*Math.pow(Math.cos(eingegebenerWinkel * Math.PI/180), 2))+Math.tan(eingegebenerWinkel * Math.PI/180)*x);
		
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval(posX+40+x, getHeight()-(posY-14+y), 20, 20);
		
		g.setColor(Color.WHITE);
		g.fillOval(900, new Random().nextInt(480), 30, 30);
	} 
}


	
class SteuerPanel extends JPanel implements ActionListener, Runnable
{
	JButton start = new JButton("Start");
	JTextField kraftEingabe = new JTextField("50");
	JLabel kraft = new JLabel("Kraft:");
	JTextField  winkelEingabe = new JTextField("45");
	JLabel winkel = new JLabel("Winkel:");
	int eingegebeneKraft = 50;
	int eingegebenerWinkel = 45;
	VersuchePanel versuchsPanel;
	KatapultCanvas katapultArea;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultCanvas katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraft);
		add(kraftEingabe);
		add(winkel);
		add(winkelEingabe);
		add(start);
			
		kraftEingabe.addActionListener(this);
		kraftEingabe.setActionCommand("Newton");
		kraftEingabe.selectAll();
		winkelEingabe.addActionListener(this);
		winkelEingabe.setActionCommand("Grad");
		winkelEingabe.selectAll();
		start.addActionListener(this);
		start.setActionCommand("StartButton");
	}
	
	public void run()
	{
		for(int x = 1; x <= 825; x++)
		{	
			try 
			{ 
				Thread.sleep(50); 
			}
			catch(InterruptedException ie) {}
	         
		katapultArea.paint(getGraphics(), x, eingegebeneKraft, eingegebenerWinkel);
		}
	}
		
	public void actionPerformed(ActionEvent e)
	{
		 if(e.getActionCommand().equals("StartButton"))
		 {
			start.setEnabled(false);
			kraftEingabe.setEditable(false); 
			winkelEingabe.setEditable(false); 
			versuchsPanel.set(versuchsPanel.get() - 1);
			
			new Thread(this).start();
		 }
		 else
		{
			 String benutzerEingabe = ((JTextField)e.getSource()).getText(); 
			 boolean fehler = false;
			  
			 do
			 {	
				 try
				 {
					 if(e.getActionCommand().equals("Newton"))
						 eingegebeneKraft = Integer.parseInt(benutzerEingabe);
					 else if(e.getActionCommand().equals("Grad"))
						 eingegebenerWinkel = Integer.parseInt(benutzerEingabe);
					  
					 fehler = false;
				 }
				 catch(NumberFormatException n)
				 {
					fehler = true;
				 }
			  
				 if(fehler)
				 {
					 benutzerEingabe = ((JTextField)e.getSource()).getText(); 
				 }
			 }
			 while(fehler);
		}
	}	 
}

public class MainBallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}


Java:
public void paint(Graphics g)
	{
		int posX = 50;
		int posY = getSize().height/2;
		Image img = getToolkit().getImage("katapult.gif");
		g.drawImage(img,posX, posY, this);
		
                int eingegebeneKraft = 50;
                int eingegebenerWinkel = 45;

		int x = 0;
		int y = (int)((-10*(Math.pow(x, 2)/100))/(2*Math.pow(eingegebeneKraft, 2)*Math.pow(Math.cos(eingegebenerWinkel * Math.PI/180), 2))+Math.tan(eingegebenerWinkel * Math.PI/180)*x);
		
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval(posX+40+x, getHeight()-(posY-14+y), 20, 20);
		
		g.setColor(Color.WHITE);
		g.fillOval(900, new Random().nextInt(480), 30, 30);
	}
 
S

SlaterB

Gast
Canvas ist eine AWT-Komponente,
verwende ein JPanel aus Swing, und überschreibe dort paintComponent(Graphics g)

das Bild nur einmal laden, im Konstruktor z.B., nicht bei jedem paint
 

BlubBlub

Bekanntes Mitglied
ich hab den quellcode ein wenige umgeschrieben. aber wenn ich anstelle der Canvas von JPanel erbe (zeile 66) dann wird der hintergrund nicht auf schwarz gesetzt und das
gridlayout in zeile(120) beim untersten Panel wird nicht ausgeführt. :bahnhof:


Java:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	VersuchePanel versuchsPanel = new VersuchePanel();
	KatapultCanvas katapultArea = new KatapultCanvas(this);
	SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);
	
	MyFrame()
	{
		super("Ballistischer Wurf"); //Fenstername
		setSize(1000, 600); //Fenstergröße
		setResizable(false); //Größenänderung des Fensters nicht möglich
	
		getContentPane().setLayout(new BorderLayout());  //Layout wird gesetzt
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); //Fügt das VersuchePanel in den ContentPane im oberen Bereich ein
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(steuerung, BorderLayout.SOUTH);
		
		setVisible(true); //Fenster soll angezeigt werden
		setDefaultCloseOperation(EXIT_ON_CLOSE); //Fenster soll geschlossen und Programm beender werden beim drücken des Kreuzes
	}
	
	public SteuerPanel getSteuerPanel()
	{
		return this.steuerung;
	}
}

class VersuchePanel extends JPanel
{
	int versucheAnzahl = 5;
	JLabel versucheLabel = new JLabel("Versuche: " + versucheAnzahl);
		 
	VersuchePanel()
	{
		add(versucheLabel);
	}
		
	public void set(int versucheAnzahl)
	{
		this.versucheAnzahl = versucheAnzahl;
		repaint();
	}
	public int get()
	{
		return versucheAnzahl;
	}
}
	

class KatapultCanvas extends JPanel
{		
	int x = 0;
	SteuerPanel steuerung;

	
	KatapultCanvas(MyFrame frame)
	{
		super();
		setBackground(Color.black); 
		this.steuerung = frame.getSteuerPanel();
		
	}
	
	public void paint(Graphics g)
	{
		int posX = 50;
		int posY = getSize().height/2;
		
		Image img = getToolkit().getImage("katapult.gif");
		getGraphics().drawImage(img, posX, posY, this);
		
		int eingegebeneKraft = steuerung.getEingegebeneKraft();
		int eingegebenerWinkel = steuerung.getEingegebenerWinkel();
		
		int y = (int)((-10*(Math.pow(x, 2)/100))/(2*Math.pow(eingegebeneKraft, 2)*Math.pow(Math.cos(eingegebenerWinkel * Math.PI/180), 2))+Math.tan(eingegebenerWinkel * Math.PI/180)*x);
		
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval(posX+40+x, getHeight()-(posY-14+y), 20, 20);
		
		g.setColor(Color.WHITE);
		g.fillOval(900, new Random().nextInt(480), 30, 30);
		
		x++;
	} 
}

	
class SteuerPanel extends JPanel implements ActionListener, Runnable
{
	JButton start = new JButton("Start");
	JTextField kraftEingabe = new JTextField("50");
	JLabel kraft = new JLabel("Kraft:");
	JTextField  winkelEingabe = new JTextField("45");
	JLabel winkel = new JLabel("Winkel:");
	int eingegebeneKraft = 50;
	int eingegebenerWinkel = 45;
	VersuchePanel versuchsPanel;
	KatapultCanvas katapultArea;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultCanvas katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraft);
		add(kraftEingabe);
		add(winkel);
		add(winkelEingabe);
		add(start);
			
		kraftEingabe.addActionListener(this);
		kraftEingabe.setActionCommand("Newton");
		kraftEingabe.selectAll();
		winkelEingabe.addActionListener(this);
		winkelEingabe.setActionCommand("Grad");
		winkelEingabe.selectAll();
		start.addActionListener(this);
		start.setActionCommand("StartButton");
	}
	
	public int getEingegebeneKraft()
	{
		return this.eingegebeneKraft;
	}
	
	public int getEingegebenerWinkel()
	{
		return this.eingegebenerWinkel;
	}
	
	public void run()
	{
		for(int x = 1; x <= 825; x++)
		{	
			try 
			{ 
				Thread.sleep(50); 
			}
			catch(InterruptedException ie) {}
	         
			katapultArea.paint(getGraphics());
		}
	}
		
	public void actionPerformed(ActionEvent e)
	{
		 if(e.getActionCommand().equals("StartButton"))
		 {
			start.setEnabled(false);
			kraftEingabe.setEditable(false); 
			winkelEingabe.setEditable(false); 
			versuchsPanel.set(versuchsPanel.get() - 1);
			
			new Thread(this).start();
		 }
		 else
		{
			 String benutzerEingabe = ((JTextField)e.getSource()).getText(); 
			 boolean fehler = false;
			  
			 do
			 {	
				 try
				 {
					 if(e.getActionCommand().equals("Newton"))
						 eingegebeneKraft = Integer.parseInt(benutzerEingabe);
					 else if(e.getActionCommand().equals("Grad"))
						 eingegebenerWinkel = Integer.parseInt(benutzerEingabe);
					  
					 fehler = false;
				 }
				 catch(NumberFormatException n)
				 {
					fehler = true;
				 }
			  
				 if(fehler)
				 {
					 benutzerEingabe = ((JTextField)e.getSource()).getText(); 
				 }
			 }
			 while(fehler);
		}
	}	 
}

public class MainBallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}
 
S

SlaterB

Gast
ich sagte doch, du sollst
paintComponent(Graphics g)
überschreiben..,

gut, für den schwarzen Bildschirm hätte das auch nicht geholfen,
dafür muss
super.paintComponent(g); am Anfang von paintComponent(g) stehen

-------

> katapultArea.paint(getGraphics());
ist ganz falsch, niemals getGraphics() irgendwo aufrufen,
das Katapult kann mit dem Graphics-Objekt der Steuerung eh nix anfangen,

->
katapultArea.repaint();

-----

wie oft paintComponent() aufgerufen wird, kannst du nicht kontrollieren,
besser von der run-Schleife aus das x erhöhen, statt in paintComponent() x++;


---------

>KatapultCanvas(MyFrame frame)
> {
> super();
> setBackground(Color.black);
> this.steuerung = frame.getSteuerPanel();

funktioniert nicht, Katapult wird in MyFrame vor Steuerung definiert,
wenn also im Konstruktor von KatapultCanvas Steuerung von MyFrame abgefragt wird, ist steuerung noch null,

-> im Konstruktor gar nix machen in der Hinsicht, sondern später mit MyFrame-Konstruktor die Steuerung per setSteuerung() übergeben

--------

> getGraphics().drawImage(img, posX, posY, this);

->

g.drawImage(img, posX, posY, this);
 

BlubBlub

Bekanntes Mitglied
du hast ja zu beginn gesagt ich soll das katapult nicht jedes mal neu zeichen und soll
es im konstruktor erstellen. hab ich versucht, wie man meinem code jetzt entnehmen kann, aber irgendwie funktioniert das nicht, hab da wohl mal wieder was falsch gemacht.

hab jetzt auch die paintCompontent(Graphics g) Methode anstelle der paint(Graphics g)
Methode genommen.
Wenn ich nun in zeile 148 (in der run methode) katapultArea.repaint() aufrufe, dann wird mir ja mit diesem befehl die paintCompontent(Graphics g) Methode in zeile 87 welche im KatapultPanel ist, aufgerufen.
Nun hast du gesagt ich soll dass x nicht in der paintComponent(Graphics g) Methode erhöhen sondern in der run() Methode.
wie soll das gehen, kann ich anstelle von paintCompont(Graphics g) einfach paintComponent(Graphics g, int x) benutzen, und das x als Paramater mit übergeben, welches aus der for Schleife der run() Methode stammt?

Was ist eigentlich in dem Graphicsobjekt g gespeichert dass ich übergeben bekommen. und woher kommt das und auf was bezieht sich das?
das ist nehme ich an so wie bei public void actionPerformed(ActionEvent e) mit dem e wo ich zum beispiel auf den text zugreifen kann den ein benutzer über die tastatur eingegeben hat.


und das versteh ich nicht so ganz, wie ich dieses problem lösen soll. hab jetzt die ganze zeit drüber gegrübelt, aber so langsam gehn mir einfach die ideen aus. hab auch
erst mit GUIs angefangen also hab ich da nicht soviel erfahrung mit.
------------------------------------------------------------------------------------
>KatapultCanvas(MyFrame frame)
> {
> super();
> setBackground(Color.black);
> this.steuerung = frame.getSteuerPanel();

funktioniert nicht, Katapult wird in MyFrame vor Steuerung definiert,
wenn also im Konstruktor von KatapultCanvas Steuerung von MyFrame abgefragt wird, ist steuerung noch null,

-> im Konstruktor gar nix machen in der Hinsicht, sondern später mit MyFrame-Konstruktor die Steuerung per setSteuerung() übergeben

--------




Java:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	private VersuchePanel versuchsPanel = new VersuchePanel();
	private KatapultPanel katapultArea = new KatapultPanel(this);
	private SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);
	
	MyFrame()
	{
		super("Ballistischer Wurf"); 
		setSize(1000, 600); 
		setResizable(false); 
	
		getContentPane().setLayout(new BorderLayout());  
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); 
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(steuerung, BorderLayout.SOUTH);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
	
	public SteuerPanel getSteuerPanel()
	{
		return this.steuerung;
	}
}

class VersuchePanel extends JPanel
{
	private int versucheAnzahl = 5;
	private JLabel versucheLabel = new JLabel("Versuche: " + versucheAnzahl);
		 
	VersuchePanel()
	{
		add(versucheLabel);
	}
		
	public void set(int versucheAnzahl)
	{
		this.versucheAnzahl = versucheAnzahl;
		repaint();
	}
	public int get()
	{
		return versucheAnzahl;
	}
}
	

class KatapultPanel extends JPanel
{		
	private int x = 0;
	private int posX = 50;
	private int posY = getSize().height/2;
	MyFrame frame;
	
	KatapultPanel(MyFrame frame)
	{
		super();	
		setBackground(Color.black); 
		
		this.frame = frame;
		
		getGraphics().setColor(Color.WHITE);
		getGraphics().fillOval(900, new Random().nextInt(480), 30, 30);
		
		Image img = getToolkit().getImage("katapult.gif");
		getGraphics().drawImage(img, posX, posY, this);
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		int eingegebeneKraft = frame.getSteuerPanel().getEingegebeneKraft();
		int eingegebenerWinkel = frame.getSteuerPanel().getEingegebenerWinkel();
		
		int y = (int)((-10*(Math.pow(x, 2)/100))/(2*Math.pow(eingegebeneKraft, 2)*Math.pow(Math.cos(eingegebenerWinkel * Math.PI/180), 2))+Math.tan(eingegebenerWinkel * Math.PI/180)*x);
		
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval(posX+40+x, getHeight()-(posY-14+y), 20, 20);
	
		x++;
	} 
}

	
class SteuerPanel extends JPanel implements ActionListener, Runnable
{
	private JButton start = new JButton("Start");
	private JTextField kraftEingabe = new JTextField("50");
	private JLabel kraft = new JLabel("Kraft:");
	private JTextField  winkelEingabe = new JTextField("45");
	private JLabel winkel = new JLabel("Winkel:");
	private int eingegebeneKraft = 50;
	private int eingegebenerWinkel = 45;
	private VersuchePanel versuchsPanel;
	private KatapultPanel katapultArea;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultPanel katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraft);
		add(kraftEingabe);
		add(winkel);
		add(winkelEingabe);
		add(start);
			
		kraftEingabe.addActionListener(this);
		kraftEingabe.setActionCommand("Newton");
		kraftEingabe.selectAll();
		winkelEingabe.addActionListener(this);
		winkelEingabe.setActionCommand("Grad");
		winkelEingabe.selectAll();
		start.addActionListener(this);
		start.setActionCommand("StartButton");
	}
	
	public void run()
	{
		for(int x = 1; x <= 825; x++)
		{	
			try 
			{ 
				Thread.sleep(50); 
			}
			catch(InterruptedException ie) {}
	         
			katapultArea.repaint();
		}
	}
		
	public void actionPerformed(ActionEvent e)
	{
		 if(e.getActionCommand().equals("StartButton"))
		 {
			start.setEnabled(false);
			kraftEingabe.setEditable(false); 
			winkelEingabe.setEditable(false); 
			versuchsPanel.set(versuchsPanel.get() - 1);
			
			new Thread(this).start();
		 }
		 else
		{
			 String benutzerEingabe = ((JTextField)e.getSource()).getText(); 
			 boolean fehler = false;
			  
			 do
			 {	
				 try
				 {
					 if(e.getActionCommand().equals("Newton"))
						 eingegebeneKraft = Integer.parseInt(benutzerEingabe);
					 else if(e.getActionCommand().equals("Grad"))
						 eingegebenerWinkel = Integer.parseInt(benutzerEingabe);
					  
					 fehler = false;
				 }
				 catch(NumberFormatException n)
				 {
					fehler = true;
				 }
			 }
			 while(fehler);
		}
	}
	
	public int getEingegebeneKraft()
	{
		return this.eingegebeneKraft;
	}
	
	public int getEingegebenerWinkel()
	{
		return this.eingegebenerWinkel;
	}
}

public class MainBallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}
 
S

SlaterB

Gast
> du hast ja zu beginn gesagt ich soll das katapult nicht jedes mal neu zeichen und soll
es im konstruktor erstellen. hab ich versucht, wie man meinem code jetzt entnehmen kann, aber irgendwie funktioniert das nicht

nur das Img-Objekt einmal anfangs laden und in einem Klassenattribut speichern,
dessen Zeichnen sowie alle anderen Graphics-Aufrufe weiterhin in paintComponent

und immer noch:
niemals getGraphics() aufrufen, wenn du nocheinmal Code damit postest, antworte ich nicht mehr ;)

-----

> wie soll das gehen, kann ich anstelle von paintCompont(Graphics g) einfach paintComponent(Graphics g, int x) benutzen, und das x als Paramater mit übergeben,

es muss doch nicht alles auf einmal passieren:
katapult.setX(x); // x wird in Katapult intern gespeichert
katapult.repaint();

> Was ist eigentlich in dem Graphicsobjekt g gespeichert dass ich übergeben bekommen. und woher kommt das und auf was bezieht sich das?

entweder ignorieren (malen nur in paint/ paintComponent, g kommt von irgendwoher, damit malen, wird schon klappen)
oder dicke Bücher/ Tutorials lesen ;)

--------

>KatapultCanvas(MyFrame frame)
> {
> super();
> setBackground(Color.black);
> this.steuerung = frame.getSteuerPanel();

Java:
class MyFrame
    extends JFrame
{
    VersuchePanel versuchsPanel = new VersuchePanel();
    KatapultCanvas katapultArea = new KatapultCanvas();
    SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);

    MyFrame()
    {
        super("Ballistischer Wurf"); // Fenstername

        katapultArea.setSteuerung(steuerung);
[..]



class KatapultCanvas
    extends JPanel
{
    int x = 0;
    SteuerPanel steuerung;


    KatapultCanvas()
    {
        super();
        setBackground(Color.black);
    }

    public void setSteuerung(SteuerPanel steuerung)
    {
        this.steuerung = steuerung;
    }
[..]
 

BlubBlub

Bekanntes Mitglied
hehe, okay ich lasse die getGraphics() weg^^ , aber ich dachte die ganze zeit dass getGraphics() mir dasselbe Graphics Objekt liefert , wie in der paintComponentent(Graphics g) Methode aufgerufen wird. darum hab ich das im konstruktor des KatapultPanels benutzt. aber ich glaub allein das graphics objekt reicht nicht aus, so wies ausschaut braucht man auch die paintComponent() methode um zeichen zu könnne. ich stelle mir das einfach so vor das Graphics objekt ist der Stift mit dem gezeichnet wird, die paintComponent(Graphics g) methode ist der künstler der diesen stift in die hand gedrückt bekommt und zeichnet und das Panel ist seine Zeichenfläche :p
wenn ich im steuerpanel das getGraphics() aufrugen würde , würde ich da ein anderes graphicsobjekt bekommen als wenn ich es im katapult panel aufrufen würde? also könnte ich die beiden graphichs objekte voneinander unterscheiden wenn ich sie vergleichen würde mit einer vergleichsmethode?

nun hab ich also wiedermals ein paar veränderungen im code gemacht:
da ist mal wieder was was ich nicht verstehe ^^ und zwar wenn man die zeilen
65,66 und 86,87 betrachtet. mein katapult soll unten links sein. das ist es auch wenn ich die beiden varibalen in die zeilen 86, 87 lege. wenn ich sie aber anstelle dessen
nach oben verlege in die zeilen 65, 66 ist mein katapult oben links in der ecke.
warum ???:L



Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	private VersuchePanel versuchsPanel = new VersuchePanel();
	private KatapultPanel katapultArea = new KatapultPanel();
	private SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);
	
	MyFrame()
	{
		super("Ballistischer Wurf"); 
		setSize(1000, 600); 
		setResizable(false); 
	
		getContentPane().setLayout(new BorderLayout());  
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); 
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(steuerung, BorderLayout.SOUTH);
		
		katapultArea.setSteuerung(steuerung);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}

class VersuchePanel extends JPanel
{
	private int versucheAnzahl = 5;
	private JLabel versucheLabel = new JLabel("Versuche: " + versucheAnzahl);
		 
	VersuchePanel()
	{
		add(versucheLabel);
	}
		
	public void set(int versucheAnzahl)
	{
		this.versucheAnzahl = versucheAnzahl;
		repaint();
	}
	public int get()
	{
		return versucheAnzahl;
	}
}
	

class KatapultPanel extends JPanel
{		
	private int x = 0;
	//private int posX = 50;
	//private int posY = getSize().height/2;
	private SteuerPanel steuerung;
	private Image img = getToolkit().getImage("katapult.gif");
	private int randomInt = new Random().nextInt(480);
	
	KatapultPanel()
	{
		super();	
		setBackground(Color.black); 
	}
	
	public void setSteuerung(SteuerPanel steuerung)
	{
		this.steuerung = steuerung;
	}

	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		int posX = 50;
		int posY = getSize().height/2;
		
		g.drawImage(img, posX, posY, this);
		
		int eingegebeneKraft = steuerung.getEingegebeneKraft();
		int eingegebenerWinkel = steuerung.getEingegebenerWinkel();
		
		int y = (int)((-10*(Math.pow(x, 2)/100))/(2*Math.pow(eingegebeneKraft, 2)*Math.pow(Math.cos(eingegebenerWinkel * Math.PI/180), 2))+Math.tan(eingegebenerWinkel * Math.PI/180)*x);
		
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval(posX+40+x, getHeight()-(posY-14+y), 20, 20);
		
		g.setColor(Color.WHITE);
		g.fillOval(900, randomInt, 30, 30);
	} 
	
	public void setX()
	{
		this.x++;
	}
}

	
class SteuerPanel extends JPanel implements ActionListener, Runnable
{
	private JButton start = new JButton("Start");
	private JTextField kraftEingabe = new JTextField("50");
	private JLabel kraft = new JLabel("Kraft:");
	private JTextField  winkelEingabe = new JTextField("45");
	private JLabel winkel = new JLabel("Winkel:");
	private int eingegebeneKraft = 50;
	private int eingegebenerWinkel = 45;
	private VersuchePanel versuchsPanel;
	private KatapultPanel katapultArea;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultPanel katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraft);
		add(kraftEingabe);
		add(winkel);
		add(winkelEingabe);
		add(start);
			
		kraftEingabe.addActionListener(this);
		kraftEingabe.setActionCommand("Newton");
		kraftEingabe.selectAll();
		winkelEingabe.addActionListener(this);
		winkelEingabe.setActionCommand("Grad");
		winkelEingabe.selectAll();
		start.addActionListener(this);
		start.setActionCommand("StartButton");
	}
	
	public void run()
	{
		for(int x = 1; x <= 825; x++)
		{	
			try 
			{ 
				Thread.sleep(100); 
			}
			catch(InterruptedException ie) {}
	         
			katapultArea.setX();
			katapultArea.repaint();
		}
	}
		
	public void actionPerformed(ActionEvent e)
	{
		 if(e.getActionCommand().equals("StartButton"))
		 {
			start.setEnabled(false);
			kraftEingabe.setEditable(false); 
			winkelEingabe.setEditable(false); 
			versuchsPanel.set(versuchsPanel.get() - 1);
			
			new Thread(this).start();
		 }
		 else
		{
			 String benutzerEingabe = ((JTextField)e.getSource()).getText(); 
			 boolean fehler = false;
			  
			 do
			 {	
				 try
				 {
					 if(e.getActionCommand().equals("Newton"))
						 eingegebeneKraft = Integer.parseInt(benutzerEingabe);
					 else if(e.getActionCommand().equals("Grad"))
						 eingegebenerWinkel = Integer.parseInt(benutzerEingabe);
					  
					 fehler = false;
				 }
				 catch(NumberFormatException n)
				 {
					fehler = true;
				 }
			 }
			 while(fehler);
		}
	}
	
	public int getEingegebeneKraft()
	{
		return this.eingegebeneKraft;
	}
	
	public int getEingegebenerWinkel()
	{
		return this.eingegebenerWinkel;
	}
}

public class MainBallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}
 
S

SlaterB

Gast
> würde ich da ein anderes graphicsobjekt bekommen als wenn ich es im katapult panel aufrufen würde? also könnte ich die beiden graphichs objekte voneinander unterscheiden wenn ich sie vergleichen würde mit einer vergleichsmethode?

wie gesagt, einfach nicht drüber nachdenken,
z.B. vom Worstcase ausgehen, mal ist es dasselbe Objekt, mal nicht, mal null, alles zufällig,
völlig schnuppe, nur in paintComponent zeichnen, dann gibts keine Probleme

> da ist mal wieder was was ich nicht verstehe ^^ und zwar wenn man die zeilen 65,66 und 86,87 betrachtet.

in Zeile 65 ist das JPanel noch nicht auf dem Bildschirm zu sehen und von einem Layoutmanager korrekt eingerichtet,
ergo liefert getSize() 0,0 oder sonst was komisches, statt später z.B. 100,100
 

BlubBlub

Bekanntes Mitglied
>in Zeile 65 ist das JPanel noch nicht auf dem Bildschirm zu sehen und von einem Layoutmanager korrekt eingerichtet,
ergo liefert getSize() 0,0 oder sonst was komisches, statt später z.B. 100,100


hmm, das versteh ich nicht, wie baut sich das fenster denn auf. ich kann
mir das grad gar nicht vorstellen, wieso in zeile 65 das fenster nicht exisitert und in zeile
86 ist es da ???:L

wie funktioniert das bei meinem programm überhaupt.
ich erzeuge ja in der main funtkion ein objekt von MyFrame ohne es irgendeiner variablen zu zuweisen. also wird myFrame() erstellt. jetzt würd ich mir einfach vorstellen dass das
Haupftenster aufgebaut wird. da als erste attribut eine variabel vom typ versuchspanel aufgelistet ist, wird in das hauptfenster zuerst das versuchspanel eingefügt.
danach das Katapultpanel, da es als zweites steht und dann wird das steuerpanel eingefügt oder so
 
S

SlaterB

Gast
das Fenster wird (grob gesehen) erst dann aufgebaut, wenn setVisible(true) ausgeführt wird,
vorher sind keine Größen berechnet, Listener können nicht reagieren (da nix da ist, worauf eine Maus klicken könnte), paint wird nicht aufgerufen, selbst wenn man selber repaint() auslöst, getGraphics() würde übrigens null liefern, usw.

danach ist ein ganz andere Welt aktiv

zwischen Zeile 65 und Zeile 86 liegt ne Menge andere Code, auch in den anderen Klassen,
schaue dir genau die Abläufe an
 

BlubBlub

Bekanntes Mitglied
hmm versteh ich immernoch nicht so ganz.

woran erkenn ich denn wo ich welche variable intiliasierien soll, damit die sachen dort
gezeichnet werden wo ich will.
ich erkenne nicht, warum es bei initialisierung außerhalb der paint methode
eine andere ausgabe auf dem panel gibt als bei der initialisierung innerhalb der paint methode.
ich hab ja eine randomInt varialbe außerhalb der paint methode initialisiert, und die verwende ich in der paint methode zum zeichen des weißen zielkreises.
der kreis wird beim start des programms so wies sein soll zufällig an einem festen x wert in einer zufälligen höhe gezeichnet.
wenn ich das randomInt innerhalb der methode intialisiere müßte es der kreis sich ja dann anders verhalten als wenn ich sie aussen initialisiere, weil es bei
//int posX = 50;
//int posY = getSize().height/2;
ja auch einen unterschied macht wo sie initialisiert werden.
 
S

SlaterB

Gast
Random ist nicht setVisible(true) abhängig,
wie man das erkennt?
mit einem Kopf zum Denken, ohne den geht's nicht,

wenn man die Größe einer Liste abfragt, bevor man sie befüllt, erhält man als Ergebnis 0,
fragt man die Größe dagegen später ab, kommt vielleicht 10 raus,
wenn du das nicht begreifst, kann ich auch nicht helfen,

getSize() ist eine Methode, die vom Layout abhängt,
anfangs 0,0, nach der Initialisiertung vielleicht 100,100,
wenn der Benutzer die Größe der Anwendung verkleinert (Rahmen ziehen) irgendwann vielleicht nur noch 30,30
 

BlubBlub

Bekanntes Mitglied
achso jetzt hats klick gemacht, ich hab den wald vor lauter bäumen gar nicht gesehen.
stimmt das getSize() das hab ich eben wohl übersehen. jetzt macht das alles einen sinn.
dumme frage :p
 

BlubBlub

Bekanntes Mitglied
hi nochmals, ich wollt jetzt dem benutzer ermöglichen bei einer fehleingabe beim winkel oder bei der kraft seine eingabe zu korrigieren. dabei soll zunächst ein text im jpanel ausgegeben werden dass er eine falsche eingabe getätigt hat und dann soll er wieder eine erneute eingabe machen können. solange er keine zulässige eingabe durchführt soll das programm nicht weiter arbeiten.

wie kann ich denn bei jtextfield eine erneute eingabe erstellen? schaut euch mal meinen code an was müsste ich da verändern?

Java:
class SteuerPanel extends JPanel implements ActionListener, Runnable
{
	private JButton start = new JButton("Start");
	private JTextField kraftEingabe = new JTextField("50");
	private JLabel kraft = new JLabel("Kraft:");
	private JTextField  winkelEingabe = new JTextField("45");
	private JLabel winkel = new JLabel("Winkel:");
	private int eingegebeneKraft = 50;
	private int eingegebenerWinkel = 45;
	private VersuchePanel versuchsPanel;
	private KatapultPanel katapultArea;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultPanel katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraft);
		add(kraftEingabe);
		add(winkel);
		add(winkelEingabe);
		add(start);
			
		kraftEingabe.addActionListener(this);
		kraftEingabe.setActionCommand("Newton");
		kraftEingabe.selectAll();
		winkelEingabe.addActionListener(this);
		winkelEingabe.setActionCommand("Grad");
		winkelEingabe.selectAll();
		start.addActionListener(this);
		start.setActionCommand("StartButton");
	}
	
	public void run()
	{
		for(int x = 1; x <= 825; x++)
		{	
			try 
			{ 
				Thread.sleep(5); 
			}
			catch(InterruptedException ie) {}
	         
			katapultArea.setX();
			katapultArea.repaint();
		}
	}
		
	public void actionPerformed(ActionEvent e)
	{
		 if(e.getActionCommand().equals("StartButton"))
		 {
			start.setEnabled(false);
			kraftEingabe.setEditable(false); 
			winkelEingabe.setEditable(false); 
			versuchsPanel.set(versuchsPanel.get() - 1);
			
			new Thread(this).start();
		 }
		 else
		{
			 String benutzerEingabe = ((JTextField)e.getSource()).getText(); 
			 boolean fehler = false;
			  
			 do
			 {	
				 
				 try
				 {
					 if(e.getActionCommand().equals("Newton"))
						 eingegebeneKraft = Integer.parseInt(benutzerEingabe);
					 else if(e.getActionCommand().equals("Grad"))
						 eingegebenerWinkel = Integer.parseInt(benutzerEingabe);
					  
					 fehler = false;
				 }
				 catch(NumberFormatException n)
				 {
					kraftEingabe.setText("Fehler - Bitte Erneute Eingabe!");
					winkelEingabe.setText("Fehler - Bitte Erneute Eingabe!");
					fehler = true;
				 }
			 }
			 while(fehler);
		}
	}
}
 
Zuletzt bearbeitet:

BlubBlub

Bekanntes Mitglied
also so langsam nimmt das programm ganz gute formen an.
wenn die kugel ihr ziel trifft oder unterhalbs des fensters bzw rechts vom fenster landet soll der thread aufhören und ein fenster soll erscheinen , je nach dem ob man gewonnen oder verloren hat erscheint ein "du hast gewonnen fenster" oder "du hast verloren fenster" ^^ . dazu hab ich in meinem katapult panel ein attribut boolean unterbrecheThread eingeführt. (siehe zeilen 100, 131, 137, 233) doch aus irgendeinem grund wird mir das fenster mehrmals ausgegeben , manchmal zweimal, manchmal dreimal, warum funktioniert das nicht?


Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	private VersuchePanel versuchsPanel = new VersuchePanel();
	private KatapultPanel katapultArea = new KatapultPanel();
	private SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);
	
	MyFrame()
	{
		super("Ballistischer Wurf"); 
		setSize(1000, 600); 
		setResizable(false); 
	
		getContentPane().setLayout(new BorderLayout());  
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); 
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(steuerung, BorderLayout.SOUTH);
		
		katapultArea.setSteuerung(steuerung);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}


class WinFrame extends JFrame
{
	WinFrame()
	{
		super("Gewonnen");
		setSize(250, 250);
		setResizable(false);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}

class LooseFrame extends JFrame
{
	LooseFrame()
	{
		super("Verloren");
		setSize(250, 250);
		setResizable(false);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}

class VersuchePanel extends JPanel
{
	private int versucheAnzahl = 5;
	private JLabel versucheLabel = new JLabel("Versuche: " + versucheAnzahl);

	VersuchePanel()
	{
		add(versucheLabel);
	}
		
	public void set(int versucheAnzahl)
	{
		this.versucheAnzahl = versucheAnzahl;
		repaint();
	}
	public int get()
	{
		return versucheAnzahl;
	}
	
	public void paintComponent(Graphics g)
	{

	}
}
	

class KatapultPanel extends JPanel
{		
	private int x = 0;
	private SteuerPanel steuerung;
	private Image img = getToolkit().getImage("katapult.gif");
	private int randomInt = new Random().nextInt(480);
	private boolean unterbrecheThread = false;
	
	KatapultPanel()
	{	
		setBackground(Color.black); 
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		int posX = 50;
		int posY = getSize().height/2;
		
		g.drawImage(img, posX, posY, this);
		
		int kraftInput = steuerung.getKraftInput();
		int winkelInput = steuerung.getWinkelInput();
		
		int y = (int)((-9.81*(Math.pow(x, 2)))/(2*Math.pow(kraftInput, 2)*Math.pow(Math.cos(winkelInput * (Math.PI/180) ), 2))+Math.tan(winkelInput * (Math.PI/180) )*x);
		
		g.setColor(Color.LIGHT_GRAY);
		g.fillOval(posX+40+x, getHeight()-(posY-14+y), 20, 20);
		
		g.setColor(Color.WHITE);
		g.fillOval(900, randomInt, 30, 30);
		
		g.setClip(posX+40+x, getHeight()-(posY-14+y), 20, 20);
		if(g.hitClip(900, randomInt, 30, 30))
		{
			new WinFrame();
			unterbrecheThread = true;
		}
		
		if( (getHeight()-(posY-14+y)) > getHeight() || (posX+40+x) > getWidth() )
		{
			new LooseFrame();
			unterbrecheThread = true;
		}
	} 
	
	public void setSteuerung(SteuerPanel steuerung)
	{
		this.steuerung = steuerung;
	}
	
	public void setX()
	{
		this.x++;
	}
	
	public boolean getUnterbrecheThread()
	{
		return unterbrecheThread;
	}
}

	
class SteuerPanel extends JPanel 
{
	private JButton start = new JButton("Start");
	private JTextField kraftInputField = new JTextField("50");
	private JLabel kraftLabel = new JLabel("Kraft:");
	private int kraftInput = 50;
	private JTextField  winkelInputField = new JTextField("45");
	private JLabel winkelLabel = new JLabel("Winkel:");
	private int winkelInput = 45;
	private VersuchePanel versuchsPanel;
	private KatapultPanel katapultArea;
	private boolean fehler = false;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultPanel katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraftLabel);
		add(kraftInputField);
		add(winkelLabel);
		add(winkelInputField);
		add(start);
	
		kraftInputField.setActionCommand("Newton");
		kraftInputField.selectAll();
		winkelInputField.selectAll();
		start.addActionListener(new ButtonListener());
		start.setActionCommand("StartButton");
	}
	
	class ButtonListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			fehler = false;
			
			try
			{
				setInput();
					
				if(kraftInput < 0)
				{
					kraftInputField.setText("Nur positive Zahlen zulässig!");
					fehler = true;
				}
				
				if(winkelInput > 90 || winkelInput < 0)
				{
					winkelInputField.setText("Nur Winkel 0°-90°zulässig!");
					fehler = true;
				}
			 }
			 catch(NumberFormatException n)
			 {
				kraftInputField.setText("Mach den Text");
				winkelInputField.setText("jetzt weg du Troll!!!");
				
				fehler = true;
			 }
			
			if(!fehler)
			{
				start.setEnabled(false);
				kraftInputField.setEditable(false); 
				winkelInputField.setEditable(false); 
				versuchsPanel.set(versuchsPanel.get() - 1);
			
				new Thread(new Runnable()
								{
									public void run()
									{
										int x = 1;
										while(!katapultArea.getUnterbrecheThread())
										{
											try 
											{ 
												Thread.sleep(5); 
											}
											catch(InterruptedException ie) {}
											
											katapultArea.setX();
											katapultArea.repaint();
											x++;
										}
									}
								}).start();
			}
			else 
			{
				kraftInputField.selectAll();
				winkelInputField.selectAll();
			}
		}
	}
	
    private void setInput()
    {
        kraftInput = Integer.parseInt(kraftInputField.getText());
        winkelInput = Integer.parseInt(winkelInputField.getText());
    }
	
	public int getKraftInput()
	{
		return this.kraftInput;
	}
	
	public int getWinkelInput()
	{
		return this.winkelInput;
	}
}

public class BallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}
 

Schandro

Top Contributor
ganz einfach: Man darf in paintComponent NUR Malen! Nichts anderes!

Du musst das erstellen des Win/Loose-JFrames und das verändern der Membervariable woanders machen (im Thread?!..)
 

BlubBlub

Bekanntes Mitglied
das verursacht ein ganz schön großes problem wenn ich die membervariablen nicht in der paint methode verändern kann, weil dann kann ich das schöne konzept mit

[XML]g.setClip(posX+40+x, getHeight()-(posY-14+y), 20, 20);
if(g.hitClip(900, randomInt, 30, 30))
{
new WinFrame();
unterbrecheThread = true;
}[/XML]

gar nicht verwenden. aber ich brauche unbedingt die information von g.hitClip() ob der stein das ziel getroffen hat. und von der run methode aus weiß ich nicht wie ich die abfrage mit hitClip() machen soll, weil hitClip() muss ja aufjedenfall in der paintmethode stehen wegen dem g objekt. das war die einzige idee die ich hatte wie ich rausfinde ob stein und ziel sich berühren. wenn ich die information hätte dann wärs kein problem die fenster aus der run methode aus aufzurufen.
 
S

SlaterB

Gast
die Position, Länge und Breite des Katapult-Panels kannst du auch vom Thread aus abfragen,
zwar können sich diese Daten ändern und sind vielleicht erst nach dem ersten paint vorhanden,
aber da wird sowieso noch kein win vorliegen,
danach dann ist run() für Ortsberechnungen nicht schlechter geeignet als paintCoponent(),

hitClip() kannst du natürlich nicht verwenden, aber was kann das auch schon groß?
if (posX+breiteX > breiteDesPanels) {
}
kannst du auch in run berechnen
 

BlubBlub

Bekanntes Mitglied
naja hitclip ist hier schon sehr hilfreich, weil meinen stein hab ich ja mit g.fillOval()
erstellt und meinen ziel genauso.

und das spiel ist ja schon gewonnen wenn der stein das ziel nur ein wenig berührt, und mit hitclip wird mir jedes mal überprüft ob sich die flächen vom stein und vom zielobjekt irgendwo schneiden.


>hitClip() kannst du natürlich nicht verwenden, aber was kann das auch schon groß?
if (posX+breiteX > breiteDesPanels) {
}

ich nehme mal an breiteX ist der durchmesser des steines oder?
breiteDesPanels, die ist ja dann konstant 1000 bei mir.

posX + breiteX > breiteDesPanels
übprüft mir ja nicht ob der stein und das ziel sich irgendwo schneiden.
zudem wäre bei dieser formel posX + breiteX immer kleiner als der Panel, außer wenn der stein über das panel hinausläuft (ich weiß nicht ob die berechnung weiter geht wenn die kugel ausserhalbe des panels ist oder automatisch abbricht, aber selbst wenn sie weiter läuft und die breitesDesPanels < posX+breiteX ist dann kann ich damit lediglich überprüfen ob mein stein am ziel schon vorbeigeschossen ist)
 
Zuletzt bearbeitet:

Schandro

Top Contributor
Guck dir mal die Klasse "Shape" wegen den Kollisionsabfragen an. Den Stein kannst du z.b. mit dem Shape "Ellipse2D.Double" darstellen.
 

BlubBlub

Bekanntes Mitglied
nee in der klasse ist nichts mit kolisionsabfrage. hab mir ne mathematische gleichung ausgedacht, aber sieht total unschön aus wenn man sie ausprogrammiert. eine klasse mit der ich kolisionsabfrage machen könnte wäre da echt optimal, so langsam schlaucht mich das programm ein wenig.
 

Michael...

Top Contributor
Deswegen der Hinweis von Schandro. Wenn Du Deine Objekte von der Klasse Shape ableitest kannst deren Methode ixxxx zur Kollisionsabfrage nutzen.
 

BlubBlub

Bekanntes Mitglied
ich hab ein weiters problem: in meinem hauptfesnter also im frame sind drei panels. im obersten
ist ein zähler, der zählt wie oft ich den stein schon katapultiert habe(nocht nicht fertig programmiert), im zweiten panel da wird das katapult gezeichnet und der stein und das ziel und im dritten panel kann ich den winkel und die kraft einstellen mit welcher der stein fliegt. problem ist jetzt, sobald der stein losfliegt verzerrt bzw verschwindet das dritte panel einfach. zudem wird der stein verzerrt sobal er den rand berührt.
was hab ich falsch gemacht?

siehe zeile 119 (katapultpanel) folgende und zeile 263 (runmethode) folgende

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	private VersuchePanel versuchsPanel = new VersuchePanel();
	private KatapultPanel katapultArea = new KatapultPanel();
	private SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);
	
	MyFrame()
	{
		super("Ballistischer Wurf"); 
		setSize(1000, 600); 
		setResizable(false); 
	
		getContentPane().setLayout(new BorderLayout());  
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); 
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(steuerung, BorderLayout.SOUTH);
		
		katapultArea.setSteuerung(steuerung);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}


class WinFrame extends JFrame
{
	JButton okButton = new JButton("Ja");
	JButton beendenButton = new JButton("Beenden");
	JLabel infoLabel = new JLabel("Wollen sie das Spiel wiederholen?");
	JPanel bunkerPanel = new JPanel();
	
	WinFrame()
	{
		super("Gewonnen");
		setSize(250, 250);
		setResizable(false);
		
		bunkerPanel.setLayout(new GridLayout(1, 2));
		bunkerPanel.add(okButton);
		bunkerPanel.add(beendenButton);
		
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(infoLabel, BorderLayout.NORTH);
		getContentPane().add(bunkerPanel, BorderLayout.CENTER);
				
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}

class LooseFrame extends JFrame
{
	JButton okButton = new JButton("Ja");
	JButton beendenButton = new JButton("Nein");
	
	LooseFrame()
	{
		super("Verloren");
		setSize(250, 150);
		setResizable(false);
		
		getContentPane().setLayout(new FlowLayout());
		getContentPane().add(new JLabel("Wollen Sie das Spiel wiederholen?"));
		getContentPane().add(okButton);
		getContentPane().add(beendenButton);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}

class VersuchePanel extends JPanel
{
	private int versucheAnzahl = 5;
	private JLabel versucheLabel = new JLabel("Versuche: " + versucheAnzahl);

	VersuchePanel()
	{
		add(versucheLabel);
	}
		
	public void set(int versucheAnzahl)
	{
		this.versucheAnzahl = versucheAnzahl;
		repaint();
	}
	public int get()
	{
		return versucheAnzahl;
	}
	
	public void paintComponent(Graphics g)
	{

	}
}
	

class KatapultPanel extends JPanel
{		
	private SteuerPanel steuerung;
	private int kraftInput;
	private int winkelInput;
	private int posX = 50; //position des katapults
	private int posY = 258; //position des katapults
	private int x = 0; // 
	private int y = 0; // dieser koordinaten urpsrung liegt beim stein 
	private Image img = getToolkit().getImage("katapult.gif");
	private int randomInt = new Random().nextInt(480);
	
	KatapultPanel()
	{	
		setBackground(Color.black); 
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		this.kraftInput = steuerung.getKraftInput();
		this.winkelInput = steuerung.getWinkelInput();
			
		g.drawImage(img, posX, posY, this);
		
		g.setColor(Color.LIGHT_GRAY); //stein
		g.fillOval(posX+40+x, posY-14-y, 20, 20); //stein
		
		g.setColor(Color.WHITE); //ziel
		g.fillOval(900, randomInt, 30, 30); //ziel
	} 
	
	public int getRandomInt()
	{
		return this.randomInt;
	}
	
	public void setSteuerung(SteuerPanel steuerung)
	{
		this.steuerung = steuerung;
	}
	
	public void setX()
	{
		this.x++;
	}
	
	public void setY()
	{
		this.y = (int)((-9.81*(Math.pow(x, 2)))/(2*Math.pow(kraftInput, 2)*Math.pow(Math.cos(winkelInput * (Math.PI/180) ), 2))+Math.tan(winkelInput * (Math.PI/180) )*x);
	}
	
	public int getX()
	{
		return this.x;
	}
	
	public int getY()
	{
		return this.y;
	}
	
	public int getPosX()
	{
		return this.posX;
	}
	
	public int getPosY()
	{
		return this.posY;
	}
}

	
class SteuerPanel extends JPanel 
{
	private JButton start = new JButton("Start");
	private JTextField kraftInputField = new JTextField("50");
	private JLabel kraftLabel = new JLabel("Kraft:");
	private int kraftInput = 50;
	private JTextField  winkelInputField = new JTextField("45");
	private JLabel winkelLabel = new JLabel("Winkel:");
	private int winkelInput = 45;
	private VersuchePanel versuchsPanel;
	private KatapultPanel katapultArea;
	private boolean fehler = false;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultPanel katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		setLayout(new GridLayout(1, 5));
		
		add(kraftLabel);
		add(kraftInputField);
		add(winkelLabel);
		add(winkelInputField);
		add(start);
	
		kraftInputField.setActionCommand("Newton");
		kraftInputField.selectAll();
		winkelInputField.selectAll();
		start.addActionListener(new ButtonListener());
		start.setActionCommand("StartButton");
	}
	
	class ButtonListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			fehler = false;
			
			try
			{
				setInput();
					
				if(kraftInput < 0)
				{
					kraftInputField.setText("Nur positive Zahlen zulässig!");
					fehler = true;
				}
				
				if(winkelInput > 90 || winkelInput < 0)
				{
					winkelInputField.setText("Nur Winkel 0°-90°zulässig!");
					fehler = true;
				}
			 }
			 catch(NumberFormatException n)
			 {
				kraftInputField.setText("Mach den Text");
				winkelInputField.setText("jetzt weg du Troll!!!");
				
				fehler = true;
			 }
			
			if(!fehler)
			{
				start.setEnabled(false);
				kraftInputField.setEditable(false); 
				winkelInputField.setEditable(false); 
				versuchsPanel.set(versuchsPanel.get() - 1);
			
				new Thread(new Runnable()
								{
									public void run()
									{																				
										Ellipse2D.Double stein = new Ellipse2D.Double(katapultArea.getPosX()+40+katapultArea.getX(), katapultArea.getPosY()-14-katapultArea.getY(), 20, 20);
										Rectangle2D.Double katapultAreaRahmen = new Rectangle2D.Double(getX(),getY() ,getWidth(), getHeight());
										
										while( !(stein.intersects(900, katapultArea.getRandomInt(), 30, 30)) && !(stein.intersects(katapultAreaRahmen))) //solange der stein nicht das ziel berührt pder der stein die grenzen des pan
										{
											try 
											{ 
												Thread.sleep(5); 
											}
											catch(InterruptedException ie) {}
											
											katapultArea.setX();
											katapultArea.setY();
											katapultArea.repaint();
											
											stein = new Ellipse2D.Double(katapultArea.getPosX()+40+katapultArea.getX(), katapultArea.getPosY()-14-katapultArea.getY(), 20, 20);
											katapultAreaRahmen = new Rectangle2D.Double(getX(),getY() ,getWidth(), getHeight());
										}
										
										if((stein.intersects(900, katapultArea.getRandomInt(), 30, 30)))
												new WinFrame();
										else new LooseFrame();
									}
								}).start();
			}
			else 
			{
				kraftInputField.selectAll();
				winkelInputField.selectAll();
			}
		}
	}
	
    private void setInput()
    {
        kraftInput = Integer.parseInt(kraftInputField.getText());
        winkelInput = Integer.parseInt(winkelInputField.getText());
    }
	
	public int getKraftInput()
	{
		return this.kraftInput;
	}
	
	public int getWinkelInput()
	{
		return this.winkelInput;
	}
}

public class BallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}
 
Zuletzt bearbeitet:
J

JohannisderKaeufer

Gast
Seit geraumer Zeit kann man Methoden annotieren.

Und Methoden wie paintComponent() sind Methoden die man in der Regel überschreibt und sollten daher mid @Override annotieren.

Der Vorteil der sich daraus ergibt ist der, dass sich eine "falsche" Methodensignatur in der IDE oder dem Compiler bemerkbar macht.
 

BlubBlub

Bekanntes Mitglied
okay danke für den hinweis. das heißt also dass wenn ich eine anotation mache, dann kann ich die methode niemals überladen.

aber ich hab die methode ja eh nur überschrieben von daher machts keinen unterschied ob ich die anotation hinmache oder nicht und der fehler liegt auch nicht daran. sollte von dir ja auch sicherlich nur ein hinweis sein, worauf man beim programmieren achten sollte, werd dies auch dann anwenden.

das problem ist ja aber immer noch nicht behoben, um hilfe wäre ich wirklich sehr dankbar, ich hab mir grad das tutorial hier im forum zum zeichnen durchgelesen um evtl dort ein hinweis zu bekommen wo ich ein fehler gemacht hab, aber ich seh den fehler immer noch nicht :(
 

BlubBlub

Bekanntes Mitglied
ich hab jetzt mal nen paar screenshots gemacht um das problem zu verdeutliche.
weiß ist das ziel, grau ist der stein.
problem seht ihr ja an den bildern.
wenn ich die super.paintComponent(g) methode weglasse kann man sehen
was im einzelnen geschieht.
ich weiß aber nicht wo der fehler sein könnte. please help me.

siehe das album in meinem profil:
http://www.java-forum.org/members/blubblub-albums.html

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

class MyFrame extends JFrame
{
	private VersuchePanel versuchsPanel = new VersuchePanel();
	private KatapultPanel katapultArea = new KatapultPanel();
	private SteuerPanel steuerung = new SteuerPanel(versuchsPanel, katapultArea);
	
	MyFrame()
	{
		super("Ballistischer Wurf"); 
		setSize(1000, 600); 
		setResizable(false); 
	
		getContentPane().setLayout(new BorderLayout());  
		getContentPane().add(versuchsPanel, BorderLayout.NORTH); 
		getContentPane().add(katapultArea, BorderLayout.CENTER);
		getContentPane().add(steuerung, BorderLayout.SOUTH);
		
		katapultArea.setSteuerung(steuerung);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
	}
}


class WinFrame extends JFrame
{
	JButton okButton = new JButton("Ja");
	JButton beendenButton = new JButton("Beenden");
	JLabel infoLabel = new JLabel("Wollen sie das Spiel wiederholen?");
	JPanel bunkerPanel = new JPanel();
	
	WinFrame()
	{
		super("Gewonnen");
		setSize(250, 250);
		setResizable(false);
		
		bunkerPanel.setLayout(new GridLayout(1, 2));
		bunkerPanel.add(okButton);
		bunkerPanel.add(beendenButton);
		
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(infoLabel, BorderLayout.NORTH);
		getContentPane().add(bunkerPanel, BorderLayout.CENTER);
				
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
	}
}

class LooseFrame extends JFrame
{
	JButton okButton = new JButton("Ja");
	JButton beendenButton = new JButton("Nein");
	
	LooseFrame()
	{
		super("Verloren");
		setSize(250, 150);
		setResizable(false);
		
		getContentPane().setLayout(new FlowLayout());
		getContentPane().add(new JLabel("Wollen Sie das Spiel wiederholen?"));
		getContentPane().add(okButton);
		getContentPane().add(beendenButton);
		
		setVisible(true); 
		setDefaultCloseOperation(EXIT_ON_CLOSE); 
		setLocationRelativeTo(null);
	}
}

class VersuchePanel extends JPanel
{
	private int versucheAnzahl = 5;
	private JLabel counterLabel = new JLabel("Versuche: " + versucheAnzahl);

	VersuchePanel()
	{
		add(counterLabel);
	}
		
	public void decVersucheAnzahl()
	{	
		if(versucheAnzahl > 0)
		{
			this.versucheAnzahl--;
			counterLabel.setText("Versuche: " + versucheAnzahl);
		}
		else new LooseFrame();
	}
	
	public int getVeruscheAnzahl()
	{
		return versucheAnzahl;
	}
}
	

class KatapultPanel extends JPanel
{		
	private SteuerPanel steuerung;
	private int kraftInput;
	private int winkelInput;
	private int posX = 50; //position des katapults
	private int posY = 258; //position des katapults
	private int x = 0; // 
	private int y = 0; // dieser koordinaten urpsrung liegt beim stein 
	private Image img = getToolkit().getImage("katapult.gif");
	private int randomInt = new Random().nextInt(480);
	
	KatapultPanel()
	{	
		setBackground(Color.black); 
	}
	
	@Override
	public void paintComponent(Graphics g)
	{
		//super.paintComponent(g); //damit wird das panel jedes mal neu gezeichnet, so dass nicht tausend steine am ende zu sehen sind sondern zu jedem zeitpunkt immer nur einer
		
		this.kraftInput = steuerung.getKraftInput();
		this.winkelInput = steuerung.getWinkelInput();
		
		g.drawImage(img, posX, posY, this);
		
		g.setColor(Color.LIGHT_GRAY); //stein
		g.fillOval(posX+40+x, posY+14-y, 20, 20); //stein
		
		g.setColor(Color.WHITE); //ziel
		g.fillOval(900, randomInt, 30, 30); //ziel
	} 
	
	public int getRandomInt()
	{
		return this.randomInt;
	}
	
	public void setSteuerung(SteuerPanel steuerung)
	{
		this.steuerung = steuerung;
	}
	
	public void setX()
	{
		this.x++;
	}
	
	public void setY()
	{
		this.y = (int)((-9.81*(Math.pow(x, 2)))/(2*Math.pow(kraftInput, 2)*Math.pow(Math.cos(winkelInput * (Math.PI/180) ), 2))+Math.tan(winkelInput * (Math.PI/180) )*x); //Formel aus der Mechanik für Schiefen Wurf 
	}
	
	public int getX()
	{
		return this.x;
	}
	
	public int getY()
	{
		return this.y;
	}
	
	public int getPosX()
	{
		return this.posX;
	}
	
	public int getPosY()
	{
		return this.posY;
	}
	
	public int getComponentsX()
	{
		return super.getX();
	}
	
	public int getComponentsY()
	{
		return super.getY();
	}
}

	
class SteuerPanel extends JPanel 
{
	private JButton start = new JButton("Start");
	private JTextField kraftInputField = new JTextField("50");
	private JLabel kraftLabel = new JLabel("Kraft:");
	private int kraftInput = 50;
	private JTextField  winkelInputField = new JTextField("45");
	private JLabel winkelLabel = new JLabel("Winkel:");
	private int winkelInput = 45;
	private VersuchePanel versuchsPanel;
	private KatapultPanel katapultArea;
		
	SteuerPanel(VersuchePanel versuchsPanel, KatapultPanel katapultArea)
	{
		this.versuchsPanel = versuchsPanel;
		this.katapultArea = katapultArea;
		
		setLayout(new GridLayout(1, 5));
		
		add(kraftLabel);
		add(kraftInputField);
		add(winkelLabel);
		add(winkelInputField);
		add(start);
	
		start.addActionListener(new ButtonListener());
		
		kraftInputField.selectAll();
		winkelInputField.selectAll();
	}
	
	class ButtonListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			boolean fehler = false;
			
			try
			{
				setInput(); //selbst geschriebene Methode, kraftInput und winkelInput kriegen hier ihre Werte zugewiesen
					
				if(kraftInput < 0)
				{
					kraftInputField.setText("Nur positive Zahlen zulässig!");
					fehler = true;
				}
				
				if(winkelInput > 90 || winkelInput < 0)
				{
					winkelInputField.setText("Nur Winkel 0°-90°zulässig!");
					fehler = true;
				}
			 }
			 catch(NumberFormatException n)
			 {
				kraftInputField.setText("Mach den Text");
				winkelInputField.setText("jetzt weg du Troll!!!");
				
				fehler = true;
			 }
			
			if(!fehler)
			{
				start.setEnabled(false);
				kraftInputField.setEditable(false); 
				winkelInputField.setEditable(false); 
				versuchsPanel.decVersucheAnzahl(); //zählt die versuchsanzahl um eins runter
			
				new Thread(new Runnable()
								{
									public void run()
									{																				
										Ellipse2D.Double stein = new Ellipse2D.Double(katapultArea.getPosX()+40+katapultArea.getX(), katapultArea.getPosY()-14-katapultArea.getY(), 20, 20);
										Rectangle2D.Double katapultAreaRahmen = new Rectangle2D.Double(katapultArea.getComponentsX(),katapultArea.getComponentsY() ,katapultArea.getWidth(), katapultArea.getHeight());
										
										while( !(stein.intersects(900, katapultArea.getRandomInt(), 30, 30)) && (stein.intersects(katapultAreaRahmen))) //solange der stein nicht das ziel berührt oder der stein die grenzen des panels überschreitet
										{
											try 
											{ 
												Thread.sleep(5); 
											}
											catch(InterruptedException ie) {}
											
											katapultArea.setX();
											katapultArea.setY();
											katapultArea.repaint();
											
											stein = new Ellipse2D.Double(katapultArea.getPosX()+40+katapultArea.getX(), katapultArea.getPosY()-14-katapultArea.getY(), 20, 20);
											katapultAreaRahmen = new Rectangle2D.Double(katapultArea.getComponentsX(),katapultArea.getComponentsY() ,katapultArea.getWidth(), katapultArea.getHeight());
										}
										
										if((stein.intersects(900, katapultArea.getRandomInt(), 30, 30)))
												new WinFrame();
										else new LooseFrame();
									}
								}).start();
			}
			else 
			{
				kraftInputField.selectAll();
				winkelInputField.selectAll();
			}
		}
	}
	
    private void setInput()
    {
        kraftInput = Integer.parseInt(kraftInputField.getText());
        winkelInput = Integer.parseInt(winkelInputField.getText());
    }
	
	public int getKraftInput()
	{
		return this.kraftInput;
	}
	
	public int getWinkelInput()
	{
		return this.winkelInput;
	}
}

public class BallistischerWurf 
{
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}
 
J

JohannisderKaeufer

Gast
okay danke für den hinweis. das heißt also dass wenn ich eine anotation mache, dann kann ich die methode niemals überladen.

aber ich hab die methode ja eh nur überschrieben von daher machts keinen unterschied ob ich die anotation hinmache oder nicht und der fehler liegt auch nicht daran. sollte von dir ja auch sicherlich nur ein hinweis sein, worauf man beim programmieren achten sollte, werd dies auch dann anwenden.

das problem ist ja aber immer noch nicht behoben, um hilfe wäre ich wirklich sehr dankbar, ich hab mir grad das tutorial hier im forum zum zeichnen durchgelesen um evtl dort ein hinweis zu bekommen wo ich ein fehler gemacht hab, aber ich seh den fehler immer noch nicht :(

Naja, in deinem ersten Thread hast du in Zeile 67 die Methode überladen.

paintComponent wird jedesmal aufgerufen wenn die Componente neu gezeichnet werden soll.
überlädst du die Methode, so wird lediglich die Methode aus der Superklasse aufgerufen.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben