|
|

楼主 |
发表于 2006-1-26 13:49:00
|
显示全部楼层
Re: [求助]关于SetColorKey
我把代码的关键地方贴出来:
简单说明一下,第一个是HRESULT InitDirectDraw( HWND hWnd ),主要是用来创建CDisplay对象还有CSurface表面,然后设置ColorKey....第二个是DisplayFrame()函数,用来将表面Blt和Flip,由于用了SDK里的类,Flip操作用present()就行了...
HRESULT InitDirectDraw( HWND hWnd )
{
HRESULT hr;
LPDIRECTDRAWPALETTE pDDPal = NULL; //定义程序中的调色板
LPDIRECTDRAWSURFACE pDDSurface = NULL;
// Release all existing surfaces
//模式要切换,现有的表面都要释放,然后创建新的表面
SAFE_DELETE( g_pTextSurface );
SAFE_DELETE( g_pBackSurface );
SAFE_DELETE( g_pChraSurface );
SAFE_DELETE( g_pDisplay );
// The back buffer and primary surfaces need to be created differently
// depending on if we are in full-screen or windowed mode
g_pDisplay = new CDisplay();
if( FAILED( hr = g_pDisplay->CreateWindowedDisplay( hWnd, SCREEN_WIDTH, SCREEN_HEIGHT ) ) )
{
MessageBox( hWnd, TEXT("创建窗口模式失败,\n可能您的显卡不支持这个模式,\n程序即将退出"),
TEXT("DirectDraw Sample"), MB_ICONERROR | MB_OK );
return hr;
}
if( FAILED( hr = g_pDisplay->CreatePaletteFromBitmap( &pDDPal, "animate.bmp") ) )
return hr;
g_pDisplay->SetPalette( pDDPal );
SAFE_RELEASE( pDDPal );
// Create a surface, and draw a bitmap resource on it. The surface must
// be newly created every time the screen mode is switched since it
// uses the pixel format of the primary surface
if( FAILED( hr = g_pDisplay->CreateSurfaceFromBitmap( &g_pBackSurface, "BackGround256.bmp",
SCREEN_WIDTH,SCREEN_HEIGHT ) ) )
return hr;
//创建人物表面
if( FAILED( hr = g_pDisplay->CreateSurfaceFromBitmap( &g_pChraSurface, "Character256.bmp",
290, 784 ) ) )
if( FAILED( hr = g_pChraSurface->SetColorKey( RGB( 255, 0, 255) ) ) )
return hr;
if( FAILED( hr = g_pBackSurface->SetColorKey( RGB( 255, 255, 255) ) ) )
return hr;
if( FAILED( hr = g_pDisplay->CreateSurfaceFromText(&g_pTextSurface,NULL,HELPTEXT,
RGB(255,255,255),RGB(255, 0, 255) ) ) )
return hr;
if( FAILED( hr = g_pTextSurface->SetColorKey( RGB( 255, 255, 255) ) ) )
return hr;
if( FAILED( hr = g_pDisplay->CreateSurfaceFromBitmap(&g_pChraNextSurface, "animate.bmp",
200, 200 ) ) )
return hr;
if( FAILED( hr = g_pChraNextSurface->SetColorKey( 0 ) ) )
return hr;
return S_OK;
}
HRESULT DisplayFrame()
{
HRESULT hr;
// Fill the back buffer with black, ignoring errors until the flip
g_pDisplay->Clear( 0 );//清空后备缓冲区表面,即用黑色填满
// Blt the help text on the backbuffer, ignoring errors until the flip
//将文本信息拷贝到后备缓存区,坐标是10,10
g_pDisplay->Blt( 10, 10, g_pTextSurface, NULL );
//从BackSurface读取rc大小拷贝到后备缓存区中...
//这样就可以实现动画了,哈哈...
g_pDisplay->Blt( 0, 0 , g_pBackSurface, NULL );
RECT rc;
rc.top = g_Char.direc * CHAR_HEIGHT;
rc.left = g_xChar * CHAR_WIDTH;
rc.right = (g_xChar + 1) * CHAR_WIDTH;
rc.bottom = (g_Char.direc + 1) * CHAR_HEIGHT;
g_pDisplay->Blt( g_Char.xPos, g_Char.yPos, g_pChraSurface, &rc);
g_pDisplay->Blt( 200, 200, g_pChraNextSurface, NULL );
// We are in fullscreen mode, so perform a flip and return
// any errors like DDERR_SURFACELOST
//最关键的地方在这里,请看下面的语句,只要我们一执行翻页操作,就可以将改动了的图像了显示在屏幕上了
if( FAILED( hr = g_pDisplay-> resent() /*翻页操作*/) )
return hr;
return S_OK;
}
下面这个是DirectInput里的读取键盘操作
for( i = 0; i < 256; i++ )
{
if( diks & 0x80 ) //记录此键的状态,低字节最高位是 1 表示按下,0 表示松开,一般用 diks&0x80 来测试
{
switch(i)
{
//我们可以通过测试计数器i,来判断是哪个键被按下了。
//我们提供几个数据 UP:200 down:208 left:203 right:205 enter:28 space:57
//其实你可以用DirectX中的Samples\C++\DirectInput\Bin\Keyboard.exe程序来测试,只不过那是用
//16进制显示的。
case 0xc8: //上键
{
//g_Char.direc = 4;
g_Char.yVel = -1;
if(g_Char.yPos >= 10 )
g_Char.yPos -= 10;
else
g_Char.yPos = 0;
UpdateFrame();
}
break;
case 0xd0: //下键
{
//g_Char.direc = 0;
g_Char.yVel = 1;
if(g_Char.yPos <= (SCREEN_HEIGHT - CHAR_HEIGHT - 10 ) )
g_Char.yPos += 10;
else
g_Char.yPos = (SCREEN_HEIGHT - CHAR_HEIGHT);
UpdateFrame();
}
break;
case 0xcb://左键
{
//g_Char.direc = 2;
g_Char.xVel =-1;
if(g_Char.xPos >= 10 )
g_Char.xPos -= 10;
else
g_Char.xPos = 0;
UpdateFrame();
}
break;
case 0xcd://右键
{
//g_Char.direc = 6;
g_Char.xVel = 1;
if(g_Char.xPos <= (SCREEN_WIDTH - CHAR_WIDTH - 10 ) )
g_Char.xPos += 10;
else
g_Char.xPos = (SCREEN_WIDTH - CHAR_WIDTH);
UpdateFrame();
}
break;
case 0x01://ESC键
{
PostQuitMessage( 0 );
}
break;
default:
break;
}
}
这个函数用来对RECT的范围进行操作
void UpdateFrame( )
{
g_xChar++;
if( g_xChar == 5 )
g_xChar = 1;
if( g_Char.xVel == 1 && g_Char.yVel == 1)
g_Char.direc = 7;
if( g_Char.xVel == -1 && g_Char.yVel == -1)
g_Char.direc = 3;
if( g_Char.xVel == 1 && g_Char.yVel == -1)
g_Char.direc = 5;
if( g_Char.xVel == -1 && g_Char.yVel == 1)
g_Char.direc = 1;
if( g_Char.xVel == 1 && g_Char.yVel == 0)
g_Char.direc = 6;
if( g_Char.xVel == 0 && g_Char.yVel == 1)
g_Char.direc = 0;
if( g_Char.xVel == -1 && g_Char.yVel == 0)
g_Char.direc = 2;
if( g_Char.xVel == 0 && g_Char.yVel == -1)
g_Char.direc = 4;
DisplayFrame();
}
|
|