FullScreenMode下纵卷轴背景图象(转)

FullScreenMode下纵卷轴背景图象(转)[@more@]

  
  2004.12.26.10.19.46.1.gif

  将与画面同样大小的图象上下分割,使用计时器纵向卷轴。

  这是在 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 下。)

  
  2004.12.26.10.19.57.2.gif

  这样的图片上下连续拼接在一起,接合处不会有不自然的感觉:

  
2004.12.26.10.20.7.3.gif

  这样的图片通常在网页中用来铺背景,即所谓的"无缝贴图"。

  2. 因为画面的大小是 640*480 ,所以把上面的图片扩展到这个大小,储存在 BmpSurface :

  if (FAILED(hr= g_pDisplay->CreateSurfaceFromBitmap(&g_pBmpSurface,

  "G:DirectX 8Flowers.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 8Flowers.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

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-952199/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8225414/viewspace-952199/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值