⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cpp

📁 Torus 3D Engine is an open-source OpenGL ES 3D Engine for creating your own games in BREW environmen
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// -----------------------------------------------------------------------------------------
	//
	// render scene
	//
	// -----------------------------------------------------------------------------------------
	m_pScene->Render(m_pScene->Root(), m_pCam);
}


// ----------------------------------------------------------------------------------------------------------
//
// Render game over
//
// ----------------------------------------------------------------------------------------------------------
void CGame::RenderGameOver()
{
	if (m_kSELECT || m_kCLEAR)
	{
		CleanUpLevel();
		m_dwFrame = 0;
		m_jGameStatus = STATUS_INTRO;
		return;
	}

	// render game over sprite
	m_pSprGameOver->Draw((m_pEngine->ScreenWidth()-m_pSprGameOver->Width())>>1, (m_pEngine->ScreenHeight()-m_pSprGameOver->Height())>>1);

	char szNumber[16];

	// remaining flags
	SPRINTF(szNumber, "%02u", m_jFlagsLeft);
	m_pSprNumbers->DrawNumber(4,m_pEngine->ScreenHeight()-8, szNumber);

	// current level
	SPRINTF(szNumber, "%02u", m_jLevel);
	m_pSprLevel->Draw(4,4);
	m_pSprNumbers->DrawNumber(4,10, szNumber);

	// current score
	SPRINTF(szNumber, "%06u", m_dwScore);
	m_pSprScore->Draw(m_pEngine->ScreenWidth()-m_pSprScore->Width()-4,4);
	m_pSprNumbers->DrawNumber(m_pEngine->ScreenWidth()-33,10, szNumber);

	// "press start"
	m_pSprPressStart->Draw((m_pEngine->ScreenWidth()-m_pSprPressStart->Width())>>1, m_pEngine->ScreenHeight()-m_pSprPressStart->Height()-4);
}


// ----------------------------------------------------------------------------------------------------------
//
// Render a game frame
//
// ----------------------------------------------------------------------------------------------------------
void CGame::RenderGame()
{
	// -----------------------------------------------------------------------------------------
	//
	// player movement
	//
	// -----------------------------------------------------------------------------------------

	if (m_kCLEAR)
	{
		CleanUpLevel();
		m_dwFrame = 0;
		m_jGameStatus = STATUS_INTRO;
		return;
	}

	byte xx;

	if (m_dwFrame > GET_READY_DELAY)
	{
		//
		// 10x10 grid alignment
		//
		word gdx, gdz;
		boolean bMove = FALSE, bAligned = FALSE;

		gdx = XTOI(m_pPlayer->Position()[0]) % 10;
		gdz = XTOI(m_pPlayer->Position()[2]) % 10;

		if (!m_jTurnLeft && !m_jTurnRight)
			bMove = TRUE; //m_kUP;

		if (gdx || gdz)
		{
			bMove = TRUE;
			bAligned = FALSE;
		}
		else bAligned = TRUE;

		// calculate current centered grid position of player
		word gsx, gsz, gsp;
		gsx = (XTOI(m_pPlayer->Position()[0]) + 5) / 10;
		gsz = (XTOI(m_pPlayer->Position()[2]) + 5) / 10;
		gsp = gsx + gsz * GRID_SIZE;

		//
		// check collision with enemy
		//
		if (m_pLevelGrid[gsp] == 4)
		{
			// collided with enemy
			m_pSndBang->Play();
			m_DieImpulse = DIE_IMPULSE;
			m_jGameStatus = STATUS_DYING;
		}

		//
		// turning
		//
		if (bAligned)
		{
			//
			// automan style player turns
			//

			boolean bCanLeft, bCanRight;

			word ang = XTOI(m_pPlayer->Rotation()[1]);
			switch (ang)
			{
				case 0:
				{
					bCanLeft = (m_pLevelGrid[gsp-1] != 0);
					bCanRight = (m_pLevelGrid[gsp+1] != 0);
					break;
				}
				case 180:
				{
					bCanLeft = (m_pLevelGrid[gsp+1] != 0);
					bCanRight = (m_pLevelGrid[gsp-1] != 0);
					break;
				}
				case 90:
				{
					bCanLeft = (m_pLevelGrid[gsp+GRID_SIZE] != 0);
					bCanRight = (m_pLevelGrid[gsp-GRID_SIZE] != 0);
					break;
				}
				case 270:
				{
					bCanLeft = (m_pLevelGrid[gsp-GRID_SIZE] != 0);
					bCanRight = (m_pLevelGrid[gsp+GRID_SIZE] != 0);
					break;
				}
			}

			// ### force no constraints in player rotation
			bCanLeft = bCanRight = TRUE;

			if (m_kDOWN)
			{
				if (!m_jTurnLeft && !m_jTurnRight && !m_klastLEFT)
				{
					m_jTurnLeft = 180;
					m_klastLEFT = TRUE;
					bMove = FALSE;
				}
			}

			if (m_kLEFT && bCanLeft)
			{
				if (!m_jTurnLeft && !m_jTurnRight && !m_klastLEFT)
				{
					m_jTurnLeft = 90;
					m_klastLEFT = TRUE;
					bMove = FALSE;
				}
			}
			else m_klastLEFT = FALSE;

			if (m_kRIGHT && bCanRight)
			{
				if (!m_jTurnRight && !m_jTurnLeft && !m_klastRIGHT)
				{
					m_jTurnRight = 90;
					m_klastRIGHT = TRUE;
					bMove = FALSE;
				}
			}
			else m_klastRIGHT = FALSE;

			if (m_jTurnLeft)
			{
				m_pPlayer->AddRotation(0, ITOX(PLAYER_TURN_SPEED), 0);
				m_jTurnLeft -= PLAYER_TURN_SPEED;
			}
			else m_klastLEFT = FALSE;

			if (m_jTurnRight)
			{
				m_pPlayer->AddRotation(0, -ITOX(PLAYER_TURN_SPEED), 0);
				m_jTurnRight -= PLAYER_TURN_SPEED;
			}
			else m_klastRIGHT = FALSE;
		}

		m_pPlayer->UpdateDirection();

		//
		// movement and collision detection
		//

		int spx=0, spz=0;

		// because lack of precision, select a speed based on orthogonal directions
		// first we initialize spx and spz to just the direction of movement, further ahead
		// we'll multiply then by the PLAYER_MOVE_SPEED.
		switch (XTOI(m_pPlayer->Rotation()[1]))
		{
			case 0:
			{
				spx = 0;
				spz = 1;
				break;
			}
			case 90:
			{
				spx = -1;
				spz = 0;
				break;
			}
			case 180:
			{
				spx = 0;
				spz = -1;
				break;
			}
			case 270:
			{
				spx = 1;
				spz = 0;
				break;
			}
		}

		// end positions (used later)
		word gex, gez, gep;

		// clear current position in the level grid
		m_pLevelGrid[gsp] = 5;	// put "track" there

		//
		// check if can move to the cell ahead
		//
		if (bAligned)
		{
			gex = (XTOI(m_pPlayer->Position()[0]) + spx*10) / 10;
			gez = (XTOI(m_pPlayer->Position()[2]) - spz*10) / 10;
			gep = gex + gez * GRID_SIZE;
			if (m_pLevelGrid[gep] == 0) bMove = FALSE;
		}

		// update speed to correct one
		spx = ITOX(spx * PLAYER_MOVE_SPEED);
		spz = ITOX(spz * PLAYER_MOVE_SPEED);

		if (bMove)
		{
			// end grid position
			gex = (XTOI(m_pPlayer->Position()[0] + spx) + 5) / 10;
			gez = (XTOI(m_pPlayer->Position()[2] - spz) + 5) / 10;
			gep = gex + gez * GRID_SIZE;

			//
			// check end position
			//
			switch (m_pLevelGrid[gep])
			{
				case 0:
				{
					// wall
					break;
				}

				case 1:
				{
					// own player
					m_pPlayer->AddTranslation(spx, 0, -spz);
					break;
				}

				case 2:
				{
					// special flag
					m_pSndSpecialBonus->Play();
					m_pPlayer->AddTranslation(spx, 0, -spz);
					m_pPtrGrid[gep]->AddTranslation(0,ITOX(1000),0);
					m_dwScore += (1 + m_jFlagsCount - m_jFlagsLeft) * 20;
					m_jFlagsLeft--;
					break;
				}

				case 3:
				{
					// normal flag
					m_pSndBonus->Play();
					m_pPlayer->AddTranslation(spx, 0, -spz);
					m_pPtrGrid[gep]->AddTranslation(0,ITOX(1000),0);
					m_dwScore += (1 + m_jFlagsCount - m_jFlagsLeft) * 10;
					m_jFlagsLeft--;
					break;
				}

				case 5:
				{
					// track
					m_pPlayer->AddTranslation(spx, 0, -spz);
					break;
				}
			}
		}

		if (!m_jFlagsLeft)
		{
			// passed level
			m_pSndBonus->Stop();
			m_pSndSpecialBonus->Stop();
			m_jGameStatus = STATUS_PASSLEVEL;
		}

		// recalculate current grid position of player
		gsx = (XTOI(m_pPlayer->Position()[0]) + 5) / 10;
		gsz = (XTOI(m_pPlayer->Position()[2]) + 5) / 10;
		gsp = gsx + gsz * GRID_SIZE;

		// put player on the new position in level grid
		m_pLevelGrid[gsp] = 1;

		// -----------------------------------------------------------------------------------------
		//
		// third person camera
		//
		// -----------------------------------------------------------------------------------------
		m_pCam->TranslateTo(m_pPlayer->Position()[0] - m_pPlayer->Direction()[0]*25,ITOX(20), m_pPlayer->Position()[2] + m_pPlayer->Direction()[2]*25);
		VectorCopy(m_pPlayer->Rotation(), m_pCam->Rotation());
		m_pCam->AddRotation(ITOX(-45), 0, 0);
		m_pCam->UpdateDirection();

		// -----------------------------------------------------------------------------------------
		//
		// enemies movement
		//
		// -----------------------------------------------------------------------------------------
		for (xx=0; xx<m_jEnemyCount; xx++)
		{
			boolean bEnemyTurned = FALSE;

			//
			// 10x10 grid alignment
			//
			gdx = XTOI(m_pEnemies[xx]->Position()[0]) % 10;
			gdz = XTOI(m_pEnemies[xx]->Position()[2]) % 10;

			if (gdx || gdz)
				bAligned = FALSE;
			else
				bAligned = TRUE;

			// because lack of precision, select a speed based on orthogonal directions
			// first we initialize spx and spz to just the direction of movement, further ahead
			// we'll multiply then by the MOVE_SPEED.
			switch (XTOI(m_pEnemies[xx]->Rotation()[1]))
			{
				case 0:
				{
					spx = 0;
					spz = 1;
					break;
				}
				case 90:
				{
					spx = -1;
					spz = 0;
					break;
				}
				case 180:
				{
					spx = 0;
					spz = -1;
					break;
				}
				case 270:
				{
					spx = 1;
					spz = 0;
					break;
				}
			}

			// calculate current centered grid position of enemy
			gsx = (XTOI(m_pEnemies[xx]->Position()[0]) + 5) / 10;
			gsz = (XTOI(m_pEnemies[xx]->Position()[2]) + 5) / 10;
			gsp = gsx + gsz * GRID_SIZE;

			//
			// check if can move to the cell ahead
			//
			if (bAligned)
			{
				gex = (XTOI(m_pEnemies[xx]->Position()[0]) + spx*10) / 10;
				gez = (XTOI(m_pEnemies[xx]->Position()[2]) - spz*10) / 10;
				gep = gex + gez * GRID_SIZE;

				//
				// check end position
				//
				switch (m_pLevelGrid[gep])
				{
					case 0:	// wall
					case 4: // other enemy
					{
						// turn around
						TurnEnemy(xx);
						bEnemyTurned = TRUE;
						break;
					}

					case 2: // special flag
					case 3: // flag
					case 5:
					{
						// track
						// first check if it should turn in an open corner
						if (m_jEnemyStepsToTurn[xx]) m_jEnemyStepsToTurn[xx]--;
						if (!m_jEnemyStepsToTurn[xx])
						{
							m_jEnemyTurns ^= 255;
							word ang = XTOI(m_pEnemies[xx]->Rotation()[1]);
							switch (ang)
							{
								case 0:
								case 180:
								{
									if (m_pLevelGrid[gsp-1] == 5 || m_pLevelGrid[gsp+1] == 5)
									{
										TurnEnemy(xx);
										bEnemyTurned = TRUE;
										m_jEnemyStepsToTurn[xx] = ENEMY_STEPS_TURN;
									}
									break;
								}
								case 90:
								case 270:
								{
									if (m_pLevelGrid[gsp-GRID_SIZE] == 5 || m_pLevelGrid[gsp+GRID_SIZE] == 5)
									{
										TurnEnemy(xx);
										bEnemyTurned = TRUE;
										m_jEnemyStepsToTurn[xx] = ENEMY_STEPS_TURN;
									}
									break;
								}
							}
						}
						break;
					}
				}
			}

			if (!bEnemyTurned)
			{
				// restore old tile value in the level grid
				m_pLevelGrid[gsp] = m_jOldValue[xx];

				// move enemy
				spx = ITOX(spx * ENEMY_MOVE_SPEED);
				spz = ITOX(spz * ENEMY_MOVE_SPEED);
				m_pEnemies[xx]->AddTranslation(spx, 0, -spz);

				// recalculate current grid position of enemy
				gsx = (XTOI(m_pEnemies[xx]->Position()[0]) + 5) / 10;
				gsz = (XTOI(m_pEnemies[xx]->Position()[2]) + 5) / 10;
				gsp = gsx + gsz * GRID_SIZE;

				// save old tile value
				m_jOldValue[xx] = m_pLevelGrid[gsp];
				// put enemy there
				m_pLevelGrid[gsp] = 4;
			}
		}

		m_dwFrame++;

	}	// end if (m_dwFrame > ...)

	// -----------------------------------------------------------------------------------------
	//
	// flags animation
	//
	// -----------------------------------------------------------------------------------------
	for (xx=0; xx<m_jFlagsCount; xx++)
		m_pFlags[xx]->AddRotation(0,ITOX(4),0);

	// -----------------------------------------------------------------------------------------
	//
	// render scene
	//
	// -----------------------------------------------------------------------------------------
	m_pScene->Render(m_pScene->Root(), m_pCam);

	// -----------------------------------------------------------------------------------------
	//
	// show some feedback text
	//
	// -----------------------------------------------------------------------------------------

	char szNumber[16];

	// remaining flags
	SPRINTF(szNumber, "%02u", m_jFlagsLeft);
	m_pSprNumbers->DrawNumber(4,m_pEngine->ScreenHeight()-8, szNumber);

	// current level
	SPRINTF(szNumber, "%02u", m_jLevel);
	m_pSprLevel->Draw(4,4);
	m_pSprNumbers->DrawNumber(4,10, szNumber);

	// current score
	SPRINTF(szNumber, "%06u", m_dwScore);
	m_pSprScore->Draw(m_pEngine->ScreenWidth()-m_pSprScore->Width()-4,4);
	m_pSprNumbers->DrawNumber(m_pEngine->ScreenWidth()-33,10, szNumber);

	// lifes
	for (xx=1; xx<m_jLifes; xx++)
		m_pSprLive->Draw(m_pEngine->ScreenWidth()-(m_pSprLive->Width()+1)*xx-4,m_pEngine->ScreenHeight()-m_pSprLive->Height()-4);

	if (m_dwFrame <= GET_READY_DELAY)
	{
		//
		// get ready animation
		//

		m_pCam->TranslateTo(m_pPlayer->Position()[0] - m_pPlayer->Direction()[0]*25,ITOX(20), m_pPlayer->Position()[2] + m_pPlayer->Direction()[2]*25);
		VectorCopy(m_pPlayer->Rotation(), m_pCam->Rotation());
		m_pCam->AddRotation(ITOX(-45), 0, 0);
		m_pCam->UpdateDirection();

		m_pSprGetReady->Draw((m_pEngine->ScreenWidth()-m_pSprGetReady->Width())>>1, (m_pEngine->ScreenHeight()-m_pSprGetReady->Height())>>1);

		m_dwFrame++;
	}
}

⌨️ 快捷键说明

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