Erste Schritte Senkrechter Wurf

A

Andi321

Gast
Guten Abend ,

ich will ein Programm schreiben bei dem ich mit einer Kanone Gegenstände abschießen kann.
Jetzt hab ich folgendes Problem , ich weiß nicht genau wie ich es programmierne kann damit die Kugel als senkrechter Wurf mit Einfluss der Schwerkraft fliegt.

Vielen Dank schon mal im Vorraus.
 
A

Andi32

Gast
Mein Problem ist die graphische Umsetzung. Die mathematischen Grundlagen sind mir klar .
 

AquaBall

Top Contributor
Die Grafische Umsetzung steht und fällt damit welches Grafiksystem du verwenden willst.

In der Console gehts auch, schaut aber besch... aus.

Und wenn du dich für ein System entschieden hast, dann musst du erst haufenweise basics lernen.
... wie "Canvas definieren", "koordinatensystem festlegen", "objekt darstellen", "daten clippen", "Bildschirm refreshen", ...
Und dann stellt sich die Frage, ob du das ganze sequentiell, oder parallell machen willst (multiThreading).
Da wirds nochmal ein ganzes Berg Fragen neu aufgeworfen.

Das kann dir alles niemand im Forum mit einem Post beibringen. Da weiß Dr.Google besser bescheid.
Da gibts auch videoTutorials, die in 16 Teilen ganze Spiele programmieren.

Die Frage klingt für mich danach, dass du da noch WEIT entfernt bist.
 
Zuletzt bearbeitet:
A

Andi321

Gast
Kann ich es nicht einfach so machen , dass ich ein Applet mache und dann einfach mit der paint Methode einen Kreis zeichne dann den wieder übermahle und auf einer neuen Position einen neuen Kreis zeichne.
 
F

Firephoenix

Gast
so könnte man die grafische Darstellung durchaus realisieren.

Du könntest dir dazu auch mal das Spiele-Tutorial von Quaxli hier im Forum anschauen, dort geht es unter anderem auch darum.

Grundlegend würde ich aber auf alle Fälle deine Daten von der Gui trennen (nur Position des Objekts speichern, updates nur auf den Daten machen und bei Änderung der Daten die Gui auffordern sich neu zu zeichnen - MVC wäre hier ein Ansatz den man sich anschauen sollte).
Gruß
 
A

Andi321

Gast
Ich hab jetzt ein kleines Problem , wenn ich mit der allgemeinen Formel die einzelnen Positionen der Kugel berechnen kommen double Zahlen raus, wenn ich diese aufrunde ,dann flackert es und sieht nicht sehr gleichmäßig aus.
 

AquaBall

Top Contributor
Dann eben nicht AUF-runden, sondern eben nur 'runden'.

Aber: Bei einer korrekten Formel kommt ja immer das selbe Ergebnis raus. Was sollte da flackern?
Und bei einer harmonischen Bewegung dürfen Rundungen auch kein Problem sein, weil die Änderungen imer in dieselbe Richtung gehen.

Außerdem: Wenn ein Grafiksystem keine Double-Werte verkraftet, dann ist's für physikalische Prozesse nicht geeignet. Da sind die Änderungen oft minimal und doch entscheidend.
 

Marco13

Top Contributor
Nimm das nicht so ernst. Das wichtige ist, dass man mit double (oder wenigstens float) rechnet. Zum Malen kann man dann auf int casten
double d = 12.45;
int i = (int)d; // i ist jetzt 12
Wenn da was flackert, ist irgendwas falsch....
 

AquaBall

Top Contributor
Die Frage ist eher: Mit was du bisher arbeitest!

Grundsätzlich ist die ganze physikalische Welt nur "virtuell".
Also Classen/Formeln/Konstrukte, die sich überhaupt nicht um die grafische Darstellung kümmern, sondern nur die 'Welt' beschreiben. Du hast (solltest haben!) also Methoden, die !Ausschließlich! alle deine physikalischen Prozesse brechnen, und in einem Datengerüst bereitstellen. Diese Daten müss(t)en auf jeden Fall double sein.

Völlig unabhängig davon hast du einen anderen Programmteil, der !Ausschließlich! die Darstellung erledigt. Der holt nur aus dem 'Welt'-Datengerüst die aktuelle Position heraus, ohne irgendeine Berechnung zu machen. Dieser Programmteil rechnet nur die (für diesen im Augenblick bestehenden) physikalischen Koordinaten in die Anzeige am Bildschirm um. Da wird alles logischerweise Integer. (Bleibt aber in der 'Welt' unberührt double bestehen).

Und ein dritter eigener Programmteil kümmert sich um deine Eingaben und Benutzersteuerung. Damit werden auch keine Berechnungen durchgeführt, sondern !Ausschließlich! nur Trigger/StartBefehle im Datengerüst ausgelöst. (Kanone JETZT verstellen, Feuerbefehl JETZT, ...). Wie schnell sich die Kanone bewegen KANN ist, wieder Aufgabe der PhysikEngine.
Diese Programmteile arbeiten UND LAUFEN üblicherweise parallel und völlig unabhängig.

Wenn du diese Trennung noch nicht hast, dann mach das jetzt! Und zwar ABSOLUT exakt getrennt.
Das hat viele Vorteile:
Später kannst du auf ein beliebiges Grafiksystem wechseln, ohne an der Pysik auch nur einen Strich zu ändern. Es kann sich einer um Physik, und einer um Grafik kümmern. Du kannst zwischen Test-Umgebungen umschalten. ...

Im Grundgerüst sieht das Ganze so aus:
Java:
main () {
  initialisiereDaten();
  startePhysikEngineThread();
  starteDarstellungsEngineThread();
  for (endlos) {
    benutzerEingriff(); //bis Ende; break;
  }
}
Wenn du das nicht kannst, dann hast du ein Problem mit Zeitsprüngen, Harmonie, ...
Musst du dann irgendwie über 1 Schleife mit "sequenzieller" Arbeitsweise erledigen:
Java:
main () {
  initialisiereDaten();
  for (endlos) {   // Problem: Zeitscheiben einhalten, aber BenuzerEingriff nicht bremsen !?!?!
    benutzerEingriff(); //evtl mit break;
    pysikBerechnen();
    amBildschirmDarstellen();
  }
}

Wie funktioniert denn bisher dein System und die grafische Darstellung?
 
Zuletzt bearbeitet:
A

Andi321

Gast
Java:
  g2.setColor(Color.black);
               g2.fill(new Ellipse2D.Double(i, 300-y,20, 20));
               try{
                   Thread.sleep(1);
               }catch(Exception e ) {}
               g2.setColor(Color.white);
               g2.fill(new Ellipse2D.Double(i, 300-y,20, 20));

Das sieht im Moment so aus , ich berechne nach der Formel für ein schiefen Wurf die Position zeichne dann die Kugel ,lösch sie wiede rund berechne die Position etwas weiter. Jedoch funktioniert das ganze immer noch nicht so ganz einwandfrei.
Vorallem das mit dem Winkel , wenn ich jetzt 80 Grad eingebe , dann sieht das ganze nicht nach 80 Grad aus .
Ich bin noch ziemlicher Anfänger.
 

AquaBall

Top Contributor
Das sieht im Moment so aus
Das CodeSnpisel kann keine Problem machen, da du ja an den Daten nichts veränderst und nur an der selben Stelle 2 mal malst.
etwas performanter und fehler sicher wäre noch folgende Variante:
Java:
   kugel = new Ellipse2D.Double(i, 300-y,20, 20);

   g2.setColor(Color.black);
   g2.fill( kugel );

   try{
      Thread.sleep(1);
   }catch(Exception e ) {}

   g2.setColor(Color.white);
   g2.fill( kugel );

ich berechne nach der Formel für ein schiefen Wurf die Position, zeichne dann die Kugel ,lösch sie wieder und berechne die Position etwas weiter.
Jedoch funktioniert das ganze immer noch nicht so ganz einwandfrei.
Vorallem das mit dem Winkel , wenn ich jetzt 80 Grad eingebe , dann sieht das ganze nicht nach 80 Grad aus .
Ich bin noch ziemlicher Anfänger.
Wenn_s
Code:
nicht nach 80 Grad aussieht
, dann wirst du wohl dort einen Fehler machen.
Nach was siehts dann sonst aus?
 

Marco13

Top Contributor
Du musst die Kugel nicht mehr löschen. Zeichne sie in paintComponent NUR an der Position, wo sie sein soll.

Poste mal mehr Code.
 
A

Andi321

Gast
Hmm , vielen Dank erstmal für die Antworten. An sich ist es mir jetzt etwas klarer geworden ich poste mehr Code sobald ich mehr auf die Reihe bekomme. Es wird mir jetzt klar , dass mir schon einiges an Grundwissen fehlt. Ich muss noch ein bisschen googeln , wie ich die das mit den einzelnen Threads programmier.
 
A

Andi321

Gast
Mit Threads hab ich leider nur wenig Erfahrung . In welchen Thread mach ich die Schleife rein?
 
A

Andi321

Gast
Es tut mir Leid ,falls ich etwas dumme Fragen stelle , aber ist es Möglich , dass die einzelnen Threads untereinander Daten austauschen?
 

Marco13

Top Contributor
Beschreib' genauer, was du meinst. Möglich ist es sicher, aber ggf. muss man aufpassen, damit nicht z.B. zwei Threads gleichzeitig auf den Daten arbeiten und ggf. sogar versuchen, sie zu ändern.
 
A

Andi321

Gast
Java:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.awt.geom.Ellipse2D;

/**
  *
  * description
  *
  * @version 1.0 from 24.04.2012
  * @author
  */

public class asdasd extends Applet {
  // Anfang Attribute

  // Ende Attribute

  public void init () {

    rechnen a1 = new rechnen();
    a1.start();
  }
  double xRichtung , yRichtung ,gw, winkel, zeit,g1;
  class rechnen extends Thread{
              public void run(){
      

               xRichtung=1;
                gw=100;
                winkel=50;
                g1=-10;

               for(xRichtung=0;xRichtung<400;xRichtung=xRichtung+0.001){
                zeit = xRichtung/(gw*Math.cos(Math.toRadians(winkel)));
                yRichtung=gw*Math.sin(Math.toRadians(winkel))*zeit+(0.5*g1*zeit*zeit);

      
      




               }


              }



  }



          //SX-Richtung = v0 · cos(a) · t

            public void paint(Graphics g) {
                xRichtung=1;
                gw=100;
                winkel=50;
                g1=-9.81;
                Graphics2D g2 = (Graphics2D)g;
               for(xRichtung=0;xRichtung<400;xRichtung=xRichtung+0.001){
                zeit = xRichtung/(gw*Math.cos(Math.toRadians(winkel)));
                yRichtung=gw*Math.sin(Math.toRadians(winkel))*zeit+(0.5*g1*zeit*zeit);
      
      
      
                   g2.setColor(Color.black);
                    g2.fill(new Ellipse2D.Double(xRichtung, 373-yRichtung,20, 20));
                    try{
                   Thread.sleep(0);
                   }   catch(Exception e ) {}
                   g2.setColor(Color.white);
                   g2.fill(new Ellipse2D.Double(xRichtung, 373-yRichtung,20, 20));



               }

            }





  
  // Anfang Methoden
  // Ende Methoden
}

so sieht es im Moment aus , ist aber nicht gerade optimal.
 

AquaBall

Top Contributor
Vielleicht ist es ein "Overkill" und zu viel auf einmal, aber hattest du dir mal http://www.java-forum.org/mathematik/130544-formeln-fuer-einfache-schwerkraft-2.html#post865782 angesehen?

Hast mit deiner Vermutung sicher recht.
Glaubst du er kann diese 286 Zeilen verstehen kann, wenn er die eigenen 20 entscheidenden nicht eindeutig durchblickt?

[OT]PS: Diese unzähligen unnötigen nervigen verdammten Leerzeilen im Code blockieren mich, dort mitarbeiten zu wollen. Hab ich schon x mal hingewiesen.[/OT]
 

Alph0r

Mitglied
Dir scheint in ein paar Bereichen noch etwas Vorwissen zu fehlen, ich empfehle auch das Tutorial von Quaxli.

Nur ein bisschen was zu dem Rechen-Thread und der Paint-Methode:

Du berechnest ja dem Thread alle nötigen Daten für die Kugel, ich hab mir jetzt nicht angeschaut, ob das richtig berechnet ist, nur zum Design:
Du solltest die Dtaen, die du da berechnest, in der Paint Methode verwenden, du berechnest ja in der Paint Methode alles wieder neu in der Schleife.


Bei mir würde das ungefähr so aussehen (PseudoCode und einfach copy/paste nur um zu verdeutlichen was ich meine)

public class asdasd extends Applet {
// Anfang Attribute

// Ende Attribute

public void init () {

rechnen a1 = new rechnen();
a1.start();
}
double xRichtung , yRichtung ,gw, winkel, zeit,g1;
class rechnen extends Thread{
public void run(){


xRichtung=1;
gw=100;
winkel=50;
g1=-10;

for(xRichtung=0;xRichtung<400;xRichtung=xRichtung+0.001){
zeit = xRichtung/(gw*Math.cos(Math.toRadians(winkel)));
yRichtung=gw*Math.sin(Math.toRadians(winkel))*zeit+(0.5*g1*zeit*zeit);

repaint();







}


}



}



//SX-Richtung = v0 · cos(a) · t

public void paint(Graphics g) {
g2.setColor(Color.black);
g2.fill(new Ellipse2D.Double(xRichtung, 373-yRichtung,20, 20));
try{
Thread.sleep(0);
} catch(Exception e ) {}
g2.setColor(Color.white);
g2.fill(new Ellipse2D.Double(xRichtung, 373-yRichtung,20, 20));



}

}







Der Sinn ist einfach keine Interne Logik in der paint methode zu haben, sondern Positionen usw aus anderen Methoden zu holen und die Paint Methode wirklich nur sachen wie fill() ausführen zu lassen an den in anderen Methoden berechneten Positionen.

Ist einfach deutlich besser bei größeren Projekten das zu trennen.
 
Zuletzt bearbeitet:
A

Andi321

Gast
Guten Abend ,

ich leider fehlt mir noch einiges an Vorwissen. Ich hab es jetzt aber hinbekommen :).
Ich habe jetzt ein Thread der nur die Position berechnet und die paint Methode zeichnet nur die Kugel.
Außerdem lösche jetzt nich nur die Kugel sondern zeichne den kompletten Hintergrund neu , dadurch ist das flackern weg. :)
 

Neue Themen


Oben