main.cpp

来自「VC游戏编程基础」· C++ 代码 · 共 1,966 行 · 第 1/4 页

CPP
1,966
字号
	g_SheepSprite.AddState(ST_STAND_STILL, pt, 2, 60);
	rcBounding.top = 0;
	rcBounding.bottom = nHeight-10;
	rcBounding.left = 10;
	rcBounding.right= nWidth - 20;
	pt.x = 6*64; pt.y =6*64;
	g_SheepSprite.AddState(ST_WALK_UP, pt, 3, 10,&rcBounding);
	rcBounding.top = 10;
	rcBounding.bottom = nHeight-10;
	
	pt.x = 64*9;pt.y = 6*64;
	g_SheepSprite.AddState(ST_WALK_DOWN, pt, 3, 10,&rcBounding);
	
	rcBounding.top = 10;
	rcBounding.bottom = nHeight - 20;
	rcBounding.left = 0;
	rcBounding.right=nWidth - 10;
	pt.x = 3*64;pt.y = 6*64;
	g_SheepSprite.AddState(ST_WALK_LEFT, pt, 3, 10,&rcBounding);
	pt.x = 64*0;pt.y = 6*64;
	rcBounding.left = 10;
	rcBounding.right=nWidth-10;
	
	g_SheepSprite.AddState(ST_WALK_RIGHT, pt, 3, 10,&rcBounding);
	pt.x = 64 * 8; pt.y = 9 * 64;
	g_SheepSprite.AddState(ST_KILL, pt, 4, 20);
	g_SheepSprite.MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);
	g_SheepSprite.m_pfnDead = DeadPig;
	g_SheepSprite.m_Movement.m_pfnCollision = IsHit;
	
	g_SheepPooSprite.CreateSprite(&g_pSpriteSurface, TYPE_POO, nHeight,nWidth);
	rcBounding.top = rcBounding.left = 20;
	rcBounding.right=rcBounding.bottom = nHeight - 40;
	pt.x = 0*64;pt.y = 9*64;
	g_SheepPooSprite.AddState(ST_DEFAULT, pt, 3, 50,&rcBounding);
	pt.x = 11*64;pt.y = 10*64;
	g_SheepPooSprite.AddState(ST_DEAD, pt, 3, 50,&rcBounding);
	g_SheepPooSprite.SetState(ST_DEFAULT);
	
	// --------------- 敌人精灵--------------------//
	
	//敌人精灵管理器
	g_EnemySpriteManager.SetCollAndPathFn(IsHit, FindPath);
	
	rcBounding.left =  10;
	rcBounding.top =0;
	rcBounding.right = SPRITE_WIDTH - 20;
	rcBounding.bottom = SPRITE_HEIGHT ;
	
    g_Enemy1Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY1, nHeight,nWidth);
	pt.x = 6*64;pt.y = 0*64;
	g_Enemy1Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
	pt.x = 3*64;pt.y = 0*64;
	g_Enemy1Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
	pt.x = 0*64;pt.y = 0*64;
	g_Enemy1Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
	pt.x = 8*64;pt.y = 0*64;
	g_Enemy1Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
	pt.x = 10*64;pt.y = 0*64;
	g_Enemy1Sprite.AddState(ST_KILL, pt, 3, 100);
	g_Enemy1Sprite.m_pfnDead= DeadEnemy;
	g_Enemy1Sprite.m_nPoints = 100;
	
	
    g_Enemy2Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY2, nHeight,nWidth);
	pt.x = 6*64;pt.y = 1*64;
	g_Enemy2Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
	pt.x = 3*64;pt.y = 1*64;
	g_Enemy2Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
	pt.x = 0*64;pt.y = 1*64;
	g_Enemy2Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
	pt.x = 8*64;pt.y = 1*64;
	g_Enemy2Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
	pt.x = 10*64;pt.y = 1*64;
	g_Enemy2Sprite.AddState(ST_KILL, pt, 3, 100);
	g_Enemy2Sprite.m_pfnDead= DeadEnemy;
	g_Enemy2Sprite.m_nPoints = 100;
	
    g_Enemy3Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY3, nHeight,nWidth);
	pt.x = 6*64;pt.y = 2*64;
	g_Enemy3Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
	pt.x = 3*64;pt.y = 2*64;
	g_Enemy3Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
	pt.x = 0*64;pt.y = 2*64;
	g_Enemy3Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
	pt.x = 8*64;pt.y = 2*64;
	g_Enemy3Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
	pt.x = 10*64;pt.y = 2*64;
	g_Enemy3Sprite.AddState(ST_KILL, pt, 3, 100);
	g_Enemy3Sprite.m_pfnDead= DeadEnemy;
	g_Enemy3Sprite.m_nPoints = 100;
	g_EnemySpriteManager.AddSprite(&g_Enemy3Sprite);
	
    g_Enemy4Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY4, nHeight,nWidth);
	pt.x = 6*64;pt.y = 3*64;
	g_Enemy4Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
	pt.x = 3*64;pt.y = 3*64;
	g_Enemy4Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
	pt.x = 0*64;pt.y = 3*64;
	g_Enemy4Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
	pt.x = 8*64;pt.y = 3*64;
	g_Enemy4Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
	pt.x = 10*64;pt.y =3*64;
	g_Enemy4Sprite.AddState(ST_KILL, pt, 3, 100);
	g_Enemy4Sprite.m_pfnDead= DeadEnemy;
	g_Enemy4Sprite.m_nPoints = 200;
	g_EnemySpriteManager.AddSprite(&g_Enemy4Sprite);
	
    g_Enemy5Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY4, nHeight,nWidth);
	pt.x = 6*64;pt.y = 3*64;
	g_Enemy5Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
	pt.x = 3*64;pt.y = 3*64;
	g_Enemy5Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
	pt.x = 0*64;pt.y = 3*64;
	g_Enemy5Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
	pt.x = 8*64;pt.y = 3*64;
	g_Enemy5Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
	pt.x = 10*64;pt.y =3*64;
	g_Enemy5Sprite.AddState(ST_KILL, pt, 3, 100);
	g_Enemy5Sprite.m_pfnDead= DeadEnemy;
	g_Enemy5Sprite.m_nPoints = 200;
	g_EnemySpriteManager.AddSprite(&g_Enemy5Sprite);
	
	
	//其它精灵
	g_SpecialSprite.CreateSprite(&g_pSpriteSurface, TYPE_SPECIAL, nHeight,nWidth);
	pt.x = 5*64;pt.y = 10*64;
	g_SpecialSprite.AddState(ST_FOOD1, pt, 1, 100);
	pt.x = 6*64;pt.y = 10*64;
	g_SpecialSprite.AddState(ST_FOOD2, pt, 1, 100);
	pt.x = 7*64;pt.y = 10*64;
	g_SpecialSprite.AddState(ST_FOOD3, pt, 1, 100);
	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_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) ) ;
	
	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;
	

	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 );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?