📄 cracetrack.cpp
字号:
{
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 + -