📄 gameframe.cpp
字号:
acc <<= 1;
g--;
}
m_revs += (0x10000 - m_revs) / acc;
int leanDiff = ABS(m_lean) << 3;
m_speed[0] = m_revs * ((m_gearSpeeds[0][m_gear[0]] - leanDiff) >> 16);
} //end if(diff < 0)
}
} //end if(m_bCrashing)
m_zPos[0] += m_speed[0] >> 16;
m_partsWear[0] += (m_speed[0] / 3) >> 15; //tyres
m_partsWear[1] += (m_speed[0] / 5) >> 15; //suspension
m_partsWear[2] += (m_speed[0] / 7) >> 15; //exhaust
m_partsWear[3] += (m_speed[0] / 6) >> 15; //engine
if(m_zPos[0] > m_trackLength) //done a lap?
{
m_lap[0]++;
m_zPos[0] &= m_trackLength;
ResetBends();
long endTime = GETTIMEMS();
m_lastLapTime = endTime - m_lapStartTime;
if(m_lastLapTime < m_bestLapTime)
m_bestLapTime = m_lastLapTime;
m_lapStartTime = endTime;
if(m_lap[0] == m_numberOfLaps) //race over
{
m_raceTime = endTime - (m_raceStartTime + 4000);
m_bRace_over = TRUE;
}
else
DrawLapNum();
}
for(int i = 0; i < NUM_PARTS; i++)
{
if(m_partsWear[i] > 63 << 16)
m_partsWear[i] = 63 << 16;
}
} //end if(m_bRace_over)
}
/*===============================================================================
METHOD: DrawPlayer
=============================================================================== */
void GameFrame:: DrawPlayer()
{
int frame,smokeFrame;
int x;
int slideTime;
boolean bFlip=FALSE;
x=m_canvasW>>1;
x+=m_xPos[0]>>17; //extra shift because bike windows to edge of screen
smokeFrame=-1;
if(m_bCrashing)
{
frame=(int)(m_currentMillisecs-m_crashTime)>>7;
if(frame>15)
{
m_bCrashing=FALSE;
m_lean=0;
m_drag=0;
m_revs=0;
m_speed[0]=0;
m_xPos[0]=0;
m_gear[0]=0;
}
if(frame>=3) //do biker on floor as well
{
DrawBike(x+(m_crashX>>21),m_canvasH-(m_crashY>>23),10,m_pData->playerBikeOffsets,m_pFrontend->m_pPng[PNG_PLAYER_BIKE]);
m_crashY+=m_crashSpeed;
if(m_xPos[0]>0)
m_crashX-=m_crashSpeed;
else
m_crashX+=m_crashSpeed;
m_crashSpeed-=(m_crashSpeed>>3);
frame=9; //the bike without it's rider
}
else
frame+=6; //to the crash frames
}
else if(m_bDoingPowerSlide)
{
if(m_lean>0)
bFlip=TRUE;
frame=11;
slideTime=(int)(m_currentMillisecs-m_powerSlideStart);
//YingZ: Debug, creash very quick
if(slideTime>3000)
{
if(!m_bRace_over) // Just to be extra safe if we just about to crash when crossing finishing line
{
Crash(m_xPos[0]);
frame=6;
}
m_bWobbledLastTime=FALSE;
}
else if(slideTime<0x200 || slideTime>2000) //smoke and wobble 1 second before,smoke at start
{
smokeFrame=(slideTime&0x128)>>3;
//wobble if at end
if(slideTime>2000)
{
if(m_bWobbledLastTime)
m_bWobbledLastTime=FALSE;
else
{
m_bWobbledLastTime=TRUE;
frame=12;
}
}
}
}
else
{
frame=((m_lean+0x3000)>>15)+5;
if(frame>5)
{
frame=10-frame;
bFlip=TRUE;
}
}
//YingZ: Brew API does not support image flipping, so we use 2 sets of bitmap for bikes (Left/ Right flip)
if(!bFlip)
DrawBike(x,m_canvasH-3,frame,m_pData->playerBikeOffsets,m_pFrontend->m_pPng[PNG_PLAYER_BIKE]);
else
DrawBike(x,m_canvasH-3,frame,m_pData->playerBikeOffsets,m_pFrontend->m_pPng[PNG_PLAYER_BIKE_FLIP]);
if(smokeFrame!=-1)
{
//smoke
m_pGraph->SetBitmapClip(x-8,0,16,m_canvasH);
m_pGraph->DrawImage(m_pFrontend->m_pPng[PNG_SMOKE],x-smokeFrame-8,m_canvasH-15);
}
}
/*===============================================================================
METHOD: DrawBike
=============================================================================== */
void GameFrame:: DrawBike(int x,int y,int frame,short* pOffset,IImage* im)
{
int w,h;
int drawOffsetX, drawOffsetY;
frame*=6;
//YingZ: Brew API does not support image flipping, so we use 2 sets of bitmap for bikes (Left/ Right flip)
x-=pOffset[frame++];
y-=pOffset[frame++];
w=pOffset[frame++];
h=pOffset[frame++];
drawOffsetX=pOffset[frame++];
drawOffsetY=pOffset[frame++];
m_pGraph->SetBitmapClip(x,y,w,h);
//IIMAGE_SetOffset(im,drawOffsetX,drawOffsetY);
//An alternative is to SetBitmapClip is to use IIMAGE_SetDrawSize
//maybe worth while bench marking to see which is faster
//IIMAGE_SetDrawSize(im, w,h);
//IIMAGE_SetOffset(im,drawOffsetX,drawOffsetY);
//DrawImage(im,x,y);
m_pGraph->DrawImage(im,x-drawOffsetX,y-drawOffsetY);
}
/*===============================================================================
METHOD: Crash
=============================================================================== */
void GameFrame::Crash(int pos)
{
if(m_speed[0] < m_gearSpeeds[0][3])
{
LoseSpeed();
m_xPos[0] = pos;
if(pos < 0 && m_lean < 0)
m_lean = 0;
else if(pos > 0 && m_lean > 0)
m_lean = 0;
//lots more wear on bike when in grass
m_partsWear[0] += (m_speed[0]) >> 15; //tyres
m_partsWear[1] += (m_speed[0]) >> 15; //suspension
m_partsWear[2] += (m_speed[0]) >> 16; //exhaust
m_partsWear[3] += (m_speed[0]) >> 16; //engine
}
else
{
m_bCrashing = TRUE;
m_crashTime = m_currentMillisecs;
m_bDoingPowerSlide = FALSE;
m_crashSpeed = m_speed[0] >> 2;
m_crashX = 0;
m_crashY = 0;
//BIG damage
m_partsWear[0] += 5 << 16; //tyres
m_partsWear[1] += 7 << 16; //suspension
m_partsWear[2] += 6 << 16; //exhaust
m_partsWear[3] += 8 << 16; //engine
RecalcTopSpeed();
}
}
/*===============================================================================
METHOD: Collision
=============================================================================== */
void GameFrame::Collision()
{
int b;
int myPos;
int zDist;
myPos = m_zPos[0] + (m_lap[0] * m_trackLength);
for (b = 1; b < NUM_BIKES; b++)
{
zDist = myPos - (m_zPos[b] + (m_lap[b] * m_trackLength));
if(zDist < 128 && zDist > -128) //collision
{
int temp = m_xPos[0] - m_xPos[b];
temp = ABS(temp);
if(temp < 0xe0000)
{
if(zDist<-64) //I've hit somebody from behind
{
m_zPos[b]+= 500; //Bounce the opponent I hit forward a bit
if(m_gear[0] > 3) // If we are in higher gears, auto shift down as a penalty
m_gear[0]--;
}
else //bike has hit me from behind
{
m_zPos[0]+= 100;
m_speed[b] -= 0x2d0000;
if(m_speed[b] < 0x100000)
m_speed[b] = 0x100000;
}
//reverse lean if we've collided
if(m_lean != 0)
{
m_lean = 0 - (m_lean >> 1);
m_xPos[0] += m_lean;
}
else //random bounce to side
m_lean = (m_pRandom->NextInt() & 0xffff) - 0x6000;
}
}
}
}
/*===============================================================================
METHOD: LoseSpeed
=============================================================================== */
void GameFrame::LoseSpeed()
{
int g;
m_speed[0] -= 0x20000;
if(m_speed[0] < (40 << 16))
m_speed[0] = 40 << 16;
//auto change gears
for(g = 0; g < 6; g++)
{
if(m_speed[0] - m_gearSpeeds[0][g] < 0)
{
m_gear[0] = g;
break;
}
}
}
/*===============================================================================
METHOD: CalcRacePosition
=============================================================================== */
void GameFrame::CalcRacePosition(int bike)
{
int real;
real = m_zPos[bike] + (m_trackLength * m_lap[bike]);
m_racePos[bike] = 1;
for(int i = 0; i < NUM_BIKES; i++)
{
if(i != bike)
{
if(real < m_zPos[i] + (m_trackLength * m_lap[i]))
m_racePos[bike]++;
}
}
}
/*===============================================================================
METHOD: CalcGearSpeeds
=============================================================================== */
void GameFrame::CalcGearSpeeds(int bike)
{
int speed;
int skill;
int p;
speed = m_maxSpeed << 18;
if(bike != 0)
{
skill = (bike - 1) >> 1; //skill of 0-2
//always make person gambling better. He's motivated you see ;0)
if(bike == m_pFrontend->m_myBettor - 1 && skill > 0)
skill--;
switch(skill)
{
case 0:
p = (m_pRandom->NextInt() & 7) + 95; //percentage of player speed
break;
case 1:
p = (m_pRandom->NextInt() & 15) + 85; //percentage of player speed
break;
default:
p = (m_pRandom->NextInt() & 15) + 75; //percentage of player speed
break;
}
speed = (speed / 100) * p;
}
for(int i = 0; i < 6; i++)
m_gearSpeeds[bike][i] = (speed / 100) * m_pData->gearPercent[i];
}
/*===============================================================================
METHOD: GenCPUCharacters
=============================================================================== */
void GameFrame::GenCPUCharacters(int player)
{
m_character[0] = player;
for(int i = 1; i < NUM_BIKES; i++)
{
if(i - 1 < player)
m_character[i] = i - 1;
else
m_character[i] = i;
}
}
/*===============================================================================
METHOD: DrawBikes
=============================================================================== */
void GameFrame::DrawBikes()
{
int i;
int x;
int z;
int zReal;
int sprFrame;
int trackZ;
int bike;
boolean bFlip;
bFlip=FALSE;
trackZ=m_zPos[0]-64;
trackZ&=m_trackLength;
m_drawIdx=0;
//work out which to draw
for(i=0;i<NUM_BIKES;i++)
{
zReal=m_zPos[i]-trackZ;
//deal with wrapping
if(zReal<-512)
zReal+=m_trackLength;
if(zReal>-512 && zReal<VISIBLE_ROAD_LENGTH_FRAC)
{
m_drawOrder[m_drawIdx]=i;
m_drawPos[m_drawIdx]=zReal;
m_drawIdx++;
}
}
SortDrawOrder();
for(i=0;i<m_drawIdx;i++)
{
zReal=m_drawPos[i];
if(zReal<0)
zReal=0;
bike=m_drawOrder[i];
if(m_pFrontend->m_currentTrack==8) //canyon
{
m_leftCanyonIdx=DrawCanyonScenery(m_leftCanyonIdx,m_sceneryX,zReal);
m_rightCanyonIdx=DrawCanyonScenery(m_rightCanyonIdx,m_sceneryZ,zReal);
}
if(bike==0)
DrawPlayer();
else
{
int scale=m_distTab[zReal>>5];
int idx=(1023-m_pData->roadTable[1023-(zReal>>2)])>>4;
x=scale*(m_xPos[bike]>>16);
x>>=10;
x+=128+m_xDrawTab[idx];
idx+=3;
if(idx>63)
idx=63;
z=m_zDrawTab[idx];
sprFrame=(zReal>>8)&0xe;
if(m_onBend[bike]==1)
bFlip=TRUE;
else if(m_onBend[bike]==0)
sprFrame++;
if(m_drawPos[i]<0)
z-=m_drawPos[i]>>4;
//YingZ: Brew API does not support image flipping, so we use 2 sets of bitmap for bikes (Left/ Right flip)
if(!bFlip)
DrawBike(x,z,sprFrame,m_pData->oppoBikeOffsets,m_pFrontend->m_pPng[PNG_CPU_BIKE]);
else
DrawBike(x,z,sprFrame,m_pData->oppoBikeOffsets,m_pFrontend->m_pPng[PNG_CPU_BIKE_FLIP]);
}
}
//draw any scraps of canyon sides
if(m_pFrontend->m_currentTrack==8) //canyon
{
m_leftCanyonIdx=DrawCanyonScenery(m_leftCanyonIdx,m_sceneryX,-100);
m_rightCanyonIdx=DrawCanyonScenery(m_rightCanyonIdx,m_sceneryZ,-100);
}
}
/*===============================================================================
METHOD: SortDrawOrder
=============================================================================== */
void GameFrame::SortDrawOrder()
{
boolean done;
int tmp;
do
{
done=TRUE;
for(int i=0;i<m_drawIdx-1;i++)
{
if(m_drawPos[i]<m_drawPos[i+1])
{
tmp=m_drawPos[i];
m_drawPos[i]=m_drawPos[i+1];
m_drawPos[i+1]=tmp;
tmp=m_drawOrder[i];
m_drawOrder[i]=m_drawOrder[i+1];
m_drawOrder[i+1]=tmp;
done=FALSE;
}
}
}while(!done);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -