📄 main.cpp
字号:
pt.x = 8*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD4, pt, 1, 100);
pt.x = 9*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD5, pt, 1, 100);
pt.x = 10*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD6, pt, 1, 100);
pt.x = 3*64;pt.y = 8*64;
g_SpecialSprite.AddState(ST_KEY, pt, 2, 50);
pt.x = 2*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_DOOR, pt, 3, 30);
pt.x = 3*64;pt.y = 7*64;
g_SpecialSprite.AddState(ST_KILL, pt, 2, 100);
g_SpecialSprite.m_nPoints = 200;
g_SpecialSprite.m_pfnDead = DeadSpecial;
g_SpecialSprite.m_pfnKill = KillSpecial;
// ----------子弹精灵------------ //
g_BulletSprite.CreateSprite(&g_pSpriteSurface, TYPE_BULLET, nHeight,nWidth);
rcBounding.top = rcBounding.left = 20;
rcBounding.right=rcBounding.bottom = nHeight - 40;
pt.x = 0*64;pt.y = 10*64;
g_BulletSprite.AddState(ST_DEFAULT, pt, 2, 30, &rcBounding);
pt.x = 11*64;pt.y = 10*64;
g_BulletSprite.AddState(ST_KILL, pt, 1, 10);
g_BulletSprite.m_Movement.m_pfnCollision = IsHit;
g_BulletSprite.m_Movement.m_nPathFindDelay = 5000;
g_BulletSprite.m_Movement.m_pfnFindPath=BulletFindPath;
g_BulletSprite.SetState(ST_KILL);
//显示精灵包络矩形
/*
g_Enemy1Sprite.EnableBorder(true);
g_Enemy2Sprite.EnableBorder(true);
g_Enemy3Sprite.EnableBorder(true);
g_PigSprite.EnableBorder(true);
g_RabbitSprite.EnableBorder(true);
g_SheepSprite.EnableBorder(true);
g_BulletSprite.EnableBorder(true);
*/
}
void InitLevel()
{
if (g_nCurrLevel+1 > g_nNoOfLevels) {
g_nGameState = GAMESTATE_GAMEOVERGOOD; //全部关卡用完,游戏结束
LoadJPEG(true, GAMEOVERGOODFILENAME, &g_pSplashSurface);
return;
}
int nNoOfEnemies = g_pLevel[g_nCurrLevel].nNoOfEnemys; //关卡敌人数目
g_Maze.LoadMaze(g_pLevel[g_nCurrLevel++].szLevelFile); //从关卡文件加载迷宫数据,然后g_nCurrLevel++
g_nNoOfEnemies = 10; //再生的敌人总数
SAFE_DELETE( g_pScoreTextSurface );
wsprintf((char*)g_szScore, (char*)GAMESCORE_TEXT, g_nScore); //更新得分
HFONT hFont = GetGameFont();
g_pDisplay->CreateSurfaceFromText( &g_pScoreTextSurface, hFont, (char*)g_szScore,
RGB(0,0,0), RGB(255, 255, 0) );
/*
OutputDebugString("\n-----------\n");
char szDebug[100];
wsprintf (szDebug,"g_nRows %d, g_nCols :%d Sizeof %d\n",g_nRows,g_nCols,sizeof(short[g_nCols][g_nRows]));
OutputDebugString(szDebug);
for (int i=0; i < g_nRows; i++) {
for(int j=0; j <g_nCols; j++) {
if (g_nPathArray[i][j] !=0)
szDebug[j]='1';
else
szDebug[j]='0';
}
szDebug[j]='\n';
szDebug[j+1]='\0';
OutputDebugString(szDebug);
}
OutputDebugString("-----------\n");
*/
g_nNoOfSpecials = NO_OF_SPECIALS;
//显示关卡名
SAFE_DELETE(g_pLevelTextSurface);
g_pDisplay->CreateSurfaceFromText( &g_pLevelTextSurface, hFont, g_Maze.GetName(),
RGB(0,0,0), RGB(255, 255, 0) ) ;
//显示PlayerSprite
POINT pt= { 0*64, 3*64 };
g_pPlayerSprite->MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);//移动到开始位置
g_pPlayerSprite->SetState(ST_WALK_UP, true);
g_pPlayerSprite->m_Movement.m_dx=0;
g_pPlayerSprite->m_Movement.m_dy=0;
g_pPlayerSprite->m_Movement.m_nInvulnerable=INVULNERABLE_DELAY; //不死延时
g_pPooSprite->SetState(ST_DEAD, true);
g_EnemySpriteManager.Destroy();
//创建敌人,最多五种
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy1Sprite.MoveTo(pt);
g_Enemy1Sprite.m_Movement.m_dx = -1;
g_Enemy1Sprite.m_Movement.m_nPathFindDelay = 1000;
g_Enemy1Sprite.SetState(ST_WALK_LEFT, true);
g_EnemySpriteManager.AddSprite(&g_Enemy1Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy2Sprite.MoveTo(pt);
g_Enemy2Sprite.m_Movement.m_dx = 1;
g_Enemy2Sprite.m_Movement.m_nPathFindDelay = 500;
g_Enemy2Sprite.SetState(ST_WALK_RIGHT, true);
g_EnemySpriteManager.AddSprite(&g_Enemy2Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy3Sprite.MoveTo(pt);
g_Enemy3Sprite.m_Movement.m_dy = 1;
g_Enemy3Sprite.m_Movement.m_nPathFindDelay = 300;
g_Enemy3Sprite.SetState(ST_WALK_DOWN, true);
g_EnemySpriteManager.AddSprite(&g_Enemy3Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy4Sprite.MoveTo(pt);
g_Enemy4Sprite.m_Movement.m_dy = -1;
g_Enemy4Sprite.m_Movement.m_nPathFindDelay = 200;
g_Enemy4Sprite.SetState(ST_WALK_UP, true);
g_EnemySpriteManager.AddSprite(&g_Enemy4Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy5Sprite.MoveTo(pt);
g_Enemy5Sprite.m_Movement.m_dy = 1;
g_Enemy5Sprite.m_Movement.m_nPathFindDelay = 200;
g_Enemy5Sprite.SetState(ST_WALK_DOWN, true);
g_EnemySpriteManager.AddSprite(&g_Enemy5Sprite);
}
//放置物品:食物
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_SpecialSprite.MoveTo(pt);
g_SpecialSprite.SetState(ST_FOOD1, true);
SIZE szDim = { 64,64};
// g_Maze.DisplayGrid(true); //显示迷宫格子
// g_Maze.DisplayDeployRects(szDim); //显示物品放置的格点
g_Maze.Draw(g_pMazeSurface); //画迷宫
//显示还剩几条命
SAFE_DELETE( g_pLifeTextSurface );
wsprintf((char*)g_szLifeLeft, (char*)LIFE_LEFT_TEXT, g_nLivesLeft - 1);
g_pDisplay->CreateSurfaceFromText( &g_pLifeTextSurface, hFont, (char*)g_szLifeLeft,
RGB(0,0,0), RGB(255, 255, 0) );
DeleteObject(hFont);
}
//-----------------------------------------------------------------------------
// Name: FreeDirectDraw()
// Desc: Release all the DirectDraw objects
//-----------------------------------------------------------------------------
VOID FreeDirectDraw()
{
#ifdef DISPLAY_STATUS
SAFE_DELETE( g_pTextSurface );
#endif
SAFE_DELETE( g_pLifeTextSurface );
SAFE_DELETE( g_pScoreTextSurface );
SAFE_DELETE( g_pLevelTextSurface );
SAFE_DELETE( g_pMazeSurface );
SAFE_DELETE( g_pSpriteSurface );
SAFE_DELETE( g_pSplashSurface);
SAFE_DELETE( g_pDisplay );
SAFE_DELETE( g_pSplashSound );
SAFE_DELETE( g_pPickupSound );
SAFE_DELETE( g_pSoundManager );
SAFE_DELETE( g_pHandleInput );
}
//-----------------------------------------------------------------------------
// Name: MainWndProc()
// Desc: The main window procedure
//-----------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch (msg)
{
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDM_TOGGLEFULLSCREEN: //Alt+回车快捷键的消息处理函数
//这个快捷键用来切换满屏/窗口模式,这是满屏程序常用的快捷键
if( g_bWindowed )
GetWindowRect( hWnd, &g_rcWindow );
g_bWindowed = !g_bWindowed;
//初始化绘制模式,可为窗口模式或全屏模式
if( FAILED( InitDirectDrawMode( hWnd, g_bWindowed ) ) )
{
SAFE_DELETE( g_pDisplay );
MessageBox( hWnd, TEXT("InitDirectDraw() failed. ")
TEXT("The sample will now exit. "), TEXT("DirectDraw Sample"),
MB_ICONERROR | MB_OK );
PostMessage( hWnd, WM_CLOSE, 0, 0 );
}
return 0L;
case IDM_PAUSE: //Pause快捷键的消息处理函数
g_bActive = true - g_bActive;
return 0L;
case IDM_EXIT: //Esc快捷键的消息处理函数
PostMessage( hWnd, WM_CLOSE, 0, 0 );
return 0L;
}
break; // Continue with default processing
case WM_GETMINMAXINFO: //窗口模式下的消息
{
//不允许改变窗口大小,固定窗口尺寸
MINMAXINFO* pMinMax = (MINMAXINFO*) lParam;
DWORD dwFrameWidth = GetSystemMetrics( SM_CXSIZEFRAME );
DWORD dwFrameHeight = GetSystemMetrics( SM_CYSIZEFRAME );
DWORD dwMenuHeight = GetSystemMetrics( SM_CYMENU );
DWORD dwCaptionHeight = GetSystemMetrics( SM_CYCAPTION );
pMinMax->ptMinTrackSize.x = SCREEN_WIDTH + dwFrameWidth * 2;
pMinMax->ptMinTrackSize.y = SCREEN_HEIGHT + dwFrameHeight * 2 +
dwMenuHeight + dwCaptionHeight;
pMinMax->ptMaxTrackSize.x = pMinMax->ptMinTrackSize.x;
pMinMax->ptMaxTrackSize.y = pMinMax->ptMinTrackSize.y;
}
return 0L;
case WM_MOVE: //窗口模式下的消息
//移动窗口
if( g_pDisplay )
g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE: //检测游戏是否失去了窗口焦点
if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
g_bActive = FALSE;
else
g_bActive = TRUE;
if( g_pDisplay )
g_pDisplay->UpdateBounds();
break;
case WM_SETCURSOR: //光标消息
// 在全屏模式下隐藏光标
if( !g_bWindowed )
{
SetCursor( NULL );
return TRUE;
}
break;
case WM_QUERYNEWPALETTE: //
if( g_pDisplay && g_pDisplay->GetFrontBuffer() )
{
// If we are in windowed mode with a desktop resolution in 8 bit
// color, then the palette we created during init has changed
// since then. So get the palette back from the primary
// DirectDraw surface, and set it again so that DirectDraw
// realises the palette, then release it again.
LPDIRECTDRAWPALETTE pDDPal = NULL;
g_pDisplay->GetFrontBuffer()->GetPalette( &pDDPal );
g_pDisplay->GetFrontBuffer()->SetPalette( pDDPal );
SAFE_RELEASE( pDDPal );
}
break;
case WM_EXITMENULOOP: //忽略在菜单上花费的时间
g_dwLastTick = timeGetTime();
break;
case WM_EXITSIZEMOVE: //忽略移动窗口的时间
g_dwLastTick = timeGetTime();
break;
case WM_SYSCOMMAND: //防止全屏模式下的移动/变尺和调电
switch( wParam )
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
if( !g_bWindowed )
return TRUE;
}
break;
case WM_DESTROY: //清除,结束游戏
FreeDirectDraw();
PostQuitMessage( 0 );
return 0L;
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//-----------------------------------------------------------------------------
// Name: ProcessNextFrame()
// Desc: Move the sprites, blt them to the back buffer, then
// flip or blt the back buffer to the primary buffer
//-----------------------------------------------------------------------------
HRESULT ProcessNextFrame( HWND hWnd )
{
HRESULT hr;
// Figure how much time has passed since the last time
DWORD dwCurrTick = timeGetTime();
DWORD dwTickDiff = dwCurrTick - g_dwLastTick;
// Don't update if no time has passed
if( dwTickDiff == 0 )
return S_OK;
g_dwLastTick = dwCurrTick;
//时间间隔17毫秒
dwTickDiff = 17 - dwTickDiff;
if (dwTickDiff > 0 && dwTickDiff < 17)
Sleep(dwTickDiff); //不足延时
// Sleep(10);
// Check the cooperative level before rendering
if( FAILED( hr = g_pDisplay->GetDirectDraw()->TestCooperativeLevel() ) )
{
switch( hr )
{
case DDERR_EXCLUSIVEMODEALREADYSET:
case DDERR_NOEXCLUSIVEMODE:
// Do nothing because some other app has exclusive mode
Sleep(10);
return S_OK;
case DDERR_WRONGMODE:
// The display mode changed on us. Update the
// DirectDraw surfaces accordingly
return InitDirectDrawMode( hWnd, g_bWindowed );
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -