 将与画面同样大小的图象上下分割,使用计时器纵向卷轴。 这是在 Full Screen Mode(全屏模式) 下应用 mydx8.lib 的一个例子。 以前程序的开头必须要记述的 #define 语句,现在已经在 mydx8.h 中定义好了,所以从程序中把它去掉,别的就没有什么变化了。 使用私有库,如果编译的时候出现如下的错误信息,不必理会。(你再编译一遍,错误信息就没有了。) LINK : warning LNK4098: defaultlib "LIBC" conflicts with use of other libs; use /NODEFAULTLIB:library 这个程序基本上跟 §13. 背景卷轴 差不多,重写一遍没意思,这回我们把 640*480 的图象上下分割来卷轴。 这个程序的卷轴方法: 1. 准备一张图片,要求它的上端和下端能够自然地拼接。 (下面是我用的图片, 320*240 ,命名为 Flowers.bmp ,放在 G:\DirectX 8\ 下。)  这样的图片上下连续拼接在一起,接合处不会有不自然的感觉:  这样的图片通常在网页中用来铺背景,即所谓的"无缝贴图"。 2. 因为画面的大小是 640*480 ,所以把上面的图片扩展到这个大小,储存在 BmpSurface : if (FAILED(hr= g_pDisplay->CreateSurfaceFromBitmap(&g_pBmpSurface, "G:\\DirectX 8\\Flowers.bmp",640,480))) return hr; 3. 启动计时器控制卷轴速度。 指定计时间隔 20 毫秒: #define ID_TIMER 32767 : SetTimer(hWnd,ID_TIMER,20,NULL); 4. 在计时器(WM_TIMER)中计数 g_cnt : int g_cnt = 0; : case WM_TIMER: g_cnt++; break; 5. 把背景图象上下分割、卷轴描绘。 清空 BackBuffer ,对 RECT 结构体设定左右坐标。 因为画面大小是 640*480 ,设定如下: RECT rt; int dt; g_pDisplay->Clear(0); rt.left= 0; rt.right= 640; 上部分的描绘。 上部分描绘图片的纵坐标从 dt 到底部(rt.bottom= 480)之间的部分,dt 的值在 0~479 之间循环, dt 越大,描绘的上部分的高度就越小: dt= g_cnt%480; rt.top= dt; rt.bottom= 480; g_pDisplay->Blt(0,0,g_pBmpSurface,&rt); 下部分的描绘。 下部分描绘图片的纵坐标从顶部(rt.top= 0)到 dt 之间的部分,dt 越大,描绘的下部分的高度也越大: rt.top= 0; rt.bottom= dt; g_pDisplay->Blt(0,480-dt,g_pBmpSurface,&rt); 6. 上部分的描绘范围慢慢变窄、下部分的描绘范围慢慢变高,就这样循环下去。 如果你准备的背景图片不合适,上端和下端不能自然地衔接,卷轴的时候就不好看, 7. 退出程序时关闭计时器: case WM_DESTROY: KillTimer(hWnd, ID_TIMER); 创建窗口的代码。 640*480 是窗口的初始大小,但在全屏模式下这个数值没有意义,我们还用 CreateFullScreenDisplay() 来设定画面大小: HWND hWnd = CreateWindow(NAME,NAME,WS_OVERLAPPEDWINDOW,0,0,640,480, GetDesktopWindow(),NULL,wc.hInstance,NULL); if (hWnd==NULL) return FALSE; 决定全屏模式下画面大小(画面的解析度)的代码。 640,480,16 三个值分别表示画面的宽度、高度和颜色模式。 只能指定为你的显示器支持的显示模式。 g_pDisplay = new CDisplay(); if (FAILED(hr= g_pDisplay->CreateFullScreenDisplay(hWnd, 640, 480, 16))) { ERMSG("This display card does not support 640x480x16."); return hr; } 下面说明工程的创建方法。 首先请确认你的 mydx8.lib 和 mydx8.h 已经安放在 \Mssdk\ 下的指定位置。 私有库的引入进一步简化了工程的创建。 1. 新建一个 Win32 Application 空白工程,命名为 "VScrool"。 2. 准备合适的图象文件(我是在 G:\DirectX 8\ 下放了张 "Flowers.bmp" ,参见本章开头)。 3. 向工程中新建一个 C++ Source File ,命名为 "vscrool" ,向其中键入篇末附带的源程序。 4. 选择菜单 [Project|工程]-[Settings...|设定...] 打开[Project Settings|工程设定] 面板,点击 [Link|链接] 标签,向 [Object/library modules|对象、库模块] 栏内添加下面4个库文件: mydx8.lib dxguid.lib ddraw.lib dxerr8.lib 5. 编译并执行! 源程序: /****************************************************************************/ /*★ Full Screen Mode(全屏模式) 下纵卷轴背景图象 2001-01-21 前田 稔 ★*/ /****************************************************************************/ #define NAME "Scrool" #define STRICT #include // Defines, constants, and global variables CDisplay* g_pDisplay = NULL; CSurface* g_pBmpSurface = NULL; BOOL g_bActive = FALSE; int g_cnt= 0; // Function-prototypes LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HRESULT InitDraw(HWND hWnd); VOID FreeDirectDraw(); HRESULT DisplayFrame(); //★ Windows Main int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow) { MSG msg; WNDCLASS wc = { CS_CLASSDC,WndProc,0L,0L,hInst, NULL,NULL,NULL,NULL,NAME }; if (RegisterClass(&wc)==0) return FALSE; HWND hWnd = CreateWindow(NAME,NAME,WS_OVERLAPPEDWINDOW,0,0,640,480, GetDesktopWindow(),NULL,wc.hInstance,NULL); if (hWnd==NULL) return FALSE; if (FAILED(InitDraw(hWnd))) { if (g_pDisplay) g_pDisplay->GetDirectDraw()->SetCooperativeLevel(NULL, DDSCL_NORMAL); ERMSG("DirectDraw init failed. The sample will now exit."); return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); SetTimer(hWnd,0,20,NULL); while(TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (0 == GetMessage(&msg, NULL, 0, 0)) return (int)msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else { if (g_bActive) { if (FAILED(DisplayFrame())) { SAFE_DELETE(g_pDisplay); ERMSG("Displaying the next frame failed"); return FALSE; } } else WaitMessage(); } } } //★ WndProc() LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_KEYDOWN: PostMessage(hWnd, WM_CLOSE, 0, 0); return 0L; case WM_TIMER: g_cnt++; break; case WM_SIZE: if (SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam) g_bActive = FALSE; else g_bActive = TRUE; break; case WM_SETCURSOR: //隐藏光标 SetCursor(NULL); return TRUE; case WM_SYSCOMMAND: switch(wParam) { case SC_MOVE: case SC_SIZE: case SC_MAXIMIZE: case SC_MONITORPOWER: return TRUE; } break; case WM_DESTROY: KillTimer(hWnd, 0); FreeDirectDraw(); PostQuitMessage(0); return 0L; } return DefWindowProc(hWnd, msg, wParam, lParam); } //★ InitDraw() HRESULT InitDraw(HWND hWnd) { HRESULT hr; g_pDisplay = new CDisplay(); if (FAILED(hr= g_pDisplay->CreateFullScreenDisplay(hWnd, 640, 480, 16))) { ERMSG("This display card does not support 640x480x16."); return hr; } if (FAILED(hr= g_pDisplay->CreateSurfaceFromBitmap(&g_pBmpSurface, "G:\\DirectX 8\\Flowers.bmp",640,480))) return hr; return S_OK; } //★ DisplayFrame() HRESULT DisplayFrame() { HRESULT hr; RECT rt; int dt; g_pDisplay->Clear(0); rt.left= 0; rt.right= 640; dt= g_cnt%480; rt.top= dt; rt.bottom= 480; g_pDisplay->Blt(0,0,g_pBmpSurface,&rt); rt.top= 0; rt.bottom= dt; g_pDisplay->Blt(0,480-dt,g_pBmpSurface,
 【责编:admin】
|