我想做个扑克在移动中的动画,用的是双缓冲,但是牌一移动总是一抖一抖的,不平滑,哪位做过或是有源码,帮帮我,谢谢大家了

解决方案 »

  1.   

    貌似你的双缓冲没用好。GDI连动画都能实现。
      

  2.   


    void CTestDlg::Display(CRect* pRect, CDC* pDC , int nPos )
    {
    CDC MemDC,SpiritDC;
    CBitmap MemBitmap; SpiritDC.CreateCompatibleDC(pDC);
    MemDC.CreateCompatibleDC(pDC); MemBitmap.CreateCompatibleBitmap(pDC,pRect->Width(),pRect->Height());
    CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); SpiritDC.SelectObject(&m_SpiritBitmap);
    MemDC.BitBlt(0,0,m_nWidth,m_nHeight,&SpiritDC,0,0,SRCCOPY); pDC->BitBlt(nPos ,0,pRect->Width(),pRect->Height(),&MemDC,0,0,SRCCOPY);
    //绘图完成后的清理
    MemBitmap.DeleteObject();
    MemDC.DeleteDC();
    }void CTestDlg::OnTimer(UINT_PTR nIDEvent)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    //Invalidate();
    static int nPos = 0 ; m_nNum++;
    CString str;
    str.Format(_T("第 %d 次刷新"),m_nNum);
    this->SetWindowText(str); CDC* pDC = GetDC() ;
    Display(&m_cRect, pDC );
    CDialog::OnTimer(nIDEvent);
    }这是牌移动的代码
      

  3.   


    void CTestDlg::OnBtnTest()
    {
    // TODO: 在此添加控件通知处理程序代码
    SetTimer(1,50,NULL);
    }void CTestDlg::OnTimer(UINT_PTR nIDEvent)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    //Invalidate();
    static int nPos = -100 ; if(nPos>700)
    {
    nPos = 0 ;
    }
    nPos += 100 ;
    m_nNum++;
    CString str;
    str.Format(_T("第 %d 次刷新"),m_nNum);
    this->SetWindowText(str); CDC* pDC = GetDC() ;
    Display(&m_cRect, pDC ,nPos);
    CDialog::OnTimer(nIDEvent);
    }
    void CTestDlg::Display(CRect* pRect, CDC* pDC , int nPos )
    {
    CDC MemDC,SpiritDC;
    CBitmap MemBitmap; SpiritDC.CreateCompatibleDC(pDC);
    MemDC.CreateCompatibleDC(pDC); MemBitmap.CreateCompatibleBitmap(pDC,pRect->Width(),pRect->Height());
    CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
    SpiritDC.SelectObject(&m_SpiritBitmap);
    MemDC.BitBlt(nPos,0,m_nWidth,m_nHeight,&SpiritDC,0,0,SRCCOPY); pDC->BitBlt(0 ,0,pRect->Width(),pRect->Height(),&MemDC,0,0,SRCCOPY);
    //绘图完成后的清理
    MemBitmap.DeleteObject();
    MemDC.DeleteDC();
    }这个是最完整的,nPos是每次移动的步长
      

  4.   

    你是不是在什么地方调用Invalidate();或者其他函数刷新窗口了呀?如果是刷新了窗口那肯定闪,无论你是不是用双缓冲,因为你一旦刷新窗口时就会触发WM_ERASEBKGND消息,也就是调用OnEraseBkgnd()先去清除背景,所以就会学得闪,所以你得重载WM_ERASEBKGND消息,在里面直接添加一行代码,return true;这样就避免了清除背的操作,不会闪了。
      

  5.   

    没用Invalidate(),WM_ERASEBKGND消息添加了,里面直接return true 的 ,扑克移动时,一顿一顿的
      

  6.   

    SetTimer(1,50,NULL); // 1s/20祯是不是太慢了,实际上肯定没有20祯,因为还有操作时间。
    搞快点~~
    SetTimer(1,15,NULL); 
      

  7.   

    DX前缓冲区和后缓冲区就是双缓冲了.系统默认生成的.DDRAW才会分开有双缓冲.
      

  8.   

    Display完成后调用ValidateRect()立即更新试试
      

  9.   

    你用Paint里面e.Graphics  试下  在Paint事件里面绘制应该就不会了