Autor Beitrag
LINUS19
Hält's aus hier
Beiträge: 21



BeitragVerfasst: So 12.11.17 19:23 
Hallo,
Ich habe in Java ein Pong Spiel programmiert, das Problem ist das der Ball manchmal vom Schläger abprallt und manchmal nicht.
Ich hoffe das jemand helfen kann.

LINUS19
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1073
Erhaltene Danke: 129

Windows 10 x64 Home Premium
C# (VS 2015 Enterprise)
BeitragVerfasst: So 12.11.17 20:13 
Also, ich denke, dir kann sicher jemand helfen ;)
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 78
Erhaltene Danke: 9

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: So 12.11.17 21:26 
Wir wissen ja nicht, wie genau du Pong implementiert hast, wie groß alles ist, wie du zeichnest etc. Es wäre also sinnvoll, wenn du deinen Quellcode hier teilen würdest.

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1073
Erhaltene Danke: 129

Windows 10 x64 Home Premium
C# (VS 2015 Enterprise)
BeitragVerfasst: So 12.11.17 22:11 
In kurz:
Wir wissen nichts.
Wir wissen nicht einmal, was das Problem ist, nur das Resultat des Problems.
Entsprechend hoch ist auch die Wahrscheinlichkeit, hier eine Antwort auf die Frage zu bekommen ;)

Ein Tipp: Debugging ;)
Gerade bei solchen Problemen ist das das beste Hilfsmittel
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 18:13 
Hier der Code :

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Pong extends JPanel {
     
      int x = 30, y = 300; // Anfangskoordinaten Schläger 1
      int Px = 200, Py = 200; //Anfangskoordinaten Ball
      int x2 = 770, y2 = 300; //Anfangskoordinaten Schläger 2
      int dPx = 10, dPy = 10; // Geschwindigkeit Ball
      boolean Spieler1o = false; // Pfeiltaste oben am Anfang Taste nicht gedrückt
      boolean Spieler1u = false; // Pfeiltast unten
      boolean Spieler2o = false;
      boolean Spieler2u = false;

      public Pong() {
          setPreferredSize(new Dimension(800, 600)); // Fenstergröße

          Ball neu = new Ball();
          neu.start(); // Thraed Ball wird gestartet
          Schläger s = new Schläger(); // Thread Schläger wird gestartet
          s.start();
      }

      public void paint(Graphics gr) { // beiden Schläger und Ball
          Graphics2D g = (Graphics2D) gr; // werden gezeichnet
          g.setColor(Color.WHITE);
          g.fill(g.getClipBounds()); // damit die Zeichnung überschrieben wird
          g.setColor(Color.BLACK);
          g.fillRect(x, y, 10, 80); // Ball und Schläger werden gezeichnet
          g.fillOval(Px, Py, 30, 30);
          g.fillRect(x2, y2, 10, 80);
      }

      public void PositionSchläger1() { // wird auf AnfangsPosition gesetzt
          x = 30;
          y = 300;
          repaint();
      }

      public void PositionBall() { // AnfangsPosition
          Px = 200;
          Py = 200;
          repaint();

      }

      public void PositionSchläger2() // Anfangsposition{
          x2 = 760;
          y2 = 300;
          repaint();
      }

      class Ball extends Thread { // thread für Ball
          void bewegen() {
              Px = Px + dPx; //die Bewegung
              Py = Py + dPy;

              if (Px < 0) { // Ball prallt von der Wand ab
                  Px = 0;
                  dPx = -dPx;
              }
              if (Py < 0) {  // Ball prallt von der Wand ab
                  Py = 0;
                  dPy = -dPy;
              }
              if (Py > 570) { // Ball prallt von der Wand ab
                  Py = 570;
                  dPy = -dPy;
              }
              if (Px > 770) { // Ball prallt von der Wand ab
                  Px = 770;
                  dPx = -dPx;
              }

              if (Px == 40 && Py >= y && Py <= y + 80) { // Hier soll er vom Schläger1 abprallen
                  Px = 40;
                  dPx = -dPx;                
              }

              if (Px == 740 && Py >= y2 && Py <= y2 + 80) {//// Hier soll er vom Schläger2 abprallen
                                                             
                  Px = 740;
                  dPx = -dPx;
                  dPy = -dPy;
              }
              repaint();
          }

          public void run() { // Thread für Ball

              while (!isInterrupted()) {

                  bewegen();
                  try {
                      Thread.sleep(50);
                  } catch (InterruptedException e) {
                      return;
                  }
              }
          }
      }

      class Schläger extends Thread implements KeyListener {
          Schläger() {
              addKeyListener(this); // KeyListenr wird hinzugefügt
          }

          public void run() {

              while (true) { // solange Spieler Taste drückt
                                  //wird Schläger bewegt
                if (Spieler1o == true) { // Bewegung Schläger1
                      y -= 12;
                  }
                  if (Spieler1u == true) {
                      y += 12;
                  }
                  if (Spieler2o == true) { // Bewegung Schläger2
                      y2 -= 12;
                  }
                  if (Spieler2u == true) {
                      y2 += 12;
                  }
                 
                    if (y2 > 520) { // 600-80 wegen Schlägerlänge
                      y2 = 520; // Damit die Schläger nicht aus dem Bild verschwinden
                  }
                  if (y2 < 0) {
                      y2 = 0;
                  }
                  if (y < 0) {
                      y = 0;
                  }
                  if (y > 520) {
                      y = 520;
                  }
                  repaint();
                  try {
                      Thread.sleep(50);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }

          public void keyPressed(KeyEvent e) { // Spieler 1 hier wird geguckt ob Taste gedrückt
              if (e.getKeyCode() == KeyEvent.VK_W) {
                  Spieler1o = true;
              }
              if (e.getKeyCode() == KeyEvent.VK_S) {
                  Spieler1u = true;
              }
             
              if (e.getKeyCode() == KeyEvent.VK_UP) { // Spieler2 hier wird geguckt ob Taste gedrückt
                  Spieler2o = true;
              }
              if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                  Spieler2u = true;
              }
          }

          public void keyReleased(KeyEvent e) { // Hier ob Taste wieder losgelassen
              // wenn ja stoppt Schlägerbewegung
            if (e.getKeyCode() == KeyEvent.VK_W) {
                  Spieler1o = false;
              }
              if (e.getKeyCode() == KeyEvent.VK_S) {
                  Spieler1u = false;
              }
              if (e.getKeyCode() == KeyEvent.VK_UP) {
                  Spieler2o = false;
              }
              if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                  Spieler2u = false;
              }
          }

          public void keyTyped(KeyEvent e) {
          }
      }
}


und die Hauptklasee:

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

public class Fenster extends JFrame {
   private Pong pong = new Pong();

   public Fenster() {
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
     getContentPane().add(pong);

     pong.PositionBall();
     pack();
     getRootPane();setVisible(true);

     pong.PositionSchläger2();
     pong.PositionSchläger1();
     pong.setFocusable(true);

   }

   public static void main(String[] args) {
     new Fenster();

   }
}


hoffe ihr könnt damit was anfangen.

VG
LINUS19

Moderiert von user profile iconChristian S.: Code-Tags hinzugefügt
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Chefentwickler
Beiträge: 20113
Erhaltene Danke: 1941

Win 10
C# (VS 2015)
BeitragVerfasst: Mo 13.11.17 20:02 
Du prüfst exakt auf Px == 40. Was passiert, wenn der Ball so schnell ist, dass er bereits "hinter" dem Schläger ist?

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 20:11 
Ok, danke und wie soll ich das am besten beheben?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Chefentwickler
Beiträge: 20113
Erhaltene Danke: 1941

Win 10
C# (VS 2015)
BeitragVerfasst: Mo 13.11.17 20:16 
Welche Idee hast Du denn dazu? Tipp: Schau mal, wie das drum herum in Deinem Sourcecode gemacht wird.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".

Für diesen Beitrag haben gedankt: LINUS19
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 20:47 
Ich komme gerade wirklich nicht darauf, habe schon einige Sachen probiert so z.B Px>=30 && Px <= 40, hat aber auch nichts genützt.
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 21:05 
Habs jetzt hinbekommen danke nochmal für die Mühen.

LINUS19
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 78
Erhaltene Danke: 9

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: Mo 13.11.17 21:28 
Selbst wenn es jetzt (anscheinend) funktioniert, befürchte ich immernoch, dass deine Kollisionsabfrage(n) nicht stimmen. Am meisten zwischen dem Ball und den Schlägern, aber auch bei den Oberen und unteren Wänden. Da musst du nämlich den Durchmesser des Balles noch mit einbeziehen, sonst können Ball und Schläger/Wand sich noch immer überlappen.

Außerdem solltest du evtl für die Größen aller Objekte variablen anlegen - also Ballradius bzw. Durchmesser, Schlägerhöhe und Breite und evtl auch Fensterhöhe und Breite.
Ich hab leider noch nie mit Java ernsthaft gearbeitet, deswegen weiß ich nicht wie es mit Makros steht - dann bräuchtest du nichtmal extra Variablen.

Da ich jetzt aber eine sehr sehr hilfreiche Vorlage habe, kann ich deinen Code mal für mich so modifizieren, wie ich das umsetzte. Wenn du willst, kann ich dann den modifizierten Code auch mal posten, aber ich will dir ja nichts vorschreiben oder so ;)

LG,
Symbroson

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 21:33 
Den Radius des Balls hatte ich mit einberechnet, das abprallen vom Rand hatte vorher ja auch schon funktioniert.
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 21:39 
Aber poste dann gerne mal deine Code.
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Mo 13.11.17 21:49 
Das habe ich auch noch verändert, falls der Ball sehr weit an den Rand vom Schläger kommt.

if(Px <= 40 && Py >= y-15 && Py <= y +95) vorher :if(Px <= 40 && Py >= y && Py <= y +80)
if(Px>=740 && Py>=y2-15 && Py<= y2+95 vorher: if(Px <= 740 && Py >= y && Py <= y +80)
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 78
Erhaltene Danke: 9

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: Mo 13.11.17 22:04 
Warum hast du eigentlich die Tastatur und die Bewegung in zwei separate Threads ausgelagert? du kannst doch die Tastatur auch vor der Bewegung abfragen, oder nicht?
Zusätzlich renderst du das Bild unnötig oft und das wirkt sich hart auf die Performance aus. Das kann auch einmalig nach der Bewegung aller Objekte geschehen.
Also Frage ist warum du das so gemacht hast

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 78
Erhaltene Danke: 9

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: Di 14.11.17 01:36 
Ich hab es endlich geschafft. :D
Ich muss dir auf jeden Fall sehr Danken, weil du mir die gelegeneit gegeben hast mal 'was richtiges' mit Java zu machen. Sonst hab ich mich ehrlich gesagt eher geweigert Java auch nur anzugucken :roll:
Hab also einige Erkenntnisse aufgrund deines Programms gewinnen können ^^

Ich habe versucht das unverständlichste so gut wie möglich zu erklären, solltest du aber dennoch irgendwelche Fragen haben, frag natürlich!
Auch wenn du oder jemand anderes irgendwelche Vorschläge bzgl. des Codes machen möchte - warum man zB dies und jenes nicht machen sollte uä. - immer her damit!

Was du auf jeden Fall noch implementieren solltest ist der Score, was damit einhergeht das Spiel zu resetten wenn der Ball die linke bzw rechte Wand Berührt. Aber das überlasse ich deiner Kreativität ;)

LG,
Symbroson
Einloggen, um Attachments anzusehen!
_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)


Zuletzt bearbeitet von Symbroson am Di 14.11.17 10:09, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: LINUS19
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Chefentwickler
Beiträge: 20113
Erhaltene Danke: 1941

Win 10
C# (VS 2015)
BeitragVerfasst: Di 14.11.17 07:35 
Zwischenbemerkung: Ich habe .java gerade als Dateianhangserweiterung erlaubt, sodass man die nicht mehr als .txt anhängen muss.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Di 14.11.17 14:27 
Hallo,
Das ist mein erstes Java Programm mit Grafik und Animation und dementsprechend noch ziemlich unausgereift. Könntest du das mit dem Bild rendern nochmal genauer erklären, wie ich es verbessern kann. Der Punkte Zähler usw. sollte ja nicht so schwer sein.

Ich hatte auch noch die Idee wenn ich das Spiel fertig habe, das ganze über ein Netzwerk zumachen für 2 Spieler an beliebigen Orten,doch ein Problem könnte dann sein mit den schnellen Bewegungen und der Zeitverzögerung( anders als z.B. bei Tictactoe).
Ist das ganze dann überhaupt für einen Anfänger machbar ?.

LG
LINUS19
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 78
Erhaltene Danke: 9

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: Di 14.11.17 14:54 
Bzgl dem Rendern: ursprünglich hattest du ja zwei Threads, einen für den Ball und einen für die Tastatur.
Beispiel: Ich drücke eine Beliebige Taste -> die Callback-Funktion wird aufgerufen. Die bewegt dann den Schläger, und Zeichnet (Rendert) alles. Dabei hat sich nur ein bis 2 Objekte bewegt - der Ball, die Score-Anzeige usw haben sich aber nicht verändert.
Der Ball aber wird ebenfalls periodisch bewegt und rendert alles, aber die Schläger bleiben nach wie vor an derselben Position.
Da die mit Abstand am zeitaufwändigste Methode das Zeichnen ist, wird die Framerate an sich nicht verändert, aber es werden eben manchmal nur halb so viele Aktionen pro Rendervorgang ausgeführt wie eigentlich möglich wären.
Deshalb solltest du erst alle Objekte bewegen, Kollisionsabfrage etc. und danach alles mit einem Mal rendern.

Außerdem wäre es in Zukunft sinnvoll die Zeitdifferenz zwischen dem letzten und dem Aktuellen Rendervorgang einzukalkulieren, da diese erstens zwischen verschiedenen Grafikkarten und Rechnern sehr stark variieren kann.
Wenn dein Rechner zB. etwas langsamer ist, erhöhst du die Geschwindigkeiten etwas, wenn dann aber jemand anderes mit einem besonders leistungsstarken Rechner dein Spiel spielt ist es viel zu schnell und unspielbar.
Aber auch zT. durch andere Prozesse kann das Spiel unregelmäßig gebremst werden.
Die Zeitdifferenz dient also dann dazu, diese Unterschiede und Unregelmäßigkeiten auszugleichen.
Da das aber wie du sagtest dein erstes Grafische Spiel ist, solltest du das vorerst missachten, aber später mal auf jeden Fall einhalten.
Außerdem mal ein Lob dafür, dass dein erstes entwickeltes Spiel nicht Minecraft oder so werden soll :D Ist ja ein allgemein bekanntes Problem, dass Einsteiger in die Spieleentwicklung gleich RPG, 3D, Multiplayer und alles Mögliche umsetzen wollen. ^^


Mit dem Nezwerkzeug bzw online multiplayer hab ich selber nicht viel am Hut. Ich hab nur mal mit Bluetooth ein Multiplayerspiel für Android gemacht. Das zumindest war relativ schnell.
Wenn du aber mal logisch überlegst was bei deinem PC für Netzwerkgeschwindigkeiten stehen, von kB (1000) oder sogar MB (Mio Byte) pro Sekunde - ist es relativ Wahrscheinlich, dass das keine Hürde für dein Spiel darstellen sollte. Viele Spiele im Internet bzw. aus dem Play/Appstore beweisen das. Und wenn man bedenkt, dass viele Tools auch über Internet Sprache in Echtzeit übermitteln...

Die Programmatische umsetzung ist natürlich wieder ein ganz anderes Problem - Da müsstest du mal nachschauen was es für Java-Module dafür gibt - 'Sockets' kannst du beispielsweise suchen. Ansonsten hat vielleicht jemand hier andere tolle Vorschläge für Java-Bibliotheken.

Sorry dass das so ein Roman geworden ist ^^ Hoffentlich ist es dadurch wenigstens etwas Verständlicher.

LG,
Symbroson

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
LINUS19 Threadstarter
Hält's aus hier
Beiträge: 21



BeitragVerfasst: Di 14.11.17 17:35 
Ok, danke das hat mir wirklich sehr weiter geholfen. Mit der Netzwerkprogrammierung schaue ich mir dann einfach ein paar Tutorials an.

LG
LINUS19