Pong-Problems



  • Hallo Zusammen

    Neulich hab ich mich an mein erstes Spiel gewagt. Ein einfaches Pong sollte es werden. Nun ja, ich bin fertig, aber es gibt noch einige Dinge wo ich nicht weiterweiss.

    Der Ball macht gelegentlich beim zurückschlagen einen Schlenker. Das heisst er ändert zwei Mal schnell hintereinander den Winkel für die Bewegung nach oben bzw. unten. Woran könnte das liegen? Was könnte ich dagegen tun??
    Dann möchte ich gerne die in den Spieleinstellungen für die Ball-Schläger berührung einen Standard-Signalton ausgeben. Finde aber einfach die Funktion nicht..

    Weiss nicht ob es was bringt den ganzen Code zu posten. Ist ziemlich riesig. Aber trotzdem mal hier:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "pong.h"
    #include "punkte.h"
    #include "pongspiel.h"
    #include "einstellungen.h"
    #include "about.h"
    
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TfrmPong *frmPong;
    PongSpiel *Spielfeld;
    Score *Spielpunkte;
    
    //---------------------------------------------------------------------------
    __fastcall TfrmPong::TfrmPong(TComponent* Owner)
            : TForm(Owner)
    {
            //den Zeiger auf die Zeichenfläche setzen
            ZFlaeche=frmPong->Canvas;
            //die Größe aus ClientRect holen
            FeldGroesse=frmPong->ClientRect;
            //ein neues Spielfeld erzeugen
            Spielfeld=new(PongSpiel);
            Spielfeld->SetzeSpielfeld(ZFlaeche, FeldGroesse);
            //eine neue Instanz für die Punkte erzeugen
            Spielpunkte=new(Score);
            //die Instanz an die andere Unit übergeben
            SetzePunkte(Spielpunkte);
            //das Spiel ist angehalten
            SpielPause=true;
            //der Menüeintrag für Pause ist abgeblendet
            mmPause->Enabled=false;
            //der Menüeintrag für Bestenliste ist scharf
            mmListe->Enabled=true;
            //der für Einstellungen ebenfalls
            mmEinstellungen->Enabled=true;
            //der für die Info-Box auch
            mmUeber->Enabled=true;
            //alle Timer sind angehalten
            TimerBall->Enabled=false;
            TimerSekunde->Enabled=false;
            TimerSpiel->Enabled=false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::FormPaint(TObject *Sender)
    {
            Spielfeld->ZeichneSpielfeld();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmBeendenClick(TObject *Sender)
    {
            frmPong->Close();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
            int AltePos;
            //wenn das Spiel angehalten ist, sofort wieder raus
            if (SpielPause==true)
                    return;
            //wenn die linke Maustaste gedrückt ist
            if (Shift.Contains(ssLeft)) {
                    //die aktuelle Position holen
                    AltePos=Spielfeld->LiefereSPos();
                    //erst übermalen
                    Spielfeld->ZeichneSchlaeger(AltePos);
                    //dann an der Mausposition neu zeichnen
                    Spielfeld->ZeichneSchlaeger(Y);
            }
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmPong::FormClose(TObject *Sender, TCloseAction &Action)
    {
            delete (Spielfeld);
            delete (Spielpunkte);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::TimerBallTimer(TObject *Sender)
    {
            BPos AlteBPos;
            int NeuX, NeuY;
            //die alte Position abfragen
            AlteBPos=Spielfeld->LiefereBPos();
            //den alten Ball "übermalen"
            Spielfeld->ZeichneBall(AlteBPos.X,AlteBPos.Y);
            //abhängig von der Bewegungsrichtung neue Koordinaten setzen
            if (AlteBPos.RichtungX)
                    NeuX=AlteBPos.X+10;
            else
                    NeuX=AlteBPos.X-10;
            //der Winkel kommt aus
            if (AlteBPos.RichtungY)
                    NeuY=AlteBPos.Y-AlteBPos.Winkel;
            else
                    NeuY=AlteBPos.Y+AlteBPos.Winkel;
            //den neuen Ball zeichnen
            Spielfeld->ZeichneBall(NeuX,NeuY);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::TimerSekundeTimer(TObject *Sender)
    {
            AnsiString RestZeit;
            //eine "Sekunde" abziehen
            AktuelleSZeit=AktuelleSZeit-1;
            //die Zeit in einen String umwandeln
            //zwei Leerzeichen anhängen, damit "Reste" überschrieben werden
            RestZeit=IntToStr(AktuelleSZeit)+ "  ";
            Spielfeld->ZeichneZeit(RestZeit);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmNeuClick(TObject *Sender)
    {
            //"läuft" ein Spiel? Dann erst einmal Pause
            if (SpielPause==false) {
                    mmPauseClick(Sender);
                    NeuesSpiel();
                    mmPauseClick(Sender);
            }
            else {
                    if (NeuesSpiel()==true)
                            mmPauseClick(Sender);
            }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmPauseClick(TObject *Sender)
    {
            //erst einmal prüfen wir den Status
            //läuft das Spiel?
            if (SpielPause==false) {
                    //alle Timer anhalten
                    TimerBall->Enabled=false;
                    TimerSekunde->Enabled=false;
                    TimerSpiel->Enabled=false;
                    //die Markierung im Menü einschalten
                    mmPause->Checked=true;
                    frmPong->Caption ="Pong Einzel -- Spiel ist angehalten!";
                    SpielPause=true;
            }
            else {
                    //das Intervall für das Spiel auf die verbleibende Zeit setzen
                    TimerSpiel->Interval=AktuelleSZeit*1000;
                    //alle Timer wieder an
                    TimerBall->Enabled=true;
                    TimerSekunde->Enabled=true;
                    TimerSpiel->Enabled=true;
                    //die Markierung im Menü abschalten
                    mmPause->Checked=false;
                    frmPong->Caption ="Pong Einzel";
                    SpielPause=false;
            }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::TimerSpielTimer(TObject *Sender)
    {
            //Spiel anhalten
            mmPauseClick(Sender);
            MessageDlg("Die Zeit ist um!",mtConfirmation,TMsgDlgButtons()<<mbOK,0);
            //nachsehen, ob das in die Bestenliste eingetragen werden kann
            if (Spielpunkte->NeuerEintrag()==true) {
                    Spielpunkte->ListeAusgeben(ZFlaeche, FeldGroesse);
                    Sleep(5000);
            }
            if (NeuesSpiel()==true)
                    //das Spiel "fortsetzen"
                    mmPauseClick(Sender);
            else
                    //sonst beenden
                    mmBeendenClick(Sender);
    }
    
    bool TfrmPong::NeuesSpiel() {
            if (MessageDlg("Neues Spiel starten?", mtConfirmation, TMsgDlgButtons()<<mbYes<<mbNo, 0)==mrYes) {
                    //die Zeit für das Spiel neu setzen
                    AktuelleSZeit=120;
                    //alles neu zeichnen
                    Spielfeld->ZeichneSpielfeld();
                    Spielfeld->NeuerBall();
                    Spielfeld->ZeichneZeit(IntToStr(AktuelleSZeit));
                    //Punkte zurücksetzen und zeichnen
                    Spielpunkte->LoeschePunkte();
                    Spielfeld->ZeichnePunkte("0");
                    //die Menüeinträge ein bzw ausschalten
                    mmPause->Enabled=true;
                    mmListe->Enabled=false;
                    mmEinstellungen->Enabled=false;
                    mmUeber->Enabled=false;
                    frmPong->Update();
                    return(true);
            }
            else
                    return(false);
    }
    
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmListeClick(TObject *Sender)
    {
            //Menüeintrag deaktivieren
            mmListe->Enabled=false;
            //die Bestenliste ausgeben
            Spielpunkte->ListeAusgeben(ZFlaeche,FeldGroesse);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmSehrEinfachClick(TObject *Sender)
    {
            //das Intervall für den Timer setzen
            TimerBall->Interval=200;
            //Menüeintrag markieren
            mmSehrEinfach->Checked=true;
            //Einstellungen setzen
            Spielfeld->SetzeEinstellungen(100,1,-20,2);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmEinfachClick(TObject *Sender)
    {
            TimerBall->Interval=100;
            mmEinfach->Checked=true;
            Spielfeld->SetzeEinstellungen(50,1,-5,5);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmMittelClick(TObject *Sender)
    {
            TimerBall->Interval=50;
            mmMittel->Checked=true;
            Spielfeld->SetzeEinstellungen(50,3,-5,15);
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmSchwerClick(TObject *Sender)
    {
            TimerBall->Interval=25;
            mmSchwer->Checked=true;
            Spielfeld->SetzeEinstellungen(50,10,-5,25);
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmSehrSchwerClick(TObject *Sender)
    {
            TimerBall->Interval=10;
            mmSehrSchwer->Checked=true;
            Spielfeld->SetzeEinstellungen(20,20,-5,40);
    }
    //---------------------------------------------------------------------------
    
    //passt das Formular an
    void TfrmPong::SetzeFormular(int Hoehe, int Breite) {
            //das Formular ändern
            frmPong->ClientHeight=Hoehe;
            frmPong->ClientWidth=Breite;
            //neu ausrichten
            frmPong->Position=poDesktopCenter;
            //den Zeiger neu positionieren
            //sicher ist sicher!
            ZFlaeche=frmPong->Canvas;
            //die Größe neu holen
            FeldGroesse=frmPong->ClientRect;
            Spielfeld->SetzeSpielfeld(ZFlaeche, FeldGroesse);
            Spielfeld->ZeichneSpielfeld();
    }
    
    void __fastcall TfrmPong::mmSpielfeldClick(TObject *Sender)
    {
            frmEinstellungen->ShowModal();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::mmUeberClick(TObject *Sender)
    {
    AboutBox->ShowModal();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TfrmPong::FormCreate(TObject *Sender)
    {
    
    }
    //---------------------------------------------------------------------------
    

    Ich nehme an der Fehler vom Winkel liegt irgendwo zwischen 89 und 109 aber eben, komm einfach nicht drauf.

    Danke schon mal für die Hilfe!

    MFG der Lehrling 🙂



  • Hallo

    Es hat wohl niemand Lust den Fehler für dich zu suchen. Benutz den Debugger, und sei es um die Ursache erstmal besser einzugrenzen zu können, damit du dann hier im Forum konkrete Beschreibungen hinzufügen kannst.

    bis bald
    akari



  • Hallo

    Ich brauch nur hilfe dabei, dafür ist doch so ein forum oder??
    Das Programm lässt sich ausführen der Debugger bringt keine Fehler.. Das ist ja mein Problem.
    Denkst du wirklich ich hätte das nicht ausprobiert?? Ich bin nicht blöd oder so.. Ich war schon am verzweifeln, es ist mir einfach nicht ersichtlich wo das Problem liegen könnte, darum frag ich ja hier um hilfe..

    bis bald



  • Hallo

    Offenbar hast du nicht verstanden, wofür du den Debugger einsetzen must. Du meinst den Compiler, wenn du sagt das das Programm ohne Fehler startet. Der Debugger bietet dir dann die Möglichkeit zur Laufzeit das Laufverhalten deines Programmes zu untersuchen. In dem Link aus meinem Post wird erklärt wie du den Debugger einsetzt, den dieser arbeitet nicht automatisch.

    Ja hier wird dir geholfen, und je besser du dein Problem hier darlegst desto höher ist auch die Wahrscheinlichkeit das hier jemand sich in deinen Quellcode einarbeitet und mitdebuggt.

    bis bald
    akari



  • Zudem ist der gezeigte Code ja nicht vollständig. Sinnvoll wäre es ggf., das komplette Projekt zur Verfügung zu stellen, so dass ein Interessent das ohne grosse Handarbeit in seinem BCB testen kann.



  • Wie kann ich das ganze Projekt zur Verfügung stellen?



  • verpacken und hochladen ?



  • ok. werd heute abend gleich mal das ganze hochladen und mit dem debugger rumprobieren.


Anmelden zum Antworten