main.cpp
来自「VC游戏编程基础」· C++ 代码 · 共 1,966 行 · 第 1/4 页
CPP
1,966 行
}
return hr;
}
// Display the sprites on the screen
if( FAILED( hr = DisplayFrame() ) )
{
if( hr != DDERR_SURFACELOST )
return hr;
// The surfaces were lost so restore them
RestoreSurfaces();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DisplayFrame()
// Desc: Blts a the sprites to the back buffer, then it blts or flips the
// back buffer onto the primary buffer.
//-----------------------------------------------------------------------------
HRESULT DisplayFrame()
{
HRESULT hr;
if( Input() )
Input()->UpdateDevices();
// Fill the back buffer with black, ignoring errors until the flip
g_pDisplay->Clear( 0 );
switch (g_nGameState)
{
case GAMESTATE_SPLASHSCREEN:
{
if (g_pSplashSound == NULL) {
g_pSoundManager->Create( &g_pSplashSound, "WavSplashScreen", 0, GUID_NULL );
}
if (g_pSplashSound->IsSoundPlaying() == false) {
g_pSplashSound->Play(0,DSBPLAY_LOOPING);
LoadJPEG(true, SPLASHFILENAME, &g_pSplashSurface);
}
g_pDisplay->Blt(0,0, g_pSplashSurface, NULL);
break;
}
case GAMESTATE_CHOICE:
{
g_pDisplay->Blt(0,0, g_pSplashSurface, NULL);
break;
}
case GAMESTATE_RUNNING:
{
LPDIRECTDRAWSURFACE7 lpdds = g_pDisplay->GetBackBuffer();
if (g_nPooDelay)
--g_nPooDelay;
else {
g_pPooSprite->SetState(ST_DEAD);
}
g_pDisplay->Blt( 0, 0, g_pMazeSurface, NULL );
// Blt the help text on the backbuffer, ignoring errors until the flip
#ifdef DISPLAY_STATUS
g_pDisplay->Blt( 10, 10, g_pTextSurface, NULL );
#endif
g_pDisplay->Blt( 10, 710, g_pLifeTextSurface, NULL );
g_pDisplay->Blt( SCREEN_WIDTH - g_pScoreTextSurface->GetSurfaceDesc().dwWidth - 10, 710, g_pScoreTextSurface, NULL );
g_pDisplay->Blt( SCREEN_WIDTH/2 - g_pLevelTextSurface->GetSurfaceDesc().dwWidth/2, 710, g_pLevelTextSurface, NULL );
g_pPooSprite->Update();
g_pPlayerSprite->Update();
g_SpecialSprite.Update();
g_EnemySpriteManager.Update();
g_BulletSprite.Update();
g_EnemySpriteManager.KillSpritesColliWith(g_pPooSprite);
if (g_pPlayerSprite->m_Movement.m_nInvulnerable == 0) {
if (g_EnemySpriteManager.IsHit(g_pPlayerSprite->GetRect()) || g_BulletSprite.IsHit(g_pPlayerSprite->GetRect())) {
g_pPlayerSprite->SetState(ST_KILL);
g_BulletSprite.SetState(ST_KILL);
g_pPlayerSprite->m_Movement.m_dx = g_pPlayerSprite->m_Movement.m_dy =0;
}
}
if (g_SpecialSprite.IsHit(g_pPlayerSprite->GetRect()) && g_SpecialSprite.GetState()!=ST_KILL) {
g_pPickupSound->Play(0,0);
g_SpecialSprite.SetState(ST_KILL);
}
g_pPooSprite->Draw(lpdds);
g_SpecialSprite.Draw(lpdds);
g_pPlayerSprite->Draw(lpdds);
g_BulletSprite.Draw(lpdds);
g_EnemySpriteManager.Draw(lpdds);
break;
}
case GAMESTATE_GAMEOVERGOOD:
case GAMESTATE_GAMEOVERBAD:
{
g_pDisplay->Blt(0,0, g_pSplashSurface, NULL);
}
}
// Flip or blt the back buffer onto the primary buffer
if( FAILED( hr = g_pDisplay->Present() ) )
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreSurfaces()
// Desc: Restore all the surfaces, and redraw the sprite surfaces.
//-----------------------------------------------------------------------------
HRESULT RestoreSurfaces()
{
HRESULT hr;
LPDIRECTDRAWPALETTE pDDPal = NULL;
if( FAILED( hr = g_pDisplay->GetDirectDraw()->RestoreAllSurfaces() ) )
return hr;
// No need to re-create the surface, just re-draw it.
#ifdef DISPLAY_STATUS
if( FAILED( hr = g_pTextSurface->DrawText( NULL, (char*)g_szGameStatus,
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
#endif
if( FAILED( hr = g_pLifeTextSurface->DrawText( NULL, (char*)g_szLifeLeft,
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
if( FAILED( hr = g_pScoreTextSurface->DrawText( NULL, (char*)g_szScore,
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
if( FAILED( hr = g_pLevelTextSurface->DrawText( NULL, g_Maze.GetName(),
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
g_Maze.Draw(g_pMazeSurface);
if( FAILED( hr = g_pSpriteSurface->DrawBitmap( "Sprite.bmp"/*MAKEINTRESOURCE( IDB_SPRITE )*/,
0, 0 ) ) )
return hr;
if (g_nGameState == GAMESTATE_SPLASHSCREEN) {
LoadJPEG(true, SPLASHFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_CHOICE) {
LoadJPEG(true, CHOICEFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_GAMEOVERGOOD) {
LoadJPEG(true, GAMEOVERGOODFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_GAMEOVERBAD) {
LoadJPEG(true, GAMEOVERBADFILENAME, &g_pSplashSurface);
}
return S_OK;
}
//16Bit Color conversion macros
#define RGB555(r, g, b) ((r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10))
#define RGB565(r, g, b) ((r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11))
//16Bit Color Formats
#define PF_555 1
#define PF_565 2
//Color modes
#define C16BIT 16
#define C24BIT 24
#define C32BIT 32
//*************
//* Load JPEG *
//*************
bool LoadJPEG(bool bFromFile, LPCTSTR szName, CSurface** ppSurface)
{
//Error handle
IJLERR jerr;
int nPixelFormat = PF_555;
//Create the JPEG object
JPEG_CORE_PROPERTIES jcprops;
DDPIXELFORMAT DDPixelFormat;
ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));
DDPixelFormat.dwSize = sizeof(DDPixelFormat);
HRESULT Result = g_pDisplay->GetBackBuffer()->GetPixelFormat(&DDPixelFormat);
if(Result != DD_OK)
{
MessageBox(g_hMainWnd, "Failed to retrieve pixel format", TITLE, MB_OK);
return false;
}
//Get green bitmask and set pixel format
if((DDPixelFormat.dwGBitMask / 32) == 31)
nPixelFormat = PF_555;
else if((DDPixelFormat.dwGBitMask / 32) == 63)
nPixelFormat = PF_565;
//Initialize the JPEG object
jerr = ijlInit(&jcprops);
if (jerr != IJL_OK)
{
MessageBox(g_hMainWnd, "IJLInit problem", TITLE, MB_OK);
return false;
}
//Load from File or Resource?
if (bFromFile)
{
//Set the IJL data source as a filename
jcprops.JPGFile = szName;
//Read JPEG parameters from the file
jerr = ijlRead(&jcprops, IJL_JFILE_READPARAMS);
}
else //(Location == FROM_RESOURCE) or integer ID of resource
{
//Resource variables
BYTE* pmem;
HGLOBAL hmem;
DWORD size;
HRSRC hres;
hres = FindResource(NULL, szName, "JPEG");
if (hres)
{
size = SizeofResource(NULL, hres);
if (!size)
{
MessageBox(g_hMainWnd, "Error retrieving resource size",
TITLE, MB_OK);
return false;
}
hmem = LoadResource(NULL, hres);
if (hmem == NULL)
{
MessageBox(g_hMainWnd, "Error loading resource", TITLE, MB_OK);
return false;
}
pmem = (BYTE *)LockResource(hmem);
if (pmem == NULL)
{
MessageBox(g_hMainWnd, "Error locking resource", TITLE, MB_OK);
return false;
}
}
else
{
MessageBox(g_hMainWnd, "JPEG resource not found", TITLE, MB_OK);
return false;
}
//Set the IJL data source as the resource buffer
jcprops.JPGFile = NULL;
jcprops.JPGBytes = pmem;
jcprops.JPGSizeBytes = size;
//Read JPEG parameters from the buffer
jerr = ijlRead(&jcprops, IJL_JBUFF_READPARAMS);
}
//Make sure Parameter read was successful
if (jerr != IJL_OK)
{
MessageBox(g_hMainWnd, "Error reading JPEG parameters", TITLE, MB_OK);
return false;
}
//Prepare a 24Bit buffer to receive image data
BYTE *buffer24;
//Determine the required size
long szbuff24 = (jcprops.JPGWidth * C24BIT + 7) / 8
* jcprops.JPGHeight;
//Resize the buffer
buffer24 = new BYTE [szbuff24];
if (buffer24 == NULL)
{
MessageBox(g_hMainWnd, "Memory Allocation Error", TITLE, MB_OK);
return false;
}
//Set up the DIB specification for the JPEG decoder
jcprops.DIBWidth = jcprops.JPGWidth;
jcprops.DIBHeight = jcprops.JPGHeight; //Implies a bottom-up DIB.
jcprops.DIBChannels = 3;
jcprops.DIBColor = IJL_BGR;
jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES(jcprops.JPGWidth,3);
jcprops.DIBBytes = reinterpret_cast<BYTE*>(buffer24);
//Set the JPG color space ... this will always be somewhat of an
//educated guess at best because JPEG is "color blind" (i.e.,
//nothing in the bit stream tells you what color space the data was
//encoded from. However, in this example we assume that we are
//reading JFIF files which means that 3 channel images are in the
//YCbCr color space and 1 channel images are in the Y color space.
switch(jcprops.JPGChannels)
{
case 1: jcprops.JPGColor = IJL_G;
break;
case 3: jcprops.JPGColor = IJL_YCBCR;
break;
default:
//This catches everything else, but no color twist will be
//performed by the IJL.
jcprops.DIBColor = (IJL_COLOR)IJL_OTHER;
jcprops.JPGColor = (IJL_COLOR)IJL_OTHER;
break;
}
//Read JPEG image data into our 24bit buffer
if (bFromFile)
jerr = ijlRead(&jcprops, IJL_JFILE_READWHOLEIMAGE);
else
jerr = ijlRead(&jcprops, IJL_JBUFF_READWHOLEIMAGE);
//Make sure the read was successful
if (jerr != IJL_OK)
{
MessageBox(g_hMainWnd, "Error reading JPEG image", TITLE, MB_OK);
return false;
}
HBITMAP hbm;
//Convert to current CLRMODE
if (DDPixelFormat.dwRGBBitCount == C16BIT)
{
//Create a 16bit buffer
WORD *buffer16;
long szbuff16;
//determine the size of our buffer
szbuff16 = ((jcprops.JPGWidth * C16BIT + 7) / 8)
* jcprops.JPGHeight;
//resize the buffer and make sure resize works
buffer16 = new WORD [szbuff16];
if (buffer16 == NULL)
{
MessageBox(g_hMainWnd, "Error creating 16Bit buffer", TITLE, MB_OK);
return false;
}
//Start at the beginning of the buffer
long j = 0;
//Step through the 24bit buffer
//Retrieve 3 channels at a time and convert their values to 16bit
for (long i = 0; i < szbuff24; i += 3)
{
//Check the pixel format and write the color data
//to the 16bit buffer. After the write, advance the
//16bit buffer by one.
if (nPixelFormat == PF_555)
buffer16[j++] = RGB555(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
else
buffer16[j++] = RGB565(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
}
//Create the bitmap using the new 16bit buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C16BIT, buffer16);
if(hbm == NULL)
{
MessageBox(g_hMainWnd, "Failed to create 16Bit Bitmap", TITLE, MB_OK);
return false;
}
//remove the new buffer
delete buffer16;
}
else if (DDPixelFormat.dwRGBBitCount == C24BIT)
{
//The data we have from the JPEG is already 24bit
//Just create the new bitmap from our buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C24BIT, buffer24);
if(hbm == NULL)
{
MessageBox(g_hMainWnd, "Failed to create 24Bit Bitmap", TITLE, MB_OK);
return false;
}
}
else if (DDPixelFormat.dwRGBBitCount == C32BIT)
{
//Create a 32bit buffer
BYTE *buffer32;
long szbuff32;
//determine the size of our buffer
szbuff32 = ((jcprops.JPGWidth * C32BIT + 7) / 8)
* jcprops.JPGHeight;
//resize the buffer and make sure resize works
buffer32 = new BYTE [szbuff32];
if (buffer32 == NULL)
{
MessageBox(g_hMainWnd, "Error creating 32Bit buffer", TITLE, MB_OK);
return false;
}
//Start at the beginning of the 24bit buffer
long j = 0;
//Step through the 32bit buffer, copying the 3 Channels from
//the 24bit buffer. However, at the end of each channel, we
//have to write an extra byte for the 32bit image's alpha
//channel
for (long i = 0; i < szbuff32; i += 4)
{
buffer32[i + 0] = buffer24[j++]; //Blue channel
buffer32[i + 1] = buffer24[j++]; //Green channel
buffer32[i + 2] = buffer24[j++]; //Red channel
buffer32[i + 3] = (BYTE)0x00; //Alpha channel
}
//Create the bitmap using the new 32bit buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C32BIT, buffer32);
if(hbm == NULL)
{
MessageBox(g_hMainWnd, "Failed to create 32Bit Bitmap",
TITLE, MB_OK);
return false;
}
//remove the 32bit buffer
delete buffer32;
}
else
{
MessageBox(g_hMainWnd,
"Palettized modes not supported. Use a 16, 24, or 32 Bit display.",
TITLE, MB_OK);
return false;
}
//remove the old buffer
delete buffer24;
//If DirectDraw Surface is NULL, create it
if (*ppSurface == NULL)
{
//Create the surface from our surface description
Result = g_pDisplay->CreateSurface(ppSurface,jcprops.JPGWidth,jcprops.JPGHeight );
if(Result != DD_OK)
{
MessageBox(g_hMainWnd, "Could not create surface", TITLE, MB_OK);
return false;
}
}
//Copy bitmap data to DirectDraw Surface
(*ppSurface)->DrawBitmap(hbm, 0, 0, 0, 0);
// clean up and destroy the JPEG Decompressor
ijlFree(&jcprops);
DeleteObject(hbm);
return true;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?