Spielball bewegt sich nicht richtig, prallt falsch ab

Alex2013

Bekanntes Mitglied
hey leute,

ich habe versucht mal ein kleines pong spiel zu schreiben.
Soweit passt auch fast alles. Aber der Ball prallt am oberen Rand nicht richtig ab (auf höhe des schlägers). Am linken rand mit weitem Abstand und am unteren Rand erst, wenn er verschwunden ist.

Ich habe schon einige Varianten in den Klassen ausprobiert. Ich kann den Fehler aber leider nicht ausmerzen.

Ich hoffe ihr habt einen Tipp, wo ich was falsch gemacht habe.
Hier die in frage kommenden Klassen:
PingPong:
Java:
public class Pingpong extends JComponent implements ActionListener, MouseMotionListener, KeyListener
{
    //Anfangs X und Y Position
    public static int ballX=0;
    public static int ballY=0;
   
    //X und Y Geschwindigkeit
    public static int ballXSpeed=1;
    public static int ballYSpeed=-1;
   
    //Anfangsposition des Schlägers
    static int schlaegerSpielerX=0;
    static int schlaegerGegnerX=0;
   
    //Höhe und breite
    static int hoehe=800;
    static int breite=1200;
    //Schrift für die Punkte
    static Font font=new Font("Arial", Font.PLAIN, 20);
    static int spielerpoints=0;
    static int gegnerpoint=0;
   
   
    public Pingpong() {

        JFrame frame=new JFrame("Ping Pong");
        Draw draw=new Draw();
        Move move=new Move();
        Kollision kollision=new Kollision();
        Gegnermove gm=new Gegnermove();
        frame.add(draw);
        frame.addMouseMotionListener(this);
        frame.setSize(1200, 800);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   
    }

//Hier sind noch eininge Methoden der Listener vorhanden. Diese habe ich jetzt weggelassen, da sie nicht relevant sind.

Move:
Java:
import java.util.Timer;
import java.util.TimerTask;


public class Move {
Timer timer;
    public Move() {
    timer=new Timer();
    TimerTask TimerTask;
    timer.scheduleAtFixedRate(TimerTask=new TimerTask() {
       
        @Override
        public void run() {

            //Festlegen der Geschwindigkeit in x und y richtung
            Pingpong.ballX=Pingpong.ballX+Pingpong.ballXSpeed*2;
            Pingpong.ballY=Pingpong.ballY+Pingpong.ballYSpeed*2;
                       
            //wenn die position des balls an den rechten bildschirmrand schlägt springt er zurück
            if(Pingpong.ballX>=(1170))
            {
                Pingpong.ballXSpeed=-1;
            }
            //wenn die position des balls kleiner der des linken Randes ist
            if(Pingpong.ballX<=0)
            {
                Pingpong.ballXSpeed=1;
            }
            //wenn die position des balls größer als des Frames ist
            if(Pingpong.ballY>=(Pingpong.hoehe-15))//770)
            {
                Pingpong.ballYSpeed=-1;
            }
        }
    }, 0, 5);
    }
}

Kollision:
Java:
import java.util.Timer;
import java.util.TimerTask;


public class Kollision {
Timer timer;
    public Kollision() {
    timer=new Timer();
    TimerTask TimerTask;
    timer.scheduleAtFixedRate(TimerTask=new TimerTask() {
        @Override
        public void run() {
           
            if(Pingpong.ballY<=(Pingpong.hoehe-Pingpong.hoehe)+30)
            {
                Pingpong.ballYSpeed=1;
                Pingpong.spielerpoints+=1;
            }
            if(Pingpong.ballY>=(Pingpong.hoehe-30))
            {
                Pingpong.ballYSpeed=-1;
                Pingpong.gegnerpoint+=1;
            }
            if(Pingpong.ballX<=(Pingpong.breite-Pingpong.breite)+30)
            {
                Pingpong.ballXSpeed=1;
            }
            if(Pingpong.ballX>=(Pingpong.breite)-30)
            {
                Pingpong.ballXSpeed=-1;
            }
               
           
            //Der 3 Fall wurde verändert, damit der ball vom schläger und nicht mitten im Bildschirm abprallt
            //wenn die horizontale des balls größer ist als die länge des Spieler schlägers und
            //wenn die hörizontale des balls kleiner ist als die Länge des spieler schläger +150 und
            //wenn die vertikale des balls größer als der obere Rand ist
            if(Pingpong.ballX>=Pingpong.schlaegerSpielerX&&Pingpong.ballX<=Pingpong.schlaegerSpielerX-150&&Pingpong.ballY>=20)
            {
                //dann wird die geschwindigkeit positiv;
                Pingpong.ballYSpeed=1;   
            }

        }
       
    }, 0, 6);
    }

}

und gegnermove:
Java:
import java.util.Timer;
import java.util.TimerTask;


public class Gegnermove {
Timer timer;
    public Gegnermove() {
    timer=new Timer();
    TimerTask TimerTask;
    timer.scheduleAtFixedRate(TimerTask=new TimerTask() {
        @Override
        public void run() {
           
            //Gegnermove
            //wenn der ball in der oberen Hälfte ist und er in der horizontalen kleiner ist als der Gegner schläger +75
            if(Pingpong.ballY<Pingpong.hoehe/2&&Pingpong.ballX<=Pingpong.schlaegerGegnerX+75)
            {//und wenn der ball in der oberen hälfte in der horizontalen kleiner als die hälfte der breite ist
                //und wenn der gegner schläger in der horiz. größer als die hälfte der breite ist
                if(Pingpong.ballX<=Pingpong.breite/2 && Pingpong.schlaegerGegnerX>=Pingpong.breite/2)
                {//dann wandert der gegnerschläger nach links
                    Pingpong.schlaegerGegnerX-=1;
                }
            }
            //wenn der ball in der horizontalen größer als die breite des Spielfelds ist
            //und der gegner schläger kleiner als die hälfte des felds
            if(Pingpong.ballX>=Pingpong.breite/2 && Pingpong.schlaegerGegnerX<=Pingpong.breite/2)
                {//dann wandert der gegnerschläger nach rechts
                    Pingpong.schlaegerGegnerX+=1;
                }

//            //wenn die horizontale des balls größer gleich das ende des Gegner Schlägers ist
//            if(Pingpong.ballX>=Pingpong.schlaegerGegnerX+75)
//            {
//                Pingpong.schlaegerGegnerX=5;
//            }
//            //wenn die horizontale des balls kleiner oder gleich der des gegner schlägers ist
//            if(Pingpong.ballX<=Pingpong.schlaegerGegnerX+75)
//            {
//                Pingpong.schlaegerGegnerX=-5;
//            }
//            //Wenn der ball am oberen Rand anschlägt
//            if(Pingpong.ballY<=(Pingpong.hoehe-Pingpong.hoehe)+30)
//            {
//                //fliegt er zurück
//                Pingpong.ballYSpeed=1;
//                //und der spieler bekommt einen punkt
//                Pingpong.spielerpoints+=1;
//            }
//       
//
////        //Wenn der Ball in der unteren Hälfte ist
//        if(Pingpong.ballY>=Pingpong.hoehe/2)
//        //wenn der ball am unteren rand anschlägt
//        if(Pingpong.ballY>=(Pingpong.hoehe-30))//770)
//        {
//            //fliegt er zurück
//            Pingpong.ballYSpeed=-1;
//            //und der gegner bekommt einen Punkt
//            Pingpong.gegnerpoint+=1;
//        }
           
        }
    }, 0, 5);
    }

}

Ich hoffe mir kann jemand die schwachstelle aufzeigen. anschließend würde ich dann mit dem abprallen am unteren und oberen balken weiter machen.
 

Alex2013

Bekanntes Mitglied
So den ersten Teil habe ich jetzt. Die Punkte werden gezählt und die Bewegungen laufen auch recht sauber.

Aber der Ball reagiert noch nicht auf die Kollision mit den jeweiligen Balken und springt dann zurück...

Hat hier zufällig jemand einen Tipp? @Meniskusschaden oder @Robat wisst ihr zufällig weiter?

Mein aktueller Code für die Kollisionsklasse ist wie folgt:
Java:
import java.util.Timer;
import java.util.TimerTask;


public class Kollision {
Timer timer;
    public Kollision() {
    timer=new Timer();
    TimerTask TimerTask;
    timer.scheduleAtFixedRate(TimerTask=new TimerTask() {
        @Override
        public void run() {
           
            if(Variablen.ballX+30>=Variablen.breite)
            {
                Variablen.ballXSpeed=-1;
            }
            if(Variablen.ballX+15<=0)
            {
                Variablen.ballXSpeed=1;
            }
            if(Variablen.ballY+50>=Variablen.hoehe)
            {
               
                Variablen.ballYSpeed=-1;Variablen.gegnerpoint+=1;
            }
            if(Variablen.ballY+15<=0)
            {
           
                Variablen.ballYSpeed=1;    Variablen.spielerpoints+=1;
            }
            if(Variablen.ballX==Variablen.schlaegerSpielerX&&Variablen.ballY==Variablen.schlaegerSpielerY&&Variablen.ballX<=Variablen.schlaegerSpielerX+150&&Variablen.ballY==Variablen.hoehe)
            {
                Variablen.ballYSpeed=-1;
            }
            if(Variablen.ballX==Variablen.schlaegerGegnerX&&Variablen.ballY==Variablen.schlaegerGegnerX&&Variablen.ballX<=Variablen.schlaegerGegnerX+150&&Variablen.ballY==0)
            {
                Variablen.ballYSpeed=1;
            }
               
        }
       
    }, 0, 6);
    }

}
 

Robat

Top Contributor
Wie hast du denn dein Spieler / Schläger aufgebaut?
Würde dir hjier zu der Rect Klasse raten.
Dann kannst du die Kollision recht einfach aufbauen:

Java:
    publicvoid checkCollision(){
        if(game.getPanel().getPlayer().getBounds().intersects(ball.getBounds()) || game.getPanel().getEnemyPlayer().getBounds().intersects(ball.getBounds()))
            xa =-xa;
    }
 

Alex2013

Bekanntes Mitglied
Ich habe das gesamte etwas einfacher gehalten. Ich hoffe ich muss den gesamten Code nicht umschreiben, wenn ich mit der Rect Klasse arbeite.
Mein Code siehe wie folgt:
Java:
protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d=(Graphics2D) g;
        //Rendern der Grafiken
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
       
        //Erstellen des Spielfelds
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
       
        //Erstellen des Balls
        g.setColor(Color.RED);
        g.fillOval(ballposX, ballposY, 30, 30);

        //Erstellen der Punkte
        g.setColor(Color.BLACK);
        g.setFont(schrift);
        g.drawString(""+spielerpunkte, 40, height/2);
       
        //Erstellen des Spielerschlägers
        g.setColor(Color.BLACK);
        g.fillRect(schlaegerSpielerX,schlaegerSpielerY-40 , 150, 20);
        repaint();
    }

Ich werde mal sehen wie ich das umsetze
 

Robat

Top Contributor
Ach soo.. ein bisschen sehr vereinfacht :p Für das nächste mal würde ich dir raten ein eigenes Objekt für deinen Ball, Spieler und Gegner zu machen, mit x,y Koords, ySpeed, xSpeed, einer update Methode, einer checkCollisionMethode und einer paint Methode. Das macht vieles einfacher.

if(Variablen.ballX==Variablen.schlaegerSpielerX&&Variablen.ballY==Variablen.schlaegerSpielerY&&Variablen.ballX<=Variablen.schlaegerSpielerX+150&&Variablen.ballY==Variablen.hoehe)
{
Variablen.ballYSpeed=-1;
}
if(Variablen.ballX==Variablen.schlaegerGegnerX&&Variablen.ballY==Variablen.schlaegerGegnerX&&Variablen.ballX<=Variablen.schlaegerGegnerX+150&&Variablen.ballY==0)
{
Variablen.ballYSpeed=1;
}
Wenn ich das gerade richtig überflogen habe, dann ist deine Bedingung hier falsch.
Was du momentan prüfst ist in Worten ausgedrückt folgendes:

Code:
Wenn ( (der Ball die selbe X  Koordinate wie der Spieler hat) [B]UND [/B](der Ball die selbe Y Koordinate wie der Spieler hat) [B]und [/B](der Ball kleiner gleich der X Koordinate des Spielers ) [B]und [/B](der Ball gleichder Höhe) )

Was du eigentlich nur prüfen musst ist in Worten ausgedrückt folgendes:

Code:
Wenn ( (der Ball die selbe X Koordinate des Spielers hat) && (der Ball zwischen der oberen Y Koord. des Spielers und der unteren Y Koord. des Spielers ) ) dann..

Dabei könntest du die zweite BEdingung durch y + spieler.height / 2 und y - spieler.height/2 darstellen.

Gruß
Robert
 

Alex2013

Bekanntes Mitglied
Hey Robat, vielen Dank für deine schnelle Antwort :)
das werde ich gleich auch noch ausprobieren.

Ich habe jetzt folgenden Code. Mit diesem ist sowohl das Abprallen an allen Seiten als auch das Abprallen vom Schläger gesichert.
Was sagst du dazu?(Ist vlt. etwas lang aber klappt :) ):
Java:
//Anstoß des Balls linker Rand
        if(PingPongEinzelspieler.ballposX<=0)
        {
            PingPongEinzelspieler.geschwindigkeitX=10;
        }
        //Anstoß des Balls an der linken Seite des Schlägers und linke seite des balls ist kleiner als die Länge des Schlägers und die untere Seite des Balls ist größer als die höhe des schlägers
        if(PingPongEinzelspieler.ballposX>=PingPongEinzelspieler.schlaegerSpielerX&&PingPongEinzelspieler.ballposX<=PingPongEinzelspieler.schlaegerSpielerX+150&&PingPongEinzelspieler.ballposY+30>=(PingPongEinzelspieler.height-60))
        {
            PingPongEinzelspieler.geschwindigkeitY=-10;
        }
        //Anstoß des Balls am rechten Rand
        if(PingPongEinzelspieler.ballposX+30>=PingPongEinzelspieler.width)
        {
            PingPongEinzelspieler.geschwindigkeitX=-10;
        }
        //Anstoß des Balls oberer Rand
        if(PingPongEinzelspieler.ballposY<=0)
        {
            PingPongEinzelspieler.geschwindigkeitY=10;
        }
        //Anstoß des Balls unterer Rand
        if(PingPongEinzelspieler.ballposY+50>=PingPongEinzelspieler.height)
        {
            PingPongEinzelspieler.geschwindigkeitY=-10;
        }
 

Robat

Top Contributor
Ist vlt. etwas lang aber klappt :)

Das ist der springende Punkt :p - es gibt einen unterschied zwischen "so programmieren, dass es funktioniert" und "so programmieren, dass es funktioniert und performant" ist.

“Measuring programming progress by lines of code is like measuring aircraft building progress by weight.”
— Bill Gates

aber das soll ein anderes Thema sein :)

Wie gesagt, so wie dein Code aufgebaut ist wird das schon funktionieren.

Nimm dir vielleicht mal als nächste die Aufgabe ein Ping Pong Spiel mit versch. Klassen und Objekten zu schreiben, MVC zu trennen etc.
Dazu gehört auch die Namenskonventionen einzuahlten (das Variablennamen immer klein und in CammelCase geschrieben werden). Ist aber eher Off-Topic :p
 

Alex2013

Bekanntes Mitglied
@Robat: probier das jar mal bitte aus und gib mir eine Rückmeldung. Es geht darum was wie passiert wenn du viele Punkte hast oder wenige und zu wenige Punkte hast...
 

Anhänge

  • Pingpong Einzelspieler.jar
    2,4 KB · Aufrufe: 2
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Mein Jump and Run charakter bewegt sich nicht mehr rückwärts... Spiele- und Multimedia-Programmierung 0
N der Player bewegt sich nicht Spiele- und Multimedia-Programmierung 14
S Polygon bewegt sich nach mehreren aufrufen immer schneller Spiele- und Multimedia-Programmierung 3
xFearofdarkness Feinde überlappen sich in Java Spiel Spiele- und Multimedia-Programmierung 3
R Memory - Nicht alle Button lassen sich aktivieren? Spiele- und Multimedia-Programmierung 1
P Sich bewegende Kamera Spiele- und Multimedia-Programmierung 12
I Wo befindet sich ein Punkt? Spiele- und Multimedia-Programmierung 6
R Game Loop verhält sich eigenartig Spiele- und Multimedia-Programmierung 1
Blender3D VLCJ Video lässt sich nicht mehr abspielen nach mysql Installation Spiele- und Multimedia-Programmierung 1
Androbin Mein Spiel will sich nicht zeichnen lassen !!! Spiele- und Multimedia-Programmierung 7
S Animation zieht "Spur" hinter sich her Spiele- und Multimedia-Programmierung 2
M Bildschirmgröße ändert sich Spiele- und Multimedia-Programmierung 10
M Würdet ihr sagen Java Applets eignen sich gut Spiele- und Multimedia-Programmierung 5
J Java3D - Farben vermischen sich Spiele- und Multimedia-Programmierung 7
E [LWJGL] Karusell, mehrere Objekte drehen sich um einen Mittelpunkt Spiele- und Multimedia-Programmierung 31
CookieSoft 3D Würfel will sich nicht drehen! [LWJGL] Spiele- und Multimedia-Programmierung 2
M Beim schießen richtet sich die Kugel nach der Maus aus (Quaternion) Spiele- und Multimedia-Programmierung 5
J Pufferproblem bei sich wiederholenden MouseEvents Spiele- und Multimedia-Programmierung 4
T JOGL im OrthoMode und Texturen verfärben sich Spiele- und Multimedia-Programmierung 3
S Programm hängt sich auf wenn Lied abspielt Spiele- und Multimedia-Programmierung 4
W 2 Bälle, die sich abstoßen Spiele- und Multimedia-Programmierung 24
F RPG - Spielfigur soll sich nicht frei bewegen können. Anregugen wären gerne gesehen^^ Spiele- und Multimedia-Programmierung 13
Ivan Dolvich [LWJGL] Texturen überlagern sich Spiele- und Multimedia-Programmierung 2
P JFileChooser öffnet sich drei mal Spiele- und Multimedia-Programmierung 4
Dragonfire Java Sound API - Lautstärke ändert sich nicht Spiele- und Multimedia-Programmierung 2
H Jogl-Animator - Inhalt ändert sich nicht Spiele- und Multimedia-Programmierung 4
M Sich nach links verschiebendes Bild Spiele- und Multimedia-Programmierung 2
L Figur soll sich selbständig Bewegen Spiele- und Multimedia-Programmierung 12
B Bounds drehen sich nicht mit.... Spiele- und Multimedia-Programmierung 7
R Eignet sich Java für ein Beat'em'Up? Spiele- und Multimedia-Programmierung 3
R Kreuz lässt sich nicht zeichnen Spiele- und Multimedia-Programmierung 11

Ähnliche Java Themen

Neue Themen


Oben