会员: 密码:  免费注册 | 忘记密码 | 会员登录 网页功能: 加入收藏 设为首页 网站搜索  
游戏开发 > 程序设计 > 2D图形
从桌面切换到游戏
发表日期:2006-08-20 22:13:27作者: 出处:  


从游戏切换到桌面只要按一下ALT+TAB,hehe,老板就不知道你在玩游戏了(不包括某些特臭的游戏或特聪明的老板)。那么从桌面切换到游戏呢?就是等老板走开以后,再按一下ALT+TAB,这样就完成了本文的内容 :-)。好了,不开玩笑了,下面言归正传。

一般情况下DirectX程序运行后就开始显示程序中的正式内容。能否做一个效果,让桌面和平演变到你所想显示的内容呢?

可以做到,原理也非常简单,第一步就是在DirectDraw初始化以前将屏幕内容先保存下来,然后就任你处置了。再下一步总应该是一样的,尽可能按桌面原样画出来,给人一个桌面还没有清掉的映象。接着呢?可以发挥你的想象力 + 实现力了,理论上可以做任何你想做的事,什么淡入淡出,燃烧,Alpha,像玻璃一样碎开等等以及其它更多更复杂的效果,这方面还可以参看刘小军的一组文章。

本文的目标就是介绍如何实现第一步。好,闲话少说,请看代码片断:

bool CDesktop2DXApp::GetDXInitSettings(void)
{
    ...
    CDC dc;
    dc.Attach(::GetDC(NULL));
    if (m_pDirectDraw->GetFirstEnableDevice()->SelectDisplayMode( IsFullScreen(),
                                    dc.GetDeviceCaps(HORZRES),
                                    dc.GetDeviceCaps(VERTRES),
                                    dc.GetDeviceCaps(BITSPIXEL)/*8*/) == false)
        return  false;

    m_dc.CreateCompatibleDC(&dc);

    m_bmp.CreateCompatibleBitmap(&dc, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES));

    // Select the bitmaps into the compatible DC.
    m_pOldBMP = m_dc.SelectObject(&m_bmp);

    BOOL bRet = m_dc.BitBlt(0, 0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES), &dc, 0, 0, SRCCOPY);
    ::ReleaseDC(NULL, dc.Detach());
    dc.DeleteDC();

    if (bRet == FALSE)
        return  false;

    return true;
}

上一段代码的意思就是赶在DirectDraw初始化之前取得桌面DC,并由此得到桌面的宽、高、颜色位数,并创建一个一样的DirectDraw环境(代码略作修改也可以不一样)。然后用DC的BitBlt保存桌面位图。接下来:


bool CDesktop2DXApp::InitDXObjects(void)
{
    m_pDDDevice = GetFirstDDDevice();
    m_pRenderSurface = m_pDDDevice->GetRenderSurface();
    // add your init code here !
    for (int  i = 0; i < 4; ++ i)
    {
        m_apSurface[i] = new  CDDSurface;

        if (m_apSurface[i]->Create(m_pDDDevice, m_pDDDevice->GetWidth() / 2, m_pDDDevice->GetHeight() / 2) == false)
            return  false;
    }

    CDC dc;
    for (i = 0; i < 4; ++ i)
    {
        m_arcDest[i].left = (i & 1) ? m_pDDDevice->GetWidth() / 2 : 0;
        m_arcDest[i].top = (i >> 1) ? m_pDDDevice->GetHeight() / 2 : 0;
        m_arcDest[i].right = m_arcDest[i].left + m_pDDDevice->GetWidth() / 2;
        m_arcDest[i].bottom = m_arcDest[i].top + m_pDDDevice->GetHeight() / 2;

        if (SUCCEEDED(m_apSurface[i]->GetDC(dc)))
        {
            dc.BitBlt(0, 0, m_apSurface[i]->GetWidth(), m_apSurface[i]->GetHeight(), &m_dc, m_arcDest[i].left, m_arcDest[i].top, SRCCOPY);

            m_apSurface[i]->ReleaseDC(dc);
        }
    }
    dc.DeleteDC();

    return  true;
}

以上代码创建了四个DirectDrawSurface(根据你的需要也可以只创建一个),然后将保存下来的位图分四块拷入各自对应的Surface留做下一步用。

为了代码简洁起见(实际是我不会用复杂的方法 ^_^ ),我在演示代码中只用了Blt来缩放,使程序运行后看起来象是屏幕分成四块向四角缩去。

好这样本文的内容就算完成了。

运行:缺省是窗口方式:Desktop2DX ,全屏下:Desktop2DX /f。

注:本文最初思想来自DirectXDev上的一组讨论:“Subject: Windows ----> Game Translation”。

另外用DC时特别要注意的是要释放干净,不要产生Resource Leak。

返回顶部】 【打印本页】 【关闭窗口

关于我们 / 给我留言 / 版权举报 / 意见建议 / 网站编程QQ群   
Copyright ©2003- 2024 Lihuasoft.net webmaster(at)lihuasoft.net 加载时间 0.00252