发信人: 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]