"Bug" < ? Im Canvas?



  • Also hab hier ein projekt erstellt, es ging einfach darum mal nen gezeichnetes objekt zu haben das man rumziehen kann.

    http://uploaded.to/?id=bl2rg3

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    #pragma resource "blau.res"
    #define BallGroesse 50
    TForm1 *Form1;
    Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
    int CurrXLeft, CurrYTop, CurrXRight, CurrYBottom;
    bool MousePressed;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    CurrXLeft=Form1->Width-BallGroesse/2;
    CurrYTop=Form1->Height-BallGroesse/2;
    CurrXRight=Form1->Width+BallGroesse/2;
    CurrYBottom=Form1->Height+BallGroesse/2;
    Timer1->Interval = 15;
    Timer1->Enabled = true;
    Bitmap1->LoadFromResourceName((int)HInstance,"Blau");
    Form1->Canvas->StretchDraw(Rect(CurrXLeft,CurrYTop,CurrXRight,CurrYBottom),Bitmap1);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    CurrYTop++;
    CurrYBottom++;
    Form1->Canvas->FillRect(Rect(0,0,Form1->Width,Form1->Height));
    Form1->Canvas->StretchDraw(Rect(CurrXLeft,CurrYTop,CurrXRight,CurrYBottom),Bitmap1);
    if ( CurrYBottom >= Form1->Height )Timer1->Enabled = false;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
    if (  (( X >= CurrXLeft )&&( X <= CurrXRight ))&&(( Y >= CurrYTop )&&( Y <= CurrYBottom )) )MousePressed = true;
    Timer1->Enabled = false;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    if ( MousePressed ){
            if (( X < Form1->Width-100 ) && ( X > 0 ) && ( Y < Form1->Height-100 ) && ( Y > 0 ) ){
            Form1->Canvas->Brush->Color = clWhite;
            Form1->Canvas->FillRect(Rect(0,0,Form1->Width,Form1->Height));
            Form1->Canvas->StretchDraw(Rect(X,Y,X+BallGroesse,Y+BallGroesse),Bitmap1);
            CurrXLeft = X;
            CurrYTop  = Y;
            CurrXRight  = X+BallGroesse;
            CurrYBottom = Y+BallGroesse;
            }
    }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
    MousePressed = false;
    Timer1->Enabled = true;
    }
    //---------------------------------------------------------------------------
    

    so soweit ist ja alles okay. aber sagen wir mal ich lasse die kugel fallen, ja?

    dann fällt sie ja leicht verzögert. auch noch alles okay.

    jetzt fahre ich aber mit der maus über die kugel und taddaah sie fällt flüssig.

    wieso?

    PS: Das kompillierte projekt mit alt - f4 beenden



  • Pack das was du im Timer stehen hast in eine Schleife und füge ein Application->ProcessMessages hinzu. Ist zwar nicht der schönste Programmierstil aber das sollte den gewünschten Effekt haben.



  • und wieso geht es dann?
    und was wäre schönerer programmierstyl?



  • Schurke schrieb:

    und was wäre schönerer programmierstyl?

    Vermutlich wäre es schöner, die ganzen Canvas-Ausgaben in das OnPaint-Ereignis zu packen und diese einfach mittels Invalidate() das Neuzeichnen auszulösen.



  • Uiuiui das is doch mal ne tolle antwort ^^ danke werd ich gleich mal probieren 🙂

    Das erste mal das ich von Invaliddate() höre aber der hilfe nach hörts sich gut an 🙂

    Aber mal zur hauptfrage, warum läufst denn mit dem timer flüssig wenn die maus auf eines der objekte geht? ( habs mittlerweile in ne klasse gepackt )



  • Gute Frage. Müsste man mal mit dem Debugger nachsehen, wo der Unterschied liegt... Vermutlich wird durch das Bewegen der Maus über dem Ball, irgendein Ereignis öfter aufgerufen und in Folge dessen das Fenster öfter neu gezeichnet. Das könnte dann zu einem flüssigerem Ablauf führen.



  • Danke nochmal Joe. ich hab jetzt die zeichnung in den OnPaint, mit nem 1 Millisekunden zeiger immer Invalidate und dann noch Form1->DoubleBuffered = true; und jetzt zeichnet er auch noch bei 1000 objekten flüssig 😃


Anmelden zum Antworten