Tester für Animations-Prog gesucht (jetzt mit Thread)



  • @BF_31
    Das ist scheiße! Aber ich habe die Datei jetzt nochmal auf der MainPage meiner Homepage verlinkt. Siehe Signatur.
    Scheinbar kann man an Dateien, die auf dem geocities-Server liegen, nicht von "außen", sondern nur von einer geocities-Seite aus kommen.

    @noob
    Danke, dass du es getestet hast. Das bedeutet schonmal ein PLUS für den MMTimer.

    [ Dieser Beitrag wurde am 01.08.2002 um 03:52 Uhr von WebFritzi editiert. ]



  • Bei mir hats mit "Ziel speicher unter ..." geklappt. Allerdings habe ich nen Bug gefunden: Wenn man Animationsgeschwindigkeit ganz langsam macht, dann gibts Probleme ... Entweder hat man plötzlich zwei Karten, und/oder die Karte bewegt sich nicht ganz bis zu ihrem Zielpunkt und kann dann auch nciht mehr per Maus bewegt werden.



  • genauso ist es bei mir wie bei dEUs! ich hab die animationsgeschwindigkeit aber auf dem standardwert belassen



  • Scheiße! Bei mir funktioniert das ausgezeichnet. Vielleicht liegt's ja am Prozessor? Hab nen Celoron (oder Celeron?) mit 466 MHZ. Und der Code dazu sieht so aus (Wenn man auf den Button drückt, dann wird Button2Click() aufgerufen):

    // TBitmap kapselt ein HBITMAP mit einem eigenen DC (ist VCL)
    typedef  Graphics::TBitmap  FBitmap;
    
    struct FLOATPOINT
    {
        float  x;
        float  y;
    
        FLOATPOINT(float w, float z)
        {
           x = w;
           y = z;
        }
    
        FLOATPOINT(POINT p)
        {
           x = (float)p.x;
           y = (float)p.y;
        }
    
        FLOATPOINT(){};
    };
    
    typedef struct tagANIMATEINFO
    {
        //CBmpHandler*  This;
        FLOATPOINT       pFrom;
        FLOATPOINT       pTo;
        float            fSteps;
        int              iIter;
    } ANIMATEINFO, *LPANIMATEINFO;
    
    //  Prototypen
    VOID WINAPI CALLBACK TimerProc(UINT, UINT, DWORD, DWORD, DWORD);
    void                 DragPaintStep(RECT, TCanvas*);
    void                 DragPaintStep(POINT, TCanvas*);
    void                 AnimateTo(int, int);
    
    // Die globalen Variablen sind da, weil ich die Bitmap-Operationen noch 
    // in ne Klasse auslagern will.
    
    //  Globale Variablen
    FBitmap*  DragBmp;        // Das zu animierende Bitmap
    FBitmap*  BkgBmp;         // Das Hintergrund-Bitmap 
    FBitmap*  HelpBkgBmp;     // Ein Hilfs-Bitmap (wird in DragPaintStep() verwendet)
    int       width, height;  // Die Höhe und die Breite von DragBmp
    RECT      rcCard;         // (0,0,width,height)
    RECT      rcBkg;          // Die Position der Karte auf dem Fenster
    int       AnimationSpeed; // Der eingestellte Animations-Speed (500 - 10000)
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
       // tbAnimation ist die TrackBar (Position von 1 - 20)
       AnimationSpeed = tbAnimate->Position * 500;
       // In den Edit-Feldern stehen die Koordinaten des Endpunktes
       AnimateTo(Edit1->Text.ToInt(), Edit2->Text.ToInt());
    }
    //---------------------------------------------------------------------------
    
    void AnimateTo(int X, int Y)
    {
       POINT pFrom = ((TRect)rcBkg).TopLeft;
       POINT pTo   = Point(X,Y);
    
       int dx = pFrom.x - pTo.x;
       int dy = pFrom.y - pTo.y;
    
       float unitsToMove = sqrt(dx*dx + dy*dy);             // Satz des Pythagoras 
       float timePerStep = 1.0;                             // 1000 steps per second ( 1 step per millisecond )
       float unitsPerMs  = (float)AnimationSpeed / 1000.;   // Units per millisecond
       float timeToMove  = unitsToMove / unitsPerMs;        // Total time to move
    
       LPANIMATEINFO aniInfo = new ANIMATEINFO;
       aniInfo->pFrom  = FLOATPOINT(pFrom);
       aniInfo->pTo    = FLOATPOINT(pTo);
       aniInfo->fSteps = (float)(int)(timeToMove / timePerStep);
       aniInfo->iIter  = 0;
    
       // Vielleicht liegt's auch am zweiten Parameter???
       timeSetEvent((UINT)timePerStep, 0, TimerProc, (DWORD)aniInfo, TIME_PERIODIC);
    }
    //---------------------------------------------------------------------------
    
    //  Die Timer-Prozedur für den Multimedia-Timer
    VOID WINAPI CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
    {
       LPANIMATEINFO aniInfo = (LPANIMATEINFO)dwUser;
    
       FLOATPOINT  to     = aniInfo->pTo;
       FLOATPOINT  from   = aniInfo->pFrom;
       float       steps  = aniInfo->fSteps;
       int         i      = aniInfo->iIter;
    
       // Hier hört der Animations-Vorgang auf
       if(i >= steps)
       {
          delete aniInfo;                                       
          timeKillEvent(uID);
          POINT p = Point(to.x, to.y);
          // Nochmal das Bitmap am Endpunkt malen
          DragPaintStep(p, Form1->Canvas);
          return;
       }
    
       FLOATPOINT dP(to.x - from.x, to.y - from.y);
    
       // Den aktuellen Punkt berechnen
       POINT p_i;
       p_i.x = (int)(from.x + (i / steps) * dP.x);
       p_i.y = (int)(from.y + (i / steps) * dP.y);
    
       // Das Bitmap an aktueller Position malen
       DragPaintStep(p_i, Form1->Canvas);
    
       // Den Iterator um 1 erhöhen
       aniInfo->iIter++;
    }
    //---------------------------------------------------------------------------
    
    void RectBlt(TCanvas* cDest, RECT rcDest, TCanvas* cSrc, RECT rcSrc)
    {
       int left   = rcDest.left;
       int top    = rcDest.top;
       int width  = rcDest.right - left;
       int height = rcDest.bottom - top;
       BitBlt(cDest->Handle, left, top, width, height,
              cSrc->Handle, rcSrc.left, rcSrc.top, SRCCOPY);
    }
    //---------------------------------------------------------------------------
    
    void DragPaintStep(POINT pNew, TCanvas* Canvas)
    {
       RECT  rcNew = Rect(pNew.x, pNew.y, pNew.x + width, pNew.y + height);
       DragPaintStep(rcNew, Canvas);
    }
    //---------------------------------------------------------------------------
    
    void DragPaintStep(RECT rcNew, TCanvas* Canvas)
    {
       // Diese Funktion funzt auf jeden Fall, da ich sie auch zum Draggen benutze
       // und es dabei ja offensichtlich keine Probleme gibt.
       RECT rcIs;
       if(IntersectRect(&rcIs, &rcBkg, &rcNew))               //  Bereiche überlappen einander
       {
          //  Den neuen Background im Buffer speichern
          RECT rcRemainingOld = Rect(rcIs.left   - rcBkg.left,
                                     rcIs.top    - rcBkg.top,
                                     rcIs.right  - rcBkg.left,
                                     rcIs.bottom - rcBkg.top);
          RECT rcRemainingNew = Rect(rcIs.left   - rcNew.left,
                                     rcIs.top    - rcNew.top,
                                     rcIs.right  - rcNew.left,
                                     rcIs.bottom - rcNew.top);
          RectBlt(HelpBkgBmp->Canvas, rcCard, Canvas, rcNew);
          RectBlt(HelpBkgBmp->Canvas, rcRemainingNew, BkgBmp->Canvas, rcRemainingOld);
    
          //  Bitmap an neue Position malen
          RectBlt(Canvas, rcNew, DragBmp->Canvas, rcCard);
    
          //  Vorigen Background auf Form wiederherstellen
          RectBlt(BkgBmp->Canvas, rcRemainingOld, DragBmp->Canvas, rcRemainingNew);
          RectBlt(Canvas, rcBkg, BkgBmp->Canvas, rcCard);
    
          //  Alten Zustand der Pointer wiederherstellen
          FBitmap*  dummyBmp = BkgBmp;
          BkgBmp     = HelpBkgBmp;
          HelpBkgBmp = dummyBmp;
       }
       else                                                   //  Bereiche sind nicht überlappend
       {
          //  Alten Background auf Form wiederherstellen
          RectBlt(Canvas, rcBkg, BkgBmp->Canvas, rcCard);
          //  Alten Background im Buffer neu setzen
          RectBlt(BkgBmp->Canvas, rcCard, Canvas, rcNew);
          //  Bitmap an neue Position malen
          RectBlt(Canvas, rcNew, DragBmp->Canvas, rcCard);
       }
       rcBkg = rcNew;
    }
    //---------------------------------------------------------------------------
    

    Das Draggen mache ich auch mit DragPaintStep(), und das sieht ja offenbar ganz gut aus. Ich tippe auf die folgenden 2 Möglichkeiten:

    (1) Der Fehler liegt in AnimateTo() in der Berechnung der float-Werte
    (2) Es liegt am Prozessor. Vielleicht: Intel->OK, AMD->Geht nich!

    [ Dieser Beitrag wurde am 01.08.2002 um 16:10 Uhr von WebFritzi editiert. ]



  • Es wäre super, wenn sich jemand mal den Code anschauen würde. Ich würde mich auch freuen, wenn der eine oder andere BCB-Besitzer den Code ausprobieren würde. Einfach Paste&Copy und im Konstruktor der Form die Variablen initialisieren. Zum Draggen wird folgender Code benötigt:

    private:
        int   dX, dY;
        bool  Drag;
    
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
      if(FirstTime)
       {
          // Den Hintergrund speichern
          RectBlt(BkgBmp->Canvas, rcCard, Canvas, rcBkg);
          FirstTime = false;
       }
    
       RectBlt(Canvas, rcBkg, DragBmp->Canvas, rcCard);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
       if(PtInRect(&rcBkg, Point(X,Y)) && Button==mbLeft)
       {
          Drag = true;
          dX = X - rcBkg.left;
          dY = Y - rcBkg.top;
          ShowCursor(FALSE);
       }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
       if(Drag)
       {
          int x = X - dX;
          int y = Y - dY;
          DragPaintStep(Point(x,y), Canvas);
       }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
       if(Drag && Button==mbLeft)
       {
          Drag = false;
          ShowCursor(TRUE);
       }
    }
    


  • Ach ja, und wenn ihr das Prog testet, dann gebt bitte noch an, welches OS ihr habt und welchen Prozessor.



  • Danke für den Link;)
    Bei mir läuft alles ohne Probleme... die Probleme von dEUs habe ich nicht

    WindowsME
    AMD K6/2 450 Mhz



  • Aha. AMD - Intel kanns schonmal nicht sein. Ich würde das Programm ja zu gerne verbessern. Aber wie soll ich das anstellen, wenn es bei mir läuft. 😞



  • Bei mir läuft es auf der NT4 Kiste ebenfalls tadellos. Überhaupt keine Probs



  • @CengizS
    Dankeschön. Prozessor-Geschwindigkeit?

    @dEUs und <Zoig>
    Ich habe das Programm jetzt bezüglich der Resolution des MMTimers geändert und es hochgeladen. Wäre super, wenn ihr es jetzt nochmal testen würdet.

    [ Dieser Beitrag wurde am 01.08.2002 um 17:29 Uhr von WebFritzi editiert. ]



  • Ach ja das hab ich vergessen ...

    Das ist ein hp-Rechner mit 'nem Intel Pentium III Prozessor (1.0 GHz)
    Klein, handlich, nett 😉



  • Bei mir ist genau das selbe Problem wie bei dEUs und <Zoig>.

    Windows XP + Celeron 500 MHz



  • Ich habe jetzt das Prog dahingehend verändert, dass ich in der Statusleiste während der Animation die Steps mitzählen lasse. Am Beginn der Ani wird die benötigte Anzahl von Steps per MessageBox ausgegeben, und am Ende kommt noch ne MessageBox. Ich würde die, bei denen es nicht ging, bitten, das nochmal auszuprobieren, um zu schauen, ob der Timer auch bis zum Ende durchläuft. Tut er das nämlich, ist das Problem beim Zeichnen zu suchen.

    @Die, wo es nicht funzte
    Wie ist das denn? Das Ding bleibt irgendwo stehen. OK. Und wenn man dann oben links in die Ecke klickt, kann man dann das Bitmap von da aus wieder zeiehen (so dass 2 Bmps zu sehen sind)? Oder wie ist das?

    Vielleicht liegt es ja auch am System. Hab es jetzt auf 3 Rechnern ausprobiert (2xWin98 und 1xWinME). Hat überall geklappt. Möglicherweise liegts wieder an diesem besch.... XP.



  • funtzt (win98, amd xp1600+)
    mit xp hab ich aber auch schlechte erfahren gemacht.
    einige meiner programme funtzen da auch nicht richtig.

    [ Dieser Beitrag wurde am 02.08.2002 um 18:57 Uhr von Tendor editiert. ]



  • Jo, ich hau mir das heute abend mal auf meine 2. Festplatte. Muss es mir aber erst von nem Freund besorgen. Oh, das durfte ich ja eigentlich garnicht schreiben. 🙄 😃 Dann kann ich ja mal schauen, ob es da geht, und wenn nicht, wie ich das Problem abstellen kann.

    <edit> Hab bei dEUs nochmal angefragt. Der hat Win2k. </edit>

    [ Dieser Beitrag wurde am 02.08.2002 um 19:01 Uhr von WebFritzi editiert. ]



  • Die neue Version mit der Statuszeile + MessageBox funktioniert jetzt auf einmal richtig 😕



  • Danke, dass du's ausprobiert hast, Netter Troll. Du bist wirklich nett. 🙂 Aber das ist schon komisch, oder? Ich habe nichts geändert am Code. Kennst du dich mit Timern aus, und was für einen man nehmen sollte für sowas? Ich hab das jetzt nochmal mit GetTickCount() ausprobiert (siehe WinAPI-Forum - Thema: Neuer Timer). Geht genauso gut. Aber leider hab ich da auch keinen Vergleich, wie's auf anderen Rechnern läuft.

    [ Dieser Beitrag wurde am 03.08.2002 um 03:47 Uhr von WebFritzi editiert. ]



  • Ich weiß nicht ob's Dir was hilft, aber bei mir läufts, alles 🙂

    Athlon 1000, Win2k Advanced Server



  • Ein Danke auch an dich, 0x1. 🙂



  • Thunderbird 1Ghz, WinMe, 256 Ram läuft einwandfrei auf allen Stufen

    Tippo


Anmelden zum Antworten