发信人: winson (阿苦), 信区: Programming 标 题: 一个DirectX的例子 发信站: BBS 水木清华站 (Wed Jan 14 16:49:07 1998) #include <windows.h> #include <ddraw.h> #include <dsound.h> IDirectDraw *dd; IDirectDrawSurface *dds0, *dds1, *dds2, *dds3; IDirectDrawClipper *ddc; IDirectSound *ds; IDirectSoundBuffer *dsb1, *dsb2; int x = 20, y = 20; int vx = 5, vy = 3; void MoveBall(HWND hwnd, BOOL bMove) { BOOL bBounce = FALSE; RECT rectSrc, rectDest; int ox, oy, nx, ny; GetClientRect(hwnd, &rectDest); ClientToScreen(hwnd, (POINT *)&rectDest.left); ClientToScreen(hwnd, (POINT *)&rectDest.right); if (bMove) { ox = rectDest.left + MulDiv(rectDest.right - rectDest.left - 32, x, 500); oy = rectDest.top + MulDiv(rectDest.bottom - rectDest.top - 32, y, 500); x += vx; y += vy; if (x < 0) { x = 0; vx = -vx; bBounce = TRUE; } if (x >= 500) { x = 1000 - x; vx = -vx; bBounce = TRUE; } if (y < 0) { y = -y; vy = -vy; bBounce = TRUE; } if (y >= 500) { y = 1000 - y; vy = -vy; bBounce = TRUE; } if (bBounce) { dsb1->SetCurrentPosition(0); dsb1->Play(0, 0, 0); } } nx = rectDest.left + MulDiv(rectDest.right - rectDest.left - 32, x, 500); ny = rectDest.top + MulDiv(rectDest.bottom - rectDest.top - 32, y, 500); rectSrc.left = rectSrc.top = 0; rectSrc.right = rectSrc.bottom = 32; if (bMove) { rectDest.left = rectDest.top = 0; rectDest.right = rectDest.bottom = 32; dds2->Blt(&rectDest, dds3, &rectSrc, DDBLT_WAIT, NULL); if (abs(nx - ox) < 32 && abs(ny - oy) < 32) { if (nx < ox) { rectSrc.left = ox - nx; rectSrc.right = 32; rectDest.left = 0; rectDest.right = 32 - rectSrc.left; } else { rectDest.left = nx - ox; rectDest.right = 32; rectSrc.left = 0; rectSrc.right = 32 - rectDest.left; } if (ny < oy) { rectSrc.top = oy - ny; rectSrc.bottom = 32; rectDest.top = 0; rectDest.bottom = 32 - rectSrc.top; } else { rectDest.top = ny - oy; rectDest.bottom = 32; rectSrc.top = 0; rectSrc.bottom = 32 - rectDest.top; } dds2->Blt(&rectDest, dds1, &rectSrc, DDBLT_WAIT, NULL); } rectSrc.left = rectSrc.top = 0; rectSrc.right = rectSrc.bottom = 32; rectDest.left = ox; rectDest.top = oy; rectDest.right = rectDest.left + 32; rectDest.bottom = rectDest.top + 32; dds0->Blt(&rectDest, dds2, &rectSrc, DDBLT_WAIT, NULL); } rectDest.left = nx; rectDest.top = ny; rectDest.right = rectDest.left + 32; rectDest.bottom = rectDest.top + 32; dds0->Blt(&rectDest, dds1, &rectSrc, DDBLT_WAIT, NULL); } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT paintStruct; switch(uMsg) { case WM_PAINT: hDC = BeginPaint(hwnd, &paintStruct); if (hDC != NULL) { MoveBall(hwnd, FALSE); EndPaint(hwnd, &paintStruct); } break; case WM_TIMER: MoveBall(hwnd, TRUE); break; case WM_KEYDOWN: switch (wParam) { case VK_LEFT: vx--; break; case VK_UP: vy--; break; case VK_RIGHT: vx++; break; case VK_DOWN: vy++; break; case VK_ESCAPE: PostMessage(hwnd, WM_CLOSE, 0, 0); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR d3, int nCmdShow) { MSG msg; HWND hwnd; WNDCLASS wndClass; DDSURFACEDESC ddsd; DSBUFFERDESC dsbd; HDC hddDC; RECT rect; HRSRC hrsrc; HGLOBAL hRData; DWORD *pRData; LPBYTE pMem1, pMem2; DWORD dwSize1, dwSize2; if (hPrevInstance == NULL) { memset(&wndClass, 0, sizeof(wndClass)); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.hInstance = hInstance; wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndClass.lpszClassName = "BOUNCE"; if (!RegisterClass(&wndClass)) return FALSE; } hwnd = CreateWindow("BOUNCE", "BOUNCE", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); DirectDrawCreate(NULL, &dd, NULL); dd->SetCooperativeLevel(hwnd, DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES); memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddsd.dwFlags = DDSD_CAPS; dd->CreateSurface(&ddsd, &dds0, NULL); dd->CreateClipper(0, &ddc, NULL); dds0->SetClipper(ddc); ddc->SetHWnd(0, hwnd); ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwHeight = 32; ddsd.dwWidth = 32; ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; dd->CreateSurface(&ddsd, &dds1, NULL); dd->CreateSurface(&ddsd, &dds2, NULL); dd->CreateSurface(&ddsd, &dds3, NULL); dds1->GetDC(&hddDC); SaveDC(hddDC); rect.left = rect.top = 0; rect.right = rect.bottom = 32; FillRect(hddDC, &rect, (HBRUSH)(COLOR_WINDOW + 1)); SelectObject(hddDC, GetStockObject(BLACK_BRUSH)); SelectObject(hddDC, GetStockObject(BLACK_PEN)); Ellipse(hddDC, 0, 0, 32, 32); RestoreDC(hddDC, -1); dds1->ReleaseDC(hddDC); dds3->GetDC(&hddDC); FillRect(hddDC, &rect, (HBRUSH)(COLOR_WINDOW + 1)); dds3->ReleaseDC(hddDC); DirectSoundCreate(NULL, &ds, NULL); ds->SetCooperativeLevel(hwnd, DSSCL_NORMAL); memset(&dsbd, 0, sizeof(DSBUFFERDESC)); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dw= (LPWAVEFORMATEX)(pRData + 5); ds->CreateSoundBuffer(&dsbd, &dsb1, NULL); dsb1->Lock(0, dsbd.dwBufferBytes, &pMem1, &dwSize1, &pMem2, &dwSize2, 0); memcpy(pMem1, (LPBYTE)(pRData + 11), dwSize1); if (dwSize2 != 0) memcpy(pMem2, (LPBYTE)(pRData + 11) + dwSize1, dwSize2); dsb1->Unlock(pMem1, dwSize1, pMem2, dwSize2); hrsrc = FindResource(hInstance, "HUM.WAV", "WAVE"); hRData = LoadResource(hInstance, hrsrc); pRData = (DWORD *)LockResource(hRData); dsbd.dwBufferBytes = *(pRData + 10); dsbd.lpwfxFormat = (LPWAVEFORMATEX)(pRData + 5); ds->CreateSoundBuffer(&dsbd, &dsb2, NULL); dsb2->Lock(0, dsbd.dwBufferBytes, &pMem1, &dwSize1, &pMem2, &dwSize2, 0); memcpy(pMem1, (LPBYTE)(pRData + 11), dwSize1); if (dwSize2 != 0) memcpy(pMem2, (LPBYTE)(pRData + 11) + dwSize1, dwSize2); dsb2->Unlock(pMem1, dwSize1, pMem2, dwSize2); dsb2->Play(0, 0, DSBPLAY_LOOPING); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); SetTimer(hwnd, 1, 100, NULL); while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); KillTimer(hwnd, 1); return msg.wParam; } -- ※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.128.111]