Canvas ohne flimmern...



  • Hi!
    Wollte mit folgendem Code das Flimmern entfernen indem ich das Bild zeichne:

    void __fastcall TMain::Shuttlebewegung(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    Graphics::TBitmap *Shuttle = new Graphics::TBitmap;
    Shuttle->LoadFromFile(".\\Bilder\\Shuttle.bmp");
    
    Shuttle->TransparentColor=clBlack;
    Shuttle->Transparent=true;
    
    Image1->Canvas->Draw(X,Y,Shuttle);
    }
    

    Das Flimmern ist weg, nur lässt die Canvas Funktion das vorherige Bild immer stehen. Das will ich vermeiden. Habe es schon mit folgendem Code ausprobiert dieses Problem zu beheben:

    Image1->Picture = NULL;
    Image1->Canvas->Draw(X,Y,Shuttle);
    

    Nur habe ich dann wieder ein Flimmern.
    Wie kann ich das beheben?

    MfG
    Andi



  • Hallo

    ich verstehe dein Programm so, das du ein Hintergrund hast, über den du ein kleines Sprite (Shuttle) bewegen läßt.
    Ich denke dein Problem ist einfach, das ganze neu laden, überzeichnen und neu zeichnen zu lange dauert, als das eine flüssige Bewegung rauskommt.
    Vielleicht hilft es ja wenn du so vorgehst:
    -Initialisierung : Hintergrund und alle Sprites in einzelne Bitmaps laden, die Elemente des Forms sind, desweitern ein Buffer-Bitmap von der Größe des Hintergrunds
    -Neues Bild erstellen : Du kopierst den Inhalt des Hintergrunds in Buffer, dann alle Sprites an die aktuelle Position in den Buffer, zum Schluß Hintergrund in Canvas des Forms kopieren
    -Schließen : alle eigenen Bitmaps löschen

    bis bald
    akari



  • Sorry aber ich verstehe dich nicht ganz. Ich habe jetzt die Bilder am Anfang eingelesen:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Quelltext.h"
    //==============================================================================
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    
    Graphics::TBitmap *Shuttle = new Graphics::TBitmap;
    Graphics::TBitmap *Background = new Graphics::TBitmap;
    
    TMain *Main;
    //==============================================================================
    __fastcall TMain::TMain(TComponent* Owner)
            : TForm(Owner)
    {
    Shuttle->LoadFromFile(".\\Bilder\\Shuttle.bmp");
    Background->LoadFromFile(".\\Bilder\\Space.bmp");
    
    Shuttle->TransparentColor=clBlack;
    Shuttle->Transparent=true;
    
    }
    //==============================================================================
    
    void __fastcall TMain::Shuttlebewegung(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    
    Image1->Canvas->Draw(0,0,Background);
    Image1->Canvas->Draw(X-35,Y-30,Shuttle);
    
    }
    //==============================================================================
    

    bringt aber trotzdem nichts, es ist immer noch zu langsam.
    Oder wie hast du das gemeint?



  • Akari meint sicher:

    1 Hintergrund und Shuttle in ein (unsichtbares) Bitmap zeichnen - nacheinander.
    2 Inhalt des 'gemischten ' Bildes in Bitmat mit EINEM Draw in FImage drawen!



  • Gibt es keine einfachere Lösung?
    Mit der Methode zeichnet er mir immer den Hintergrund, d.h. Geschwindigkeit geht verloren.



  • Du kannst nicht alles haben! :p

    Schnell flackern oder SCHÖN langsam.

    Google mal nach DDraw, damit solls besser gehen - kenn ich aber nicht wirklich.



  • Hallo

    - ich habe das so gemeint

    TMain.hpp :
    class TMain : public TForm
    {
    ...
    private:	// Anwender-Deklarationen
    ...
    Graphics::TBitmap *Shuttle;
    Graphics::TBitmap *Background;
    Graphics::TBitmap *Buffer;
    
    public:
    ...
    };
    
    TMain.cpp
    __fastcall TMain::TMain(TComponent* Owner)
            : TForm(Owner)
    {
    Shuttle = new Graphics::TBitmap;
    Background = new Graphics::TBitmap;
    Buffer = new Graphics::TBitmap;
    Shuttle->LoadFromFile(".\\Bilder\\Shuttle.bmp");
    Background->LoadFromFile(".\\Bilder\\Space.bmp");
    Buffer->Height = Background->Height;
    Buffer->Width = Background->Width;
    
    ...
    }
    
    (OnDestroy-Event für TMain per Objectinspektor erstellen lassen)
    void __fastcall TMain::FormDestroy(TObject *Sender)
    {
      delete Shuttle;
      delete Background;
      delete Buffer;
    }
    
    void __fastcall TMain::Shuttlebewegung(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    
    Buffer->Canvas->Draw(0,0,Background);
    Buffer->Canvas->Draw(X-35,Y-30,Shuttle);
    Image1->Canvas->Draw(0,0,Buffer);
    }
    

    - Wie oft rufst du den Shuttlebewegung auf? Wahrscheinlich bei jedem KeyEvent, oder? Dann solltest du die Behandlung des Events und das Zeichen des Images entkoppeln, in dem du einen Timer (TTimer, Palette System) einbaust, den du auf 25/Minute (Timer->Interval = 40) einstellst. Dann erfolgt der Prozeß so :
    - Bei KeyEvents bestimmst du die neue Position des Shuttles und gibst die neuen Daten an Member-Variablen des Forms (siehe Bitmaps)
    - Im OnTimer-Event des Timers rufst du Shuttlebewegung() mit den Aktuellen Werten aus den Member-Variablen auf

    Ich hoffe du verstehst das und es funktioniert...

    bis bald
    akari



  • akari schrieb:

    Hallo

    - ich habe das so gemeint

    TMain.hpp :
    class TMain : public TForm
    {
    ...
    private:	// Anwender-Deklarationen
    ...
    Graphics::TBitmap *Shuttle;
    Graphics::TBitmap *Background;
    Graphics::TBitmap *Buffer;
    
    public:
    ...
    };
    

    WOW!!!!! 🙂 🙂 🙂 👍 👍
    DANKE!!! 😃

    es geht 🤡



  • Versuch mal mit

    DoubleBuffered = true;
    

Anmelden zum Antworten