Bewegung eines Balkens in eineum JPanel welches als Spielfeld fungiert

pmSave

Mitglied
Hallo zusammen,
ich habe ein Tennis ähnliches spiel programmiert, wo man einen Balken steuern muss, der am rechten Rand des JPanel liegt und gegen den Computer(dieser ist der linke Balken und liegt am linken Rand) spielen kann. Man muss versuchen einen Ball im Spiel zu halten und nicht gegen seine Wand prallen zu lassen, am besten gegen die linke also die des Computergesteuerten.
Hier kommt mein Problem:
Der Computergesteuerte, linke Balken wird auf das Panel gezeichnet und als Y-Koordinate(dem entsprechend die senkrechte Höhe auf der sich der Balken befindet) wird normalerweise immer die Y-Koordinate des Balls(welche sich durchgehen ändert) gesetzt.
Nun kann man so als Spieler natürlich nicht gewinnen, da der Computer den Ball immer trifft. Ich habe mir überlegt, dass es eine zufalls-chance gibt ob der Computergesteuerte linke Balken den Ball trifft oder durchlässt. Ob der Balken den Ball durchlässt wird immer geprüft, wenn der Ball von der Seite des Spielers kommt und sich ungefähr in der Mitte des Feldes befindet. Wenn der Ball durchgelassen werden soll, soll sich die Y-Koordinate des linken Balken so verändern, dass der Balken den Ball nicht mehr trifft.
Das ganze findet in der run-Methode eines laufenden Threads statt, wobei alle Komponenten auf das Panel mit der überschriebenen Methode paintComponent gezeichnet werden.

Hier die entsprechenden Auszüge aus dem Quellcode, ich entschuldige mich für event. schlechte Variablen bezeichnungen, da ich jetzt etwas länger an dem Verhalten des Balkens gearbeitet habe und leider der Balken ab einer x-Position des Balls von weniger als 300 entweder stehen bleibt oder die komischsten sachen macht.
Java:
public class JMyPanel extends JPanel implements Runnable{
...
private boolean win;        //variable zum festlegen, ob der linke Balken trifft oder nicht
    private int posBl = 0;  //gemeint ist die richtung des linken balkens wenn die variable win = true ist
    private int richtungBlzaehler = 2; //variable um die verschiebung des linken balkens auf zeit zu kontrollieren

...
public void run() {
...
    if (win == true && vor == false && ball.getX() <= 300) {
               if (ball.getX() <= 300 && ball.getX() >= 298) {
                   posBl = (int)ball.getY();
               }
               if (ball.getX() < 300) {
               if (oben) {
                   rechteckL.setY(posBl - zufall);
                   posBl-=zufall;
               } else {
                   rechteckL.setY(posBl + zufall);
                   posBl+=zufall;
               }
               abstand=0;
                   richtungBlzaehler += 1;
    }
...
}

...
/* Methode die aufgerufen werden soll um zu Prüfen, ob der linke Balken den Ball trifft
 * oder nicht*/
public void winPruefen() { 
   if((int)(Math.random()*60) > 15 || zaehler == 1) {
       win = false; //spiel geht weiter
   } else {
       win = true;   //runde gewonnen, da ball gegen die linke wand trifft
   }
   if(zaehler == 1) {
       zaehler = 2;
   }
}
}

Ich bin mir nicht ganz sicher, ob ich das lieber in einem anderen Forum posten sollte, aber da es hier lediglich um ein denk-Problem im Bezug auf das Zeichnen auf einem JPanel - was ja bekanntlich eine SWING - Komponente ist, geht.
Ich hoffe mein Code ist nachvollziehbar. Ich habe immer direkte Zahlenwerte benutzt, da die Methoden getWidth() bzw. getHeight() meist nicht gut funktioniert haben.
 
Das "tennisartige Spiel" was du beschreibst ist auch allgemein als Ping Pong bekannt.

Aus meiner Sicht ist es auch keine Lösung per Zufall zu entscheiden ob der Computer durchlässt oder nicht.
Du hast ja sicher eine Geschwindigkeit (Velocity) für den Schläger des Spielers. Eine solche Geschwindigkeit sollte der Computerschläger auch haben. Der Ball sollte eine höhere Velocity als der Schläger haben. Dann taktest du das "Denken" vom Computer (für möglichen Richtungswechsel) noch mit einem eigenen Timer. Diese Werte (Taktung, Velocity etc.) kannst du dann bissl ändern und rumprobieren. Eventuell gestaltest du die Velocity vom Computer auch etwas niedriger als deine eigene. Auf diese Weise kann, zumindest theoretisch, der Computer auch verlieren.

Noch ein kleiner Hinweis:
Es wird grundsätzlich davon abgeraten solche Runnables bei Swing-Applikationen zu haben.
Swing hat dafür https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html
 

Zurück
Oben