Autor |
Beitrag |
LINUS19
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: So 12.11.17 20: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
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: So 12.11.17 21:13
Also, ich denke, dir kann sicher jemand helfen
|
|
Symbroson
Beiträge: 382
Erhaltene Danke: 67
Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
|
Verfasst: So 12.11.17 22: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
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: So 12.11.17 23: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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 19:13
Hier der Code :
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 Christian S.: Code-Tags hinzugefügt
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 13.11.17 21: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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 21:11
Ok, danke und wie soll ich das am besten beheben?
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 13.11.17 21: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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 21: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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 22:05
Habs jetzt hinbekommen danke nochmal für die Mühen.
LINUS19
|
|
Symbroson
Beiträge: 382
Erhaltene Danke: 67
Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
|
Verfasst: Mo 13.11.17 22: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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 22:33
Den Radius des Balls hatte ich mit einberechnet, das abprallen vom Rand hatte vorher ja auch schon funktioniert.
|
|
LINUS19
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 22:39
Aber poste dann gerne mal deine Code.
|
|
LINUS19
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Mo 13.11.17 22: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
Beiträge: 382
Erhaltene Danke: 67
Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
|
Verfasst: Mo 13.11.17 23: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
Beiträge: 382
Erhaltene Danke: 67
Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
|
Verfasst: Di 14.11.17 02:36
Ich hab es endlich geschafft.
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
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 11:09, insgesamt 1-mal bearbeitet
Für diesen Beitrag haben gedankt: LINUS19
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Di 14.11.17 08: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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Di 14.11.17 15: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
Beiträge: 382
Erhaltene Danke: 67
Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
|
Verfasst: Di 14.11.17 15: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 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
Beiträge: 156
Erhaltene Danke: 1
Windows 10, 7
Java(Eclipse)
|
Verfasst: Di 14.11.17 18:35
Ok, danke das hat mir wirklich sehr weiter geholfen. Mit der Netzwerkprogrammierung schaue ich mir dann einfach ein paar Tutorials an.
LG
LINUS19
|
|
|