Spiel Programmieren mit BCB 6



  • promicha schrieb:

    Don Karlo schrieb:

    kann man auch ohne API(DX, Open GL) ein kleines game machen?
    z.B. eine Wiese(ScrollBild) über die man mit einer Figur (Bild) per Pfeiltasten läuft?

    Ja kann man mit Bitmap und Canvas

    gruß Micha

    Hmm hab mich mal nach Canvas umgesehn, aber nix gefunden, bzw kein Beispiel für dessen Funktion. Kannst du eventuel ein kleines Beispiel geben?(wäre Supi) einfach nur ein Images per PfeilTasten steuern. Für eine Animation von 3 Bildern ( linker Schritt, mitte, rechter schritt,mitte, linker schritt ....usw) brauch ich doch noch kein Open GL oder?



  • Nein das Stimmt dafür brauchste kein OpenGL!

    Schau mal hier her:
    http://www.c-plusplus.net/forum/viewtopic.php?t=67600

    promicha hat nen guten Code erstellt 🙂



  • Hmm den Thread kenn ich, da hat er nur geschrieben wie man mehrere Bilder animiert, aber net wie man sie gezielt mit den Pfeiltasten verschieben kann.



  • So, fertig.

    @Don Karlo
    @Ag3nt

    Ich habe jetzt mal auf die ganz Schnelle ein kleines Spiel erstellt, nichts
    Grossartiges, aber zum kennenlernen der Canvas Funktionen ausreichend.

    Hinweis
    Vor weg sei gesagt, das ich das ebend zwischen Tür und Angel programmiert
    habe, daher ist der Code auch dementsprechen, bitte gewöhnt euch nicht an
    viele Globale Variablen zu setzten, benutzt Strukturen und so. Ich möchte
    euch nicht zum schlechten Programmierstill führen, daher seht den Code
    bitte als reines "Canvas-Beispiel" an.

    Das Raumschiff wird mit der Maus gesteuert und mit der linken Maustaste
    wird gefeuert.
    Durch druck auf "q" kann man das Spiel verlassen, und bei 640 Punkte endet
    es von selbst.

    So, wenn ihr den Hinweis gelesen habt und auch Verstanden habt, so könnt ihr
    das Projekt "BCBGame" hier runterladen

    @Don Karlo
    Um die Pfeiltasten abzufragen, benutz man OnKeyDown und OnKeyUp.
    Canvas sind in der Hilfe sehr gut beschrieben, schaue dir mal die Hilfe-FAQ
    von Junix an: ??? Junix wo ist die URL ???
    Ansonsten "C++Builder-Hilfe"->"VCL-Referenz"->"Alphabetische Liste der..."->"TC"->"TCanvas"
    oberhalb sind die links zu Methoden und Eigenschaften

    gruß Micha



  • promicha: über der Threadübersicht z.B.

    -junix



  • Ah jetzt ja,

    war mir nicht gleich aufgefallen, du hattest es sonst in deiner Signatur.

    also Don Karlo, lese dir das mal durch und du wirst sehen wie gut die Hilfe
    ist.

    gruß Micha



  • Erst einmal Gratulation sieht super aus.

    Kannst du den Code vielleicht bischen erklären ???

    Im momment plan ich erlich gesagt fast nichts davon 🙂 Nagut ein Teil schon aber die *Bitmap geschichte z.B. nicht 😞

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include "jpeg.hpp"
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    int backpos=0,shipX=320,shipY=400;
    bool gegnerda[15];
    int gegnerbold = 0;
    bool GameOver = false;
    long Punkte = 0;
    bool fire = false;
    int firecount = 0;
    int energy = 100;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
            Form1->Close();        
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
            GameOver = false;
            //Buttons unsichtbar
            Button1->Visible = false;
            Button2->Visible = false;
            Form1->Cursor = crSizeAll;
            //Bitmaps erstellen
            Graphics::TBitmap *puffer = new Graphics::TBitmap();
            Graphics::TBitmap *backpic = new Graphics::TBitmap();
            Graphics::TBitmap *ship = new Graphics::TBitmap();
            Graphics::TBitmap *gegnerA = new Graphics::TBitmap();
            Graphics::TBitmap *gegnerB = new Graphics::TBitmap();
            puffer->Width = 640;
            puffer->Height = 480;
            //Grafiken in die Bitmaps laden
            TJPEGImage *jtemp = new TJPEGImage();
            jtemp->LoadFromFile(ExtractFilePath(ParamStr(0))+"back.jpg");
            backpic->Assign(jtemp);
            delete jtemp;
            ship->LoadFromFile(ExtractFilePath(ParamStr(0))+"ship.bmp");
            gegnerA->LoadFromFile(ExtractFilePath(ParamStr(0))+"gegnerA.bmp");
            gegnerB->LoadFromFile(ExtractFilePath(ParamStr(0))+"gegnerB.bmp");
            //Transparents Einstellung für Schiff und Gegner
            ship->TransparentColor = clBlack;
            ship->Transparent = true;
            gegnerA->TransparentColor = clBlack;
            gegnerA->Transparent = true;
            gegnerB->TransparentColor = clBlack;
            gegnerB->Transparent = true;
            //Alle Gegner aktivieren
            for (int w=0;w<16;w++) {
                    gegnerda[w] = true;
            }
            DWORD idleTime;
            bool alleweg;
            bool treffer = false;
            int gpos;
            //Spiel Schleife
            while (!GameOver) {
                    //Zeit setzten
                    idleTime = GetTickCount() + 50;
                    //Programm Messages abarbeiten
                    Application->ProcessMessages();
                    //Hintergrund in Puffer zeichnen
                    puffer->Canvas->CopyRect(Rect(0,0,640,480),backpic->Canvas,Rect(0,960-backpos,640,1440-backpos));
                    backpos++;
                    if (backpos == 960) {
                            backpos = 1;
                    }
    
                    // Shiff reinzeichnen
                    puffer->Canvas->Draw(shipX,shipY,ship);
                    //Laserstrahl wenn fire = true
                    if (fire && firecount<4) {
                            firecount++;
                            puffer->Canvas->Pen->Color = clAqua;
                            puffer->Canvas->PenPos = Point(shipX+39,shipY);
                            puffer->Canvas->LineTo(shipX+39,0);
                            energy = energy - 2;
                    } else if (firecount >=4 && firecount < 20) {
                            firecount++;
                    } else {
                            treffer = false;
                            firecount = 0;
                    }
                    if (!fire) {
                            firecount = 0;
                            if (energy<100)
                                    energy++;
                    }
                    //Energie Balken zeichnen
                    puffer->Canvas->Rectangle(20,460,122,470);
                    puffer->Canvas->Brush->Color = clYellow;
                    puffer->Canvas->FillRect(Rect(21,461,21+energy,469));
                    if (energy <= 0)
                            GameOver = true;
    
                    //nun kommen noch die Gegner
                    alleweg = true;
                    gpos = 20;
                    gegnerbold++;
                    if (gegnerbold >=30)
                            gegnerbold = 0;
    
                    for (int r=8;r<16;r++) {
                            if (gegnerda[r]) {
                                    alleweg = false;
                                    if (firecount > 0 && firecount < 5) {
                                            if (shipX+39>=gpos && shipX+39<=gpos+60 && !treffer) {
                                                    Punkte = Punkte + 10;
                                                    gegnerda[r] = false;
                                                    treffer = true;
                                            } else {
                                                    if (gegnerbold<=15) {
                                                            puffer->Canvas->Draw(gpos,80,gegnerA);
                                                    } else {
                                                            puffer->Canvas->Draw(gpos,80,gegnerB);
                                                    }
                                            }
                                    } else {
                                            if (gegnerbold<=15) {
                                                    puffer->Canvas->Draw(gpos,80,gegnerA);
                                            } else {
                                                    puffer->Canvas->Draw(gpos,80,gegnerB);
                                            }
                                    }
                            }
                            gpos = gpos + 70;
                    }
                    gpos = 20;
                    for (int i=0;i<8;i++) {
                           if (gegnerda[i]) {
                                    alleweg = false;
                                    if (firecount > 0 && firecount < 5) {
                                            if (shipX+39>=gpos && shipX+39<=gpos+60 && !gegnerda[i+8] && !treffer) {
                                                    Punkte = Punkte + 10;
                                                    gegnerda[i] = false;
                                                    treffer = true;
                                            } else {
                                                    if (gegnerbold<=15) {
                                                            puffer->Canvas->Draw(gpos,10,gegnerA);
                                                    } else {
                                                            puffer->Canvas->Draw(gpos,10,gegnerB);
                                                    }
                                            }
                                    } else {
                                            if (gegnerbold<=15) {
                                                    puffer->Canvas->Draw(gpos,10,gegnerA);
                                            } else {
                                                    puffer->Canvas->Draw(gpos,10,gegnerB);
                                            }
                                    }
                            }
                            gpos = gpos + 70;
                    }
                    if (alleweg) {
                            for (int i=0;i<16;i++) {
                                    gegnerda[i] = true;
                            }
                    }
    
                    //Punkte Reinschreiben
                    puffer->Canvas->Brush->Style = bsClear;
                    puffer->Canvas->Font->Color = clYellow;
                    puffer->Canvas->Font->Name = "Arial";
                    puffer->Canvas->Font->Size = 16;
                    puffer->Canvas->Font->Style << fsBold;
                    puffer->Canvas->TextOutA(20,10,"Score: "+IntToStr(Punkte));
    
                    //so Spielende bei 640 Punkte mal festlegen
                    if (Punkte >= 640) {
                            GameOver = true;
                    }
                    //Zeit abwarten
                    while (GetTickCount() < idleTime) {
                            Application->ProcessMessages();
                    }
                    //Puffer auf Form kopieren
                    Form1->Canvas->CopyRect(Rect(0,0,640,480),puffer->Canvas,Rect(0,0,640,480));
            }
            //Speicher Aufräumen
            delete puffer;
            delete backpic;
            delete ship;
            delete gegnerA;
            delete gegnerB;
            //Form wieder ihr Standart Face geben
            Form1->Canvas->Brush->Color = clBtnFace;
            Form1->Canvas->FillRect(Rect(0,0,640,480));
            //Buttons sichtbar
            Button1->Visible = true;
            Button2->Visible = true;
            Form1->Cursor = crDefault;
            Punkte = 0;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
            //Wenn q Taste gedrückt, dann Spiel verlassen
            if (char(Key) == 'Q')
                    GameOver = true;
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
            //Schiff position mit MausCursor koordinieren
            if (X<640 && X>0)
                    shipX = X-39;
    
            if (Y>150 && Y<410)
                    shipY = Y-30;
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
            //Laser an
            fire = true;        
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
            //Laser aus
            fire = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
            //Fenster-Buttons deaktivieren, da Exit per Button
            DeleteMenu(GetSystemMenu(Handle, false), SC_CLOSE, MF_BYCOMMAND);
            DeleteMenu(GetSystemMenu(Handle, false), SC_MINIMIZE, MF_BYCOMMAND);
            DeleteMenu(GetSystemMenu(Handle, false), SC_MAXIMIZE, MF_BYCOMMAND);
    }
    //---------------------------------------------------------------------------
    


  • Also nun hab ich den Code eigenlich so langsam verstanden 🙂



  • Ja?

    Gut, dann erkennst du sicherlich das hier mit Millisekunden gemessen wird.
    bei spielen ist das Timing immer wichtig, und es ist gut zu wissen wie
    lange eine Bestimmte Funktion braucht bis sie Ausgefürt wurde.

    Da im Code ja schon die Entsprechenden Vorgaben sind um folgende Aufgabe
    zu Lösen, dürfte es kein Problem sein.
    Aufgabe:
    Ändere den Code mal so ab das du messen kannst wie viel Millisekunden die
    Funktion nach "//Hintergrund im Puffer zeichen" benötigt, also dieses
    puffer->Canvas->CopyRect....
    Um dir diesen Wert dann anzeigen zu lassen kannst du die Funktion missbrauchen,
    welche die Punkte auf dem puffer schreibt, also statt Punkte deinen Wert.
    Die Lösung zu dieser Aufgabe springt einem Förmlich ins Gesicht.

    Der Sinn ist, zu verstehen das bei sehr vielen zeichnenoperation das ganze
    auch stark ausbremsen kann.

    gruß Micha



  • Trotzdem hab ich noch ein paar Fragen 🙂

    Also was bewirkt folgende Anweisung:

    Application->ProcessMessages();
    

    Ich werde von den BCB Beispielen einfach nicht schlau 😞

    Ansonsten Super Code 🙂

    Woher kann man solche Spiel Grafiken herbekommen ???



  • Micha ich versteh deine Aufgabe nicht ganz 😞

    So ???

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include "jpeg.hpp"
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    int backpos=0,shipX=320,shipY=400;
    bool gegnerda[15];
    int gegnerbold = 0;
    bool GameOver = false;
    long Punkte = 0;
    bool fire = false;
    int firecount = 0;
    int energy = 100;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
            Form1->Close();        
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
            GameOver = false;
            //Buttons unsichtbar
            Button1->Visible = false;
            Button2->Visible = false;
            Form1->Cursor = crSizeAll;
            //Bitmaps erstellen
            Graphics::TBitmap *puffer = new Graphics::TBitmap();
            Graphics::TBitmap *backpic = new Graphics::TBitmap();
            Graphics::TBitmap *ship = new Graphics::TBitmap();
            Graphics::TBitmap *gegnerA = new Graphics::TBitmap();
            Graphics::TBitmap *gegnerB = new Graphics::TBitmap();
            puffer->Width = 640;
            puffer->Height = 480;
            //Grafiken in die Bitmaps laden
            TJPEGImage *jtemp = new TJPEGImage();
            jtemp->LoadFromFile(ExtractFilePath(ParamStr(0))+"back.jpg");
            backpic->Assign(jtemp);
            delete jtemp;
            ship->LoadFromFile(ExtractFilePath(ParamStr(0))+"ship.bmp");
            gegnerA->LoadFromFile(ExtractFilePath(ParamStr(0))+"gegnerA.bmp");
            gegnerB->LoadFromFile(ExtractFilePath(ParamStr(0))+"gegnerB.bmp");
            //Transparents Einstellung für Schiff und Gegner
            ship->TransparentColor = clBlack;
            ship->Transparent = true;
            gegnerA->TransparentColor = clBlack;
            gegnerA->Transparent = true;
            gegnerB->TransparentColor = clBlack;
            gegnerB->Transparent = true;
            //Alle Gegner aktivieren
            for (int w=0;w<16;w++) {
                    gegnerda[w] = true;
            }
            DWORD idleTime;
            bool alleweg;
            bool treffer = false;
            int gpos;
            //Spiel Schleife
            while (!GameOver) {
                    //Zeit setzten
                    idleTime = GetTickCount() + 50;
                    //Programm Messages abarbeiten
                    Application->ProcessMessages();
                    //Hintergrund in Puffer zeichnen
                    puffer->Canvas->CopyRect(Rect(0,0,640,480),backpic->Canvas,Rect(0,960-backpos,640,1440-backpos));
                    backpos++;
                    puffer->Canvas->Brush->Style = bsClear;
                    puffer->Canvas->Font->Color = clYellow;
                    puffer->Canvas->Font->Name = "Arial";
                    puffer->Canvas->Font->Size = 16;
                    puffer->Canvas->Font->Style << fsBold;
                    puffer->Canvas->TextOutA(20,420,"Idle Time: "+IntToStr(idleTime));
    
                    if (backpos == 960) {
                            backpos = 1;
                    }
    
                    // Shiff reinzeichnen
                    puffer->Canvas->Draw(shipX,shipY,ship);
                    //Laserstrahl wenn fire = true
                    if (fire && firecount<4) {
                            firecount++;
                            puffer->Canvas->Pen->Color = clAqua;
                            puffer->Canvas->PenPos = Point(shipX+39,shipY);
                            puffer->Canvas->LineTo(shipX+39,0);
                            energy = energy - 2;
                    } else if (firecount >=4 && firecount < 20) {
                            firecount++;
                    } else {
                            treffer = false;
                            firecount = 0;
                    }
                    if (!fire) {
                            firecount = 0;
                            if (energy<100)
                                    energy++;
                    }
                    //Energie Balken zeichnen
                    puffer->Canvas->Rectangle(20,460,122,470);
                    puffer->Canvas->Brush->Color = clYellow;
                    puffer->Canvas->FillRect(Rect(21,461,21+energy,469));
                    if (energy <= 0)
                            GameOver = true;
    
                    //nun kommen noch die Gegner
                    alleweg = true;
                    gpos = 20;
                    gegnerbold++;
                    if (gegnerbold >=30)
                            gegnerbold = 0;
    
                    for (int r=8;r<16;r++) {
                            if (gegnerda[r]) {
                                    alleweg = false;
                                    if (firecount > 0 && firecount < 5) {
                                            if (shipX+39>=gpos && shipX+39<=gpos+60 && !treffer) {
                                                    Punkte = Punkte + 10;
                                                    gegnerda[r] = false;
                                                    treffer = true;
                                            } else {
                                                    if (gegnerbold<=15) {
                                                            puffer->Canvas->Draw(gpos,80,gegnerA);
                                                    } else {
                                                            puffer->Canvas->Draw(gpos,80,gegnerB);
                                                    }
                                            }
                                    } else {
                                            if (gegnerbold<=15) {
                                                    puffer->Canvas->Draw(gpos,80,gegnerA);
                                            } else {
                                                    puffer->Canvas->Draw(gpos,80,gegnerB);
                                            }
                                    }
                            }
                            gpos = gpos + 70;
                    }
                    gpos = 20;
                    for (int i=0;i<8;i++) {
                           if (gegnerda[i]) {
                                    alleweg = false;
                                    if (firecount > 0 && firecount < 5) {
                                            if (shipX+39>=gpos && shipX+39<=gpos+60 && !gegnerda[i+8] && !treffer) {
                                                    Punkte = Punkte + 10;
                                                    gegnerda[i] = false;
                                                    treffer = true;
                                            } else {
                                                    if (gegnerbold<=15) {
                                                            puffer->Canvas->Draw(gpos,10,gegnerA);
                                                    } else {
                                                            puffer->Canvas->Draw(gpos,10,gegnerB);
                                                    }
                                            }
                                    } else {
                                            if (gegnerbold<=15) {
                                                    puffer->Canvas->Draw(gpos,10,gegnerA);
                                            } else {
                                                    puffer->Canvas->Draw(gpos,10,gegnerB);
                                            }
                                    }
                            }
                            gpos = gpos + 70;
                    }
                    if (alleweg) {
                            for (int i=0;i<16;i++) {
                                    gegnerda[i] = true;
                            }
                    }
    
                    //Punkte Reinschreiben
                    puffer->Canvas->Brush->Style = bsClear;
                    puffer->Canvas->Font->Color = clYellow;
                    puffer->Canvas->Font->Name = "Arial";
                    puffer->Canvas->Font->Size = 16;
                    puffer->Canvas->Font->Style << fsBold;
                    puffer->Canvas->TextOutA(20,10,"Score: "+IntToStr(Punkte));
    
                    //so Spielende bei 640 Punkte mal festlegen
                    if (Punkte >= 640) {
                            GameOver = true;
                    }
                    //Zeit abwarten
                    while (GetTickCount() < idleTime) {
                            Application->ProcessMessages();
                    }
                    //Puffer auf Form kopieren
                    Form1->Canvas->CopyRect(Rect(0,0,640,480),puffer->Canvas,Rect(0,0,640,480));
            }
            //Speicher Aufräumen
            delete puffer;
            delete backpic;
            delete ship;
            delete gegnerA;
            delete gegnerB;
            //Form wieder ihr Standart Face geben
            Form1->Canvas->Brush->Color = clBtnFace;
            Form1->Canvas->FillRect(Rect(0,0,640,480));
            //Buttons sichtbar
            Button1->Visible = true;
            Button2->Visible = true;
            Form1->Cursor = crDefault;
            Punkte = 0;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
            //Wenn q Taste gedrückt, dann Spiel verlassen
            if (char(Key) == 'Q')
                    GameOver = true;
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
            //Schiff position mit MausCursor koordinieren
            if (X<640 && X>0)
                    shipX = X-39;
    
            if (Y>150 && Y<410)
                    shipY = Y-30;
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
            //Laser an
            fire = true;        
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
            //Laser aus
            fire = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
            //Fenster-Buttons deaktivieren, da Exit per Button
            DeleteMenu(GetSystemMenu(Handle, false), SC_CLOSE, MF_BYCOMMAND);
            DeleteMenu(GetSystemMenu(Handle, false), SC_MINIMIZE, MF_BYCOMMAND);
            DeleteMenu(GetSystemMenu(Handle, false), SC_MAXIMIZE, MF_BYCOMMAND);
    }
    //---------------------------------------------------------------------------
    


  • Ag3nt schrieb:

    Also was bewirkt folgende Anweisung:

    Application->ProcessMessages();
    

    Das bewirkt, dass das Programm an dieser Zeile erstmal stehenbleibt und alle Messages, die für das Fenster (die Form) anstehen, abgearbeitet werden. Wenn das für dich wie chinesisch klingt, schau dir mal in den FAQs das Thema "Windows Messages" an.



  • Ahso 🙂

    Ich dachte BCB macht das von alleine naja auch gut man lernt immer dazu 🙂



  • Ag3nt schrieb:

    Ich dachte BCB macht das von alleine

    Klar. Der schreibt dir auch dein Programm von ganz alleine. Du musst ihm nur deine Wünsche leise und zärtlich zuflüstern.



  • 😃 😃 😃 schön wäre es 😃 😃 😃



  • Ag3nt schrieb:

    Ahso 🙂

    Ich dachte BCB macht das von alleine naja auch gut man lernt immer dazu 🙂

    Ich habe schon mal erwähnt das der BCB eine Entwicklungsumgebung ist und
    nichts macht, dein Programm muß dafür sorgen das alles gut läuft.

    Schaue dir diesen Thread mal an, da habe ich es mal ironisch beschrieben
    wie es mit Messages ist:
    http://www.c-plusplus.net/forum/viewtopic.php?t=67718

    Spielgrafiken: Die habe ich mit Bordmitteln von Photo-Impact erstellt.

    Die Aufgabe: du sollst die Millisekunden messen, die von der CopyRect
    Routine verbraucht wird:
    puffer->Canvas->CopyRect(Rect(0,0,640,480),backpic->Canvas,Rect(0,960-backpos,640,1440-backpos));

    wie man Millisekunden messen kann, erkennt man an der Schleife, bissel
    Logic mit rein und du bekommst es hin!

    gruß Micha



  • Schaue dir diesen Thread mal an, da habe ich es mal ironisch beschrieben
    wie es mit Messages ist:
    http://www.c-plusplus.net/forum/viewtopic.php?t=67718

    Ich denke ich habs nun durch den Schnullertest kapiert 🙂

    Ich glaube ich habs:

    while (!GameOver) {
                    //Zeit setzten
                    idleTime = GetTickCount() + 50;
                    //Programm Messages abarbeiten
                    Application->ProcessMessages();
                    //Hintergrund in Puffer zeichnen
                    puffer->Canvas->CopyRect(Rect(0,0,640,480),backpic->Canvas,Rect(0,960-backpos,640,1440-backpos));
                    backpos++;
                    puffer->Canvas->Brush->Style = bsClear;
                    puffer->Canvas->Font->Color = clYellow;
                    puffer->Canvas->Font->Name = "Arial";
                    puffer->Canvas->Font->Size = 16;
                    puffer->Canvas->Font->Style << fsBold;
                    puffer->Canvas->TextOutA(20,420,"Idle Time: "+IntToStr(idleTime));
    
                    .....
    

    Oder soll es ohne +50 geschehen ???

    Mal ne andere Frage: Wo ist die Kolisionsabfrage ???



  • Ich gieb es auf 🙄

    Die Änderung ist in so fern schon richtig, aber damit erhälst du den Wert
    von "int idleTime" dieser Wert ist für die Schleife, der sagt dir aber nicht
    die Zeit die diese Funktion benötigt, man macht also:

    int ZeitMessung; // Neue Variable
    
    while (!GameOver) {
                    //Zeit setzten
                    idleTime = GetTickCount() + 50;
                    //Programm Messages abarbeiten
                    Application->ProcessMessages();
                    //Hintergrund in Puffer zeichnen
    
                    ZeitMessung = GetTickCount(); //Aktuelle Millisek. Zeit
    
                    puffer->Canvas->CopyRect(Rect(0,0,640,480),backpic->Canvas,Rect(0,960-backpos,640,1440-backpos));
    
                    ZeitMessung = GetTickCount() - ZeitMessung; // Hier Mathe
                    backpos++;
                    ....etc.
                    .....->textOutA(420,10,IntToStr(ZeitMessung)); // Hier schreiben
    

    Und schon hast du den Wert, probiere das mal für den ganzen Schleifenblock.
    Und überlege dann was für eine CPU du hast, und wie es wohl auf einen kleineren
    hinkommt mit dem Timing!

    gruß Micha



  • Achso meinst du das 🙂

    Ich muß dir echt danken. Durch dein Tutorial erstell ich mir grad einen Shooter.

    Kannst du mir vielleicht erklären wie man eine simple Kolisionsabfrage macht, wie in deinem Beispielcode ???

    Denn das versteh ich immer noch nicht.

    Die Bewegung ist klar die Variablen auch sowie die Schleife und die Punkte nur jedoch die Kollisionsabfrage beschäftigt mich 😞



  • Was mach ich hier falsch ???

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include "jpeg.hpp"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    
    // Public Variablen
    int backpos=0,shipX=300,shipY=400;
    bool GameOver=false,Fire=false;
    long Punkte=0;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
            if (char(Key) == 'Q')
                    GameOver = true;        
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
            Button1->Visible=False;
            // erstelle Puffer Bilder
            Graphics::TBitmap *puffer       = new Graphics::TBitmap();
            Graphics::TBitmap *backpic      = new Graphics::TBitmap();
            Graphics::TBitmap *ship         = new Graphics::TBitmap();
    
            // erstellt Hintergrund
            backpic->Width=640;
            backpic->Height=480;
    
            TJPEGImage *jtemp = new TJPEGImage();
            jtemp->LoadFromFile(ExtractFilePath(ParamStr(0))+"bg.jpg");
            backpic->Assign(jtemp);
            delete jtemp;
    
            // erstellt das Shiff
            ship->LoadFromFile(ExtractFilePath(ParamStr(0))+"ship1.bmp");
            DWORD idleTime;
            // Schleife für das Spiel
            while (!GameOver)
            {
    
                    //Zeit setzten
                    idleTime = GetTickCount() + 50;
                    //Programm Messages abarbeiten 
                    Application->ProcessMessages();
                    // Zeichnet Hintergrund
                    puffer->Canvas->CopyRect(Rect(0,0,640,480),backpic->Canvas,Rect(0,960-backpos,640,1440-backpos));
                    backpos++;
    
            }
    
    }
    //---------------------------------------------------------------------------
    

    [C++ Warnung] Unit1.cpp(78): W8004 'idleTime' wurde ein Wert zugewiesen, der nie verwendet wird


Anmelden zum Antworten