JJexplode 2021-06-02 23:32 采纳率: 100%
浏览 79
已采纳

win32图像移动后原来位置上的图像不会消失。

这是消息循环

MSG msg = { 0 };                //定义并初始化msg
    while (msg.message != WM_QUIT)        //使用while循环,如果消息不是WM_QUIT消息,就继续循环
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
        {
            TranslateMessage(&msg);        //将虚拟键消息转换为字符消息
            DispatchMessage(&msg);            //分发一个消息给窗口程序。
        }
        else
        {
            
            if (g_time - g_tPre >= 1)          //当此次循环运行与上次绘图时间相差0.001秒时再进行重绘操作
                Game_Paint(hwnd);
        }

    }

描画函数

VOID Game_Paint(HWND hwnd)
{
    g_Manager.GameScript();
    g_Manager.UpdateGame();
    g_Manager.ShowGame();
    
    
    BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_hdcBuffer, 0, 0, SRCCOPY);
}

游戏脚本

switch (m_ScriptMode)
    {
    case INIT:
        //玩家主控飞机
        heroPlane = new HeroPlane;
        heroPlane->SetImage(m_HeroImage);
        heroPlane->SetOffset(1, 1);
        heroPlane->SetImpactBox(10, 10);
        heroPlane->SetSpeed(1);
        heroPlane->SetLifeMax(7);
        heroPlane->SetBombMax(7);
        AddPlaneToVector(heroPlane);

        m_ScriptMode = STAGE_1;
        break;
    }

游戏更新

void GameManager::UpdateGame()
{

    for (int i = 0; i < (int)planes.size(); i++)
    {
        if (!planes[i])
        {
            continue;
        }
        planes[i]->UpdatePlane();

        if (planes[i]->GetState() == P_DISAPEEAR)
        {
            delete planes[i];
            planes[i] = NULL;
        }
    }
}

游戏显示

void GameManager::ShowGame()
{
    
    ShowBackground();
    for (int i = 0; i < (int)planes.size(); i++)
    {
        if (!planes[i])
        {
            continue;
        }
         planes[i]->ShowPlane();
         planes[i]->UpdatePlane();
    }

}

显示飞机

void HeroPlane::ShowPlane()
{
    switch (m_iState)
    {
    case P_EXPLODE:
        break;
    default :
        BITMAP bitmap;
        GetObject(m_hImage, sizeof(bitmap), &bitmap);
        HPEN oldPen = (HPEN)SelectObject(g_hdcMem, m_hImage);
        SetBkColor(g_hdcMem, RGB(32, 156, 0));                    //HERO.bmp のバックカラー 一時的

        int frameWidth = bitmap.bmWidth / 3;
        int frameHeight = bitmap.bmHeight;

        //マスクをつくる
        g_bmpMask = CreateBitmap(frameWidth, frameHeight, 1, 1, NULL);
        HPEN oldMaskPen = (HPEN)SelectObject(g_hdcMask, g_bmpMask);
        BitBlt(g_hdcMask, 0, 0, frameWidth, frameHeight, g_hdcMem, frameWidth * (1 + m_iDirection), 0, SRCCOPY);

        BitBlt(g_hdcBuffer, m_iX - m_iOffsetX, m_iY - m_iOffsetY, frameWidth, frameHeight, g_hdcMem, frameWidth * (1 + m_iDirection), 0, SRCINVERT);//AND
        BitBlt(g_hdcBuffer, m_iX - m_iOffsetX, m_iY - m_iOffsetY, frameWidth, frameHeight, g_hdcMask, 0, 0, SRCAND);//OR
        BitBlt(g_hdcBuffer, m_iX - m_iOffsetX, m_iY - m_iOffsetY, frameWidth, frameHeight, g_hdcMem, frameWidth * (1 + m_iDirection), 0, SRCINVERT);

        SelectObject(g_hdcMask, oldMaskPen);
        DeleteObject(g_bmpMask);             //デバイスコンテキストにあるマスクビットマップを削除する
        SelectObject(g_hdcMem, oldPen);
        break;
    }
}

UpDate就是一些人物操作代码就不贴了。

planes 是一个储存人物的一个向量。

每次绘制都会绘制一个新的图像,是消息循环过程中出现问题了吗?

  • 写回答

2条回答 默认 最新

  • qfl_sdu 2021-06-03 02:11
    关注

    你的pDC没有清空,之前画得肯定是在的啊,现在相当于你在桌子的面上用循环画了一排图片,但是你的桌子一直没擦,那之前的一定是有的。
    两种办法,一种是让内存DC即memDC同pDC一样大,然后移动图片在memDC的位置。
    另外一种每次重绘的时候先把pDC的擦除。
    具体参考:https://bbs.csdn.net/topics/390792751

    如有帮助,请采纳一下,谢谢

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?