📄 gameframe.cpp
字号:
/*===============================================================================
METHOD: Ai
=============================================================================== */
void GameFrame::Ai()
{
int bend, dist;
int move;
int i;
int bike;
int idealPos;
int speedDiff;
int absBend;
int playerZ;
int posDiff;
playerZ = m_zPos[0] + (m_trackLength * m_lap[0]);
for(bike = 1; bike < NUM_BIKES; bike++)
{
if(m_bRace_over)
{
m_speed[bike] -= m_speed[bike] >> 4;
if(m_speed[bike] < 0x40000)
m_speed[bike] = 0;
m_zPos[bike] += m_speed[bike] >> 16;
}
else // Still Racing
{
//move opponent to inside of any bend he's on
bend = GetCurrentBend(m_zPos[bike]);
//other bikes near, don't move if they are
if(bend < 0)
m_onBend[bike] = -1;
else if(bend > 0)
m_onBend[bike] = 1;
else
m_onBend[bike] = 0;
idealPos = (m_onBend[bike] * 60) << 16;
int left = -110 << 16;
int right = 110 >> 16;
for(i = 0; i< NUM_BIKES; i++)
{
if(i != bike)
{
dist = (m_zPos[i] + (m_lap[i] * m_trackLength)) - (m_zPos[bike] + (m_lap[bike] * m_trackLength));
if(dist < 256 && dist > -256)
{
if(m_xPos[bike] - m_xPos[i] < 0) //this bike is to my right
{
if(right > m_xPos[i] - 0x100000)
right = m_xPos[i] - 0x100000;
}
else
{
if(left < m_xPos[i] + 0x100000)
left = m_xPos[i] + 0x100000;
}
}
}
}
if(idealPos < m_xPos[bike] && idealPos < left) //want to move left
idealPos = left;
else if(idealPos > m_xPos[bike] && idealPos > right)
idealPos = right;
move = idealPos - m_xPos[bike];
move >>= 2;
if(move > 010000)
move = 0x10000;
else if(move < -0x10000)
move = -0x10000;
m_xPos[bike] += move;
//work out desired gear
//check all gear speeds and select most suitable for current speed
for(i = 0; i < 5; i++)
{
speedDiff = m_gearSpeeds[bike][i] - m_speed[bike];
if(speedDiff > 0x60000) //too far to next gear
break;
}
m_desiredGear[bike] = i;
absBend = ABS(bend);
if(absBend >= 5)
{
if(m_desiredGear[bike] > 3) //sharp bend
m_desiredGear[bike] = 3;
}
else if(absBend >= 3 && m_desiredGear[bike] > 4) //medium bend
m_desiredGear[bike] = 4;
//accelerate to this gear's top speed
speedDiff = m_gearSpeeds[bike][m_gear[bike]] - m_speed[bike];
if(speedDiff < 0) //decelerate
m_speed[bike] += speedDiff >> 4;
else
{
int accel = speedDiff >> 3;
if(accel < 0x10000)
accel = 0x10000;
else if(accel > 0x40000)
accel = 0x40000;
m_speed[bike] += accel;
//check if we should change gear
if(m_desiredGear[bike] < m_gear[bike])
m_gear[bike]--;
else if(m_desiredGear[bike] > m_gear[bike])
{
m_gear[bike]++;
}
}
posDiff = m_zPos[bike] + (m_trackLength * m_lap[bike]) - playerZ;
if(posDiff > 5000) //leading player
{
if(m_pFrontend->m_difficultyLevel == 0 && m_speedRatio[bike] > 80) //Amateur
m_speedRatio[bike] = 80;
else if(m_pFrontend->m_difficultyLevel == 1 && m_speedRatio[bike] > 90) //Int.
m_speedRatio[bike] = 90;
//pro bikes always stay at top speed
}
else if(posDiff < -1000 && m_speedRatio[bike] < 100)
m_speedRatio[bike]++; //full speed when behind
else //somewhere inbetween so gradually speed up closer to player
{
posDiff += 1000; //now between 0 and 6000;
if(m_pFrontend->m_difficultyLevel == 0) //Amateur
m_speedRatio[bike] = 100 - (posDiff / 300);
else if(m_pFrontend->m_difficultyLevel == 1) //Int.
m_speedRatio[bike] = 100 - (posDiff / 600);
}
int oldZ = m_zPos[bike] & 0x8000;
m_zPos[bike] += ((m_speed[bike] / 100) * m_speedRatio[bike]) >> 16;
if(m_zPos[bike] > m_trackLength)
{
m_lap[bike]++;
m_zPos[bike] &= m_trackLength;
}
//change bikes speed every 0x8000 units
int newZ = m_zPos[bike] & 0x8000;
if(newZ != oldZ)
CalcGearSpeeds(bike);
}// end if(m_bRace_over)
}//end for(bike = 1; bike < NUM_BIKES; bike++)
//get positions of all bikes now they've moved
if(!m_bRace_over) // As soon as Race crosses the finishing line, the race position is consolidated
{
for(i = 0; i < NUM_BIKES; i++)
CalcRacePosition(i);
}
}
/*===============================================================================
METHOD: InitBikes
=============================================================================== */
void GameFrame::InitBikes()
{
int frac = (1024 << 16) / 140;
int frac2 = (NUM_DIST << 16) / 1023;
int idx;
for(int i = 0; i < NUM_DIST; i++)
{
idx = 1023 - m_pData->roadTable[1023 - (i * 8)];
idx = (idx * frac2) >> 16;
m_distTab[i] = ((140 - idx) * frac) >> 16;
}
GenCPUCharacters(m_pFrontend->m_myCharacter);
m_numBikes = 0;
}
/*===============================================================================
METHOD: AddBike
=============================================================================== */
void GameFrame::AddBike(int x)
{
m_xPos[m_numBikes] = x << 16;
m_zPos[m_numBikes] = 0;
m_speed[m_numBikes] = 0;
m_onBend[m_numBikes] = 0;
m_lap[m_numBikes] = 0;
m_racePos[m_numBikes] = 1; //everybody is first!
m_gear[m_numBikes] = 0;
m_speedRatio[m_numBikes] = 100;
m_desiredGear[m_numBikes] = 5;
CalcGearSpeeds(m_numBikes);
m_numBikes++;
}
/*===============================================================================
METHOD: InitScenery
=============================================================================== */
void GameFrame::InitScenery()
{
int i;
//trees are dealt with separately to other scenery
m_pTreeRandom->SetSeed(0x12345678);
for(i = 0; i < NUM_TREES; i++)
AddTree(i, i * 1024);
m_firstTree = 0;
//clear all scenery
for(i = 0; i < NUM_SCENERY; i++)
m_sceneryTypes[i] = SCENERY_NONE;
m_lastSceneryItem = 0;
m_numSceneryObjects = 0;
GenerateScenery(m_pTrackSceneryTable[m_pFrontend->m_currentTrack]);
SortScenery();
}
/*===============================================================================
METHOD: DrawScenery
=============================================================================== */
void GameFrame::DrawScenery()
{
int i;
int zReal;
int x;
int playerPos;
int tree;
int cmp;
int treePos;
int numCoords;
int numPolys;
playerPos=m_zPos[0];
tree=(m_firstTree-1)&3;
cmp=tree;
treePos=m_treeZ[tree]-playerPos;
if(treePos<0)
treePos+=m_trackLength;
i=m_lastSceneryItem;
do
{
i++;
if(i==m_numSceneryObjects)
i=0;
zReal=m_sceneryZ[i]-playerPos;
if(zReal<0)
zReal+=m_trackLength;
}while(zReal<4096);
if(i==0)
i=m_numSceneryObjects-1;
else
i--;
m_lastSceneryItem=i;
do
{
zReal=m_sceneryZ[i]-playerPos;
if(zReal<0)
zReal+=m_trackLength;
if(zReal>0 && zReal<4096)
{
//is there a tree first
while(treePos>zReal)
{
DrawTree(tree);
tree=(tree-1)&3;
if(tree==cmp)
treePos=-7654321;
else
treePos=m_treeZ[tree]-playerPos;
}
switch(m_sceneryTypes[i])
{
case SCENERY_LAMPPOST:
if(m_sceneryX[i]<0)
{
//YINGZ: DO SOME OPTIMIZATION HERE: NOW WE USE DEFINE FOR VTX NUMS, NO LONGER NEED TO CALCULATE
numCoords = sizeof(m_pData->leftLamppostVtx)/ sizeof(short);
CalcScreenCoords(m_pData->leftLamppostVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->leftLamppostPolys)/ sizeof(short);
DrawModel(m_pData->leftLamppostPolys,numPolys);
}
else
{
numCoords = sizeof(m_pData->rightLamppostVtx)/ sizeof(short);
CalcScreenCoords(m_pData->rightLamppostVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->rightLamppostPolys)/ sizeof(short);
DrawModel(m_pData->rightLamppostPolys,numPolys);
}
break;
case SCENERY_TUNNEL:
numCoords = sizeof(m_pData->tunnelVtx)/ sizeof(short);
CalcScreenCoords(m_pData->tunnelVtx,numCoords,m_sceneryX[i],zReal);
m_pGraph->SetColor(0x808080);
m_pGraph->SetFillColor(0x808080);
m_pGraph->FillRect(0,m_screenCoords[1],m_screenCoords[0],m_screenCoords[3]-m_screenCoords[1]);
m_pGraph->FillRect(m_screenCoords[2],m_screenCoords[1],m_canvasW-m_screenCoords[2],m_screenCoords[3]-m_screenCoords[1]);
break;
case SCENERY_DUCATI:
if(m_sceneryX[i]<0)
{
numCoords = sizeof(m_pData->ducatiLeftVtx)/ sizeof(short);
CalcScreenCoords(m_pData->ducatiLeftVtx,numCoords,-100,zReal);
numPolys = sizeof(m_pData->ducatiLeftPolys)/ sizeof(short);
DrawModel(m_pData->ducatiLeftPolys,numPolys);
}
else
{
numCoords = sizeof(m_pData->ducatiRightVtx)/ sizeof(short);
CalcScreenCoords(m_pData->ducatiRightVtx,numCoords,110,zReal);
numPolys = sizeof(m_pData->ducatiRightPolys)/ sizeof(short);
DrawModel(m_pData->ducatiRightPolys,numPolys);
}
break;
case SCENERY_BARN:
if(m_sceneryX[i]<0)
{
numCoords = sizeof(m_pData->leftBarnVtx)/ sizeof(short);
CalcScreenCoords(m_pData->leftBarnVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->leftBarnPolys)/ sizeof(short);
DrawModel(m_pData->leftBarnPolys,numPolys);
}
else
{
numCoords = sizeof(m_pData->rightBarnVtx)/ sizeof(short);
CalcScreenCoords(m_pData->rightBarnVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->rightBarnPolys)/ sizeof(short);
DrawModel(m_pData->rightBarnPolys,numPolys);
}
break;
case SCENERY_HOUSE:
if(m_sceneryX[i]<0)
{
numCoords = sizeof(m_pData->leftHouseVtx)/ sizeof(short);
CalcScreenCoords(m_pData->leftHouseVtx,numCoords,-170,zReal);
numPolys = sizeof(m_pData->leftHousePolys)/ sizeof(short);
DrawModel(m_pData->leftHousePolys,numPolys);
}
else
{
}
break;
case SCENERY_DORIC:
numCoords = sizeof(m_pData->doricVtx)/ sizeof(short);
CalcScreenCoords(m_pData->doricVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->doricPolys)/ sizeof(short);
DrawModel(m_pData->doricPolys,numPolys);
break;
case SCENERY_ARROW:
if(m_isCliff==2 && m_sceneryX[i]>0)
{
numCoords = sizeof(m_pData->cliffArrowVtx)/ sizeof(short);
CalcScreenCoords(m_pData->cliffArrowVtx,numCoords,104,zReal);
numPolys = sizeof(m_pData->cliffArrowPolys)/ sizeof(short);
DrawModel(m_pData->cliffArrowPolys,numPolys);
}
else
{
numCoords = sizeof(m_pData->arrowVtx)/ sizeof(short);
CalcScreenCoords(m_pData->arrowVtx,numCoords,m_sceneryX[i],zReal);
if(m_sceneryX[i]<0)
{
numPolys = sizeof(m_pData->rightArrowPolys)/ sizeof(short);
DrawModel(m_pData->rightArrowPolys,numPolys);
}
else
{
numPolys = sizeof(m_pData->leftArrowPolys)/ sizeof(short);
DrawModel(m_pData->leftArrowPolys,numPolys);
}
}
break;
case SCENERY_DOUBLE_ARROW:
if(m_isCliff==2 && m_sceneryX[i]>0)
{
numCoords = sizeof(m_pData->cliffDoubleArrowVtx)/ sizeof(short);
CalcScreenCoords(m_pData->cliffDoubleArrowVtx,numCoords,104,zReal);
numPolys = sizeof(m_pData->cliffDoubleArrowPolys)/ sizeof(short);
DrawModel(m_pData->cliffDoubleArrowPolys,numPolys);
}
else
{
numCoords = sizeof(m_pData->doubleArrowVtx)/ sizeof(short);
CalcScreenCoords(m_pData->doubleArrowVtx,numCoords,m_sceneryX[i],zReal);
if(m_sceneryX[i]<0)
{
numPolys = sizeof(m_pData->doubleRightArrowPolys)/ sizeof(short);
DrawModel(m_pData->doubleRightArrowPolys,numPolys);
}
else
{
numPolys = sizeof(m_pData->doubleLeftArrowPolys)/ sizeof(short);
DrawModel(m_pData->doubleLeftArrowPolys,numPolys);
}
}
break;
case SCENERY_START_LINE:
numCoords = sizeof(m_pData->startLineVtx)/ sizeof(short);
CalcScreenCoords(m_pData->startLineVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->startLinePolys)/ sizeof(short);
DrawModel(m_pData->startLinePolys,numPolys);
break;
case SCENERY_SPEED_SIGN:
numCoords = sizeof(m_pData->speedSignVtx)/ sizeof(short);
CalcScreenCoords(m_pData->speedSignVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->speedSignPolys)/ sizeof(short);
DrawModel(m_pData->speedSignPolys,numPolys);
break;
case SCENERY_WARNING_SIGN:
numCoords = sizeof(m_pData->warningSignVtx)/ sizeof(short);
CalcScreenCoords(m_pData->warningSignVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->warningSignPolys)/ sizeof(short);
DrawModel(m_pData->warningSignPolys,numPolys);
break;
case SCENERY_JUNCTION:
case SCENERY_JUNCTION2:
{
int z=zReal+1024;
if(z>4096)
z=4096;
m_pGraph->SetColor(m_TarmacColour[m_pFrontend->m_currentTrack]);
m_pGraph->SetFillColor(m_TarmacColour[m_pFrontend->m_currentTrack]);
numCoords = sizeof(m_pData->junctionVtx)/ sizeof(short);
CalcScreenCoords(m_pData->junctionVtx,numCoords,0,zReal);
m_pGraph->FillTriangle(m_screenCoords[2],m_screenCoords[1],m_screenCoords[0],m_screenCoords[1],m_screenCoords[2],m_screenCoords[3]);
m_pGraph->FillTriangle(m_screenCoords[4],m_screenCoords[5],m_screenCoords[6],m_screenCoords[5],m_screenCoords[6],m_screenCoords[7]);
m_pGraph->DrawLine(m_screenCoords[0],m_screenCoords[1],m_screenCoords[2],m_screenCoords[3]);
m_pGraph->DrawLine(m_screenCoords[4],m_screenCoords[5],m_screenCoords[6],m_screenCoords[7]);
m_pGraph->FillRect(0,m_screenCoords[1],m_screenCoords[2],m_screenCoords[3]-m_screenCoords[1]);
m_pGraph->FillRect(m_screenCoords[6],m_screenCoords[1],m_canvasW-m_screenCoords[6],m_screenCoords[3]-m_screenCoords[1]);
if(m_sceneryTypes[i]==SCENERY_JUNCTION)
{
numCoords = sizeof(m_pData->trafficLightVtx)/ sizeof(short);
CalcScreenCoords(m_pData->trafficLightVtx,numCoords,-120,zReal);
numPolys = sizeof(m_pData->trafficLightPolys)/ sizeof(short);
DrawModel(m_pData->trafficLightPolys,numPolys);
numCoords = sizeof(m_pData->trafficLightVtx)/ sizeof(short);
CalcScreenCoords(m_pData->trafficLightVtx,numCoords,120,zReal+1024);
numPolys = sizeof(m_pData->trafficLightPolys)/ sizeof(short);
DrawModel(m_pData->trafficLightPolys,numPolys);
}
else
{
numCoords = sizeof(m_pData->warningSignVtx)/ sizeof(short);
CalcScreenCoords(m_pData->warningSignVtx,numCoords,-120,zReal);
numPolys = sizeof(m_pData->warningSignPolys)/ sizeof(short);
DrawModel(m_pData->warningSignPolys,numPolys);
numCoords = sizeof(m_pData->warningSignVtx)/ sizeof(short);
CalcScreenCoords(m_pData->warningSignVtx,numCoords,120,zReal+1024);
numPolys = sizeof(m_pData->warningSignPolys)/ sizeof(short);
DrawModel(m_pData->warningSignPolys,numPolys);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -