一、单一背景滚动
单一背景滚动就是利用一张相当大的背景图,当游戏进行的时候,随着动画中人物或鼠标的移动,背景显示区域跟着移动。例如地图显示。
如上面这张图,由左上方到右下方,三个方框。代表显示在窗口中的背景区域,程序只要按照从左上到右下的顺序就可以连续显示3个方框区域,达到背景滚动的效果。其实这原理简单,这里就直接给出程序代码来看。
范例:
以键盘方向键(↑→↓←)控制背景滚动显示:
VS2008中新建Win32应用程序,命名后,选择默认的选项,点击完成。
定义全局变量:
HBITMAP map; HDC hmdc, mdc; HWND hWnd; DWORD tPre, tNow; int x = 0, y = 0;
这里声明x,y来表示获取DC的屏幕原点:
BitBlt(hdc,0, 0, 640, 480, mdc, x, y, SRCCOPY);
消息处理函数WndProc()函数中
case WM_KEYDOWN: // 响应各个方向键的操作 switch(wParam) { case VK_UP: y -= 20; if (y < 0) y = 0; break; case VK_DOWN: y += 20; if (y > 660) y = 660; break; case VK_LEFT: x -= 20; if (x < 0) x = 0; break; case VK_RIGHT: x += 20; if (x > 910) x = 910; break; } break;
运行后通过操作方向键可以控制查看地图的位置
详细代码可以下载:点击
二、循环背景动画
循环背景动画师不断的进行背景图的裁切与接合,然后显示在窗口上所产生的一种背景画面的循环滚动效果。下面来介绍这种动画效果的制作。
如上图,在背景图向右移动时,屏幕会出现“缝隙”,所以我们就是要把移出屏幕的图贴到缝隙中来。这样子循环后,就可以看到在空中飞行的效果了。
由上面的分析,我们的工作就是两次贴图。
第一步,裁取原始背景图右边部分尽心贴图操作到另一个DC中,假设目前裁取的右边部分的宽度为x,如图:
第二步,采取原始背景图左边部分惊醒贴图操作到另一DC中,完成了向右滚动接合后的新背景图。
第三步,将接合后的背景图显示在窗口中,之后递增x值,进行循环操作。当x大于等于背景图后,就将x的值重设为0,继续重复循环。这样子就形成了背景循环效果。
利用一张640*480的背景图,制作有左向右的循环滚动的动画
程序代码:
全局变量:
HBITMAP bg; HDC hmdc, mdc, buffdc; HWND hWnd; DWORD tPre, tNow; int x = 0;
用 x 来记录被裁取的右边部分的宽度,初始值为 0
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { // HWND hWnd; HBITMAP bmp; //用于建立兼容位图 hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } MoveWindow(hWnd, 10, 10, 640, 480, true); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hmdc = GetDC(hWnd); mdc = CreateCompatibleDC(hmdc); buffdc = CreateCompatibleDC(hmdc); //建立和窗口兼容的位图 bmp = CreateCompatibleBitmap(hmdc, 640, 480); SelectObject(mdc, bmp); bg = (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE); SelectObject(buffdc, bg); MyPaint(hmdc); return TRUE; }
void MyPaint(HDC hdc) { // 截取背景图右边的部分 BitBlt(mdc, 0, 0, x, 480, buffdc, 640-x, 0, SRCCOPY); // 截取背景图左边部分进行贴图 BitBlt(mdc, x, 0, 640-x, 480, buffdc, 0, 0, SRCCOPY); // 将结合后的背景图贴到窗口 BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY); tPre = GetTickCount(); // 获得持续时间 x += 10; if (x == 640) { x = 0; } }
每次调用MyPaint()函数都会进行图形切割合并,并显示在窗口上。
运行结果:
会看到图像在向右循环滚动,感觉就是自己在空中快速飞行一样。
本程序代码:点击