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

📄 cracetrack.cpp

📁 Visual C++游戏开发技术与实例一书配套光盘。包含了冒险屠宰场、入侵者、赛车、网络五子棋、网络台球、对战坦克大战和面包圈7个游戏实例的完整源代码。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	{
		m_iViewY -= (m_iViewY)-(iY - VIEW_RANGEY);
	}
	
	if(iX - VIEW_RANGEX < m_iViewX)
	{
		m_iViewX -= (m_iViewX)-(iX - VIEW_RANGEX);
	}

	if(m_iViewY<0)
		m_iViewY = 0;

	if(m_iViewX<0)
		m_iViewX = 0;

	if(m_iViewX > (m_iCols * 40)-640)
		m_iViewX = (m_iCols * 40)-640;

	if(m_iViewY > (m_iRows * 40)-480)
		m_iViewY =(m_iRows * 40)-480;
}

int cRaceTrack::GetViewX()
{
	return m_iViewX;
}

int cRaceTrack::GetViewY()
{
	return m_iViewY;
}

BOOL cRaceTrack::CarHittedRoad(cRaceCar *pCar, int iX, int iY)
{
	//int iX, iY;
	if(iX == -1 && iY == -1)
		pCar->GetPos(&iX, &iY);
	
	return m_hcRoadMap.HaveHitted(&pCar->m_hcRaceCar, iX, iY, 0, 0);
}

int cRaceTrack::GetCheckPoint(int iX, int iY)
{
	// Check if have any check point in the iX and iY position
	iX = iX / 40;
	iY = iY / 40;
	
	if(iX < 0)
		return 0;

	if(iY < 0)
		return 0;

	if(iX > m_iCols-1)
		return 0;

	if(iY > m_iRows-1)
		return 0;

	int iResp = m_RoadMap.GetValue((int)iX,(int)iY);
	// The check point is the LOWER BYTE of the HIWORD of the track DWORD array
	iResp = LOBYTE(HIWORD(iResp));
	return iResp;
}

int cRaceTrack::GetMaxCheckPoint()
{
	// This function is used to get the number of the Last Check point we
	// have in the track

	if(m_iMaxCheckPoint != 0)
		return m_iMaxCheckPoint;

	for(int j=0;j<m_iRows;j++)
	{
		for(int i=0;i<m_iCols;i++)
		{
			if(LOBYTE(HIWORD(m_RoadMap.GetValue(i,j))) > m_iMaxCheckPoint)
				m_iMaxCheckPoint = LOBYTE(HIWORD(m_RoadMap.GetValue(i,j)));
		}
	}


	return m_iMaxCheckPoint;
}

int compare(const void* p1, const void* p2)
{
	// This function is used to sort the cars, so that we know
	// their position in the track
	cRaceCar *pCar1, *pCar2;

	pCar1 = *(cRaceCar**) p1;
	pCar2 = *(cRaceCar**) p2;

//	char buffer[100];

//	sprintf(buffer,"CAR1 %d CAR2 %d", pCar1->m_iLaps, pCar2->m_iLaps);
//	DXTRACE_MSG(buffer);

	if(pCar1->GetCarState() == CARSTATE_RACECOMPLETED &&
		pCar2->GetCarState() != CARSTATE_RACECOMPLETED)
		return -1;

	if(pCar1->GetCarState() == CARSTATE_RACECOMPLETED &&
		pCar2->GetCarState() != CARSTATE_RACECOMPLETED)
		return 1;

	if(pCar1->GetCarState() == CARSTATE_RACECOMPLETED &&
		pCar2->GetCarState() == CARSTATE_RACECOMPLETED)
	{
		if(pCar1->GetPosition() < pCar2->GetPosition())
			return -1;

		if(pCar1->GetPosition() > pCar2->GetPosition())
			return 1;
	}

	if(pCar1->m_iLaps < pCar2->m_iLaps)
	{
		return 1;
	}
	else
	{
		if(pCar1->m_iLaps > pCar2->m_iLaps)
		{
			return -1;
		}
		else
		{
			if(pCar1->m_iCheckPoint < pCar2->m_iCheckPoint)
			{
				return 1;
			}
			else
			{
				if(pCar1->m_iCheckPoint > pCar2->m_iCheckPoint)
					return -1;
				else
				{
					if(pCar1->GetDistanceToNextCheckPoint() > pCar2->GetDistanceToNextCheckPoint())
						return 1;
					else
						return -1;
				}	
			}
		}
	}
}

void cRaceTrack::Process()
{
	
	int		iOffset = 0, i=0;

	// This is the main function of the track
	// Here is where the game really happens. At each game iteration, we磍l call
	// this function to process the car data (including the racecars)

	int iSrcCarX, iSrcCarY, iCarX, iCarY;


	
	// The first thing we do is check if each one of the cars hit another car
	// If they hit another car then the car that hit will be slowed down
	// and the car that was hit will move forward
	// Notice that we磍l only check this if we磖e on the single player mode
	// or if we磖e hosting a multiplayer game. mutiplayer peers will receive
	// this information in the network package
	if(  
	   ( (GetRaceXApp()->m_bIsMultiplayer == TRUE && GetRaceXApp()->GetMultiplayer()->IsHosting())
	   || GetRaceXApp()->m_bIsMultiplayer == FALSE) && m_iState > 2
	  )
	{   
		for(i=m_iNumCars-1;i>=0;i--)
		{
			for(int j=0;j<i;j++)
			{
				if(i!=j)
				{
					m_pRaceCars[j]->GetPos(&iCarX, &iCarY);
					m_pRaceCars[i]->GetPos(&iSrcCarX, &iSrcCarY);

					if(m_pRaceCars[j]->m_hcRaceCar.HaveHitted(&m_pRaceCars[i]->m_hcRaceCar, iCarX, iCarY, iSrcCarX, iSrcCarY) == TRUE)
					{
						if(m_pRaceCars[j]->GetSpeed() != 0)
						{
							
							if(m_pRaceCars[i]->GetLastCheckPoint() < m_pRaceCars[j]->GetLastCheckPoint())
							{
								m_pRaceCars[i]->HitCar();
								m_pRaceCars[j]->MoveForward(/*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
								m_pRaceCars[j]->Accelerate();
							}
							else if (m_pRaceCars[i]->GetLastCheckPoint() < m_pRaceCars[j]->GetLastCheckPoint())
							{
								m_pRaceCars[j]->HitCar();
								m_pRaceCars[i]->MoveForward(/*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
								m_pRaceCars[i]->Accelerate();
							}
							else
							{
								if(m_pRaceCars[i]->GetDistanceToNextCheckPoint() > m_pRaceCars[j]->GetDistanceToNextCheckPoint())
								{
									m_pRaceCars[i]->HitCar();
									m_pRaceCars[j]->MoveForward(/*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
									m_pRaceCars[j]->Accelerate();
								}
								else
								{
									m_pRaceCars[j]->HitCar();
									m_pRaceCars[i]->MoveForward( /*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
									m_pRaceCars[i]->Accelerate();
								}
							}

						}
					}
				}
			}
		}
	}
	
	// In this loop we磍l process each one of the cars and set its position
	for(i=0;i<m_iNumCars;i++)
	{
		// Set the current car position (if we磖e hosting a game or are in a single player game)
		if(   ( (GetRaceXApp()->m_bIsMultiplayer == TRUE && GetRaceXApp()->GetMultiplayer()->IsHosting())  || GetRaceXApp()->m_bIsMultiplayer == FALSE) )	
			m_pRaceCars[i]->SetPosition(i+1);
		
		// We磍l only process the car if the semaphore reached the "green" light
		if(m_iState > 2)
			m_pRaceCars[i]->Process(this);
		
		// Here we磍l check if the car hit the Road. If so, we change the
		// car state to CARSTATE_CRASHED_WALL
		if(   ( (GetRaceXApp()->m_bIsMultiplayer == TRUE && GetRaceXApp()->GetMultiplayer()->IsHosting())
		   || GetRaceXApp()->m_bIsMultiplayer == FALSE) 
		   )	
		{
			if(m_pRaceCars[i]->GetCarState() == CARSTATE_OK)
			{
				if(CarHittedRoad(m_pRaceCars[i]) == TRUE)
				{
					m_pRaceCars[i]->SetCarState(CARSTATE_CRASHED_WALL);
				}
			}
		}

		// After processing the car, we will adjust the car view
		if(m_pRaceCars[i]->GetControlType() == CTRL_USER || m_pRaceCars[i]->GetControlType() == CTRL_NETWORK_LOCAL)
		{
			AdjustView(m_pRaceCars[i]);
		}
	}

	// We process all the cars and adjusted the view, now draw each one of the cars
	for(i=0;i<m_iNumCars;i++)
	{

		if(	!(m_pRaceCars[i]->GetCarState() == CARSTATE_RACECOMPLETED &&
			m_pRaceCars[i]->GetLapElapseTime() > 5000)  )
			m_pRaceCars[i]->Draw(GetViewX(), GetViewY());
	
		if(m_pRaceCars[i]->GetCarState() == CARSTATE_RACECOMPLETED && 
		   (m_pRaceCars[i]->GetControlType() == CTRL_USER || m_pRaceCars[i]->GetControlType() == CTRL_NETWORK_LOCAL) )
		{
			m_surfRaceCompleted.Draw(GetMainApp()->m_pBackBuffer, 245, 190);
		}		
	}   

	// This is used to draw the semaphore on the screen
	switch(m_iState)
	{
	case 0:

		m_sptrWait.Create(GetMainApp()->GetInstHandle(), IDB_TRAFFICLIGHT, 120, 60, RGB(0,0,0), 40, 60);
		m_sptrWait.m_iAbsolutePosition = 0;
		m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		m_lStartTime = GetTickCount();
		m_iState++;
		m_sndSemaphore.Play();
		break;
	case 1:
		if(GetTickCount() - m_lStartTime > 1200)
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, TRUE);	
			m_lStartTime = GetTickCount();
			m_iState++;
			m_sndSemaphore.Play();
		}
		else
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		}
		break;
	case 2:
		if(GetTickCount() - m_lStartTime > 1200)
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, TRUE);	
			m_lStartTime = GetTickCount();
			m_iState++;
			m_sndSemaphore.Play();
		}
		else
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		}
		break;
	default:
		if(GetTickCount() - m_lStartTime < 1200)
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		}
		break;
	}
	
	
	if(m_iState > 2)
		qsort(m_pRaceCars, m_iNumCars, sizeof(cRaceCar*), compare);

}

cRaceCar* cRaceTrack::GetCar(int iPos)
{
	return m_pRaceCars[iPos];
}

void cRaceTrack::AddCar(cRaceCar *pCar)
{
	// When we add the cars to the race track
	// we need to add them in the correct position
	int iX, iY;

	m_pRaceCars[m_iNumCars] = pCar;
	m_iNumCars++;

	GetStartPosition(&iX, &iY);
	
	switch(m_iNumCars-1)
	{
	case 0:
		pCar->SetPos(iX, iY);
		break;
	case 1:
		pCar->SetPos(iX+40, iY);
		break;
	case 2:
		pCar->SetPos(iX, iY+40);
		break;
	case 3:
		pCar->SetPos(iX+40, iY+40);
		b

⌨️ 快捷键说明

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