📄 cgame.cpp
字号:
void CGame::Draw( const TBitmap& aScreen )
{
if( aScreen.iSize != iScreen.iSize )
{
// calculate perspective:
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
float xmin, xmax, ymin, ymax;
TInt lens = 512;
const float zNear = 0.1f;
const float zFar = 500.0f;
xmax = zNear * 0.5f * aScreen.iSize.iWidth / lens;
xmin = -xmax;
ymax = zNear * 0.5f * aScreen.iSize.iHeight / lens;
ymin = -ymax;
glFrustumf( xmin, xmax, ymin, ymax, (float)zNear, (float)zFar );
glMatrixMode( GL_MODELVIEW );
glViewport( 0, 0, aScreen.iSize.iWidth, aScreen.iSize.iHeight );
TRect rect(0, 0, aScreen.iSize.iWidth, aScreen.iSize.iHeight);
i3DBase->InitFrustum( aScreen.iSize );
}
iScreen = aScreen;
/* clear */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
TInt ang = iCarAngleSpeed*5;
TInt carAngle = ang + iCarAngle;
// calculate wheel positions in space
TVertex v;
v = TVertex( -500, -KRearWheelRadius/2, 350 );
v = i3DBase->RotateY( v, carAngle );
v += iCarPosition;
iRender->SetObjectPosition( 0, v );
v = TVertex( 500, -KFrontWheelRadius/2, 300 );
v = i3DBase->RotateY( v, carAngle );
v += iCarPosition;
iRender->SetObjectPosition( 1, v );
v = TVertex( -500, -KRearWheelRadius/2, -350 );
v = i3DBase->RotateY( v, carAngle );
v += iCarPosition;
iRender->SetObjectPosition( 2, v );
v = TVertex( 500, -KFrontWheelRadius/2, -300 );
v = i3DBase->RotateY( v, carAngle );
v += iCarPosition;
iRender->SetObjectPosition( 3, v );
// turn wheels to right direction ( car's direction )
// add steering angle to front wheels
// also turn wheels by iCarPos
iRender->SetObjectAngle( 0, TVertex( 0, carAngle + ( KSinTableSize/2 ), -iCarPos*2 ) );
iRender->SetObjectAngle( 1, TVertex( 0, -iSteerAngle*4 + carAngle + ( KSinTableSize/2 ), -iCarPos*3 ) );
iRender->SetObjectAngle( 2, TVertex( 0, carAngle, iCarPos*2 ) );
iRender->SetObjectAngle( 3, TVertex( 0, -iSteerAngle*4 + carAngle, iCarPos*3 ) );
if( iCarSpeed < 0 ) ang = -ang;
// tilt car
iRender->SetObjectAngle( 4, TVertex( ang, carAngle, -iCarTilt/5 ) );
// and set car position in space
iRender->SetObjectPosition( 4, iCarPosition + TVertex( 0,-KRideHeight, 0 ) );
// calculate camera position
TInt speed = iCarSpeed;
if( speed < 0 ) speed = -speed;
switch( iCameraMode )
{
case ECameraBehind:
case ECameraInCar:
{
#ifdef SENSOR_API_SUPPORT_ENABLED
// Turn camera angle according to accelerometer data if using sensor steering mode
if ( iSensorSteeringMode )
{
TReal r;
Math::ATan( r, iSensorDataY, -iSensorDataX );
r = r * KSinTableSize/2.0 / KPi;
TInt32 i;
Math::Int( i, r );
iCameraAngle = i;
}
#endif //SENSOR_API_SUPPORT_ENABLED
TVertex camPos;
if( iCameraMode == ECameraBehind )
{
camPos = TVertex( 5000 + speed * 25, -( 3000 + speed * 15 ), 0 );
//iRender->SetCameraAngle( TVertex( 300, -( iCarAngle - KSinTableSize/4 ), 0 ) );
iRender->SetCameraAngle( TVertex( 300, -( iCarAngle - KSinTableSize/4 ), iCameraAngle ) );
}
else
{
camPos = TVertex( 500, -500, 0 );
//iRender->SetCameraAngle( TVertex( -iCarTilt/5, -( iCarAngle - KSinTableSize/4 ), -ang ) );
iRender->SetCameraAngle( TVertex( -iCarTilt/5, -( iCarAngle - KSinTableSize/4 ), iCameraAngle - ang ) );
}
camPos = i3DBase->RotateY( camPos, ( iCarAngle + KSinTableSize/2 ) );
iRender->SetCameraPosition( iCarPosition + camPos );
break;
}
case ECameraSouth:
{
TVertex camPos( 0, -( 6000 + speed * 15 ), -( 10000 + speed * 25 ) );
iRender->SetCameraPosition( iCarPosition + camPos );
iRender->SetCameraAngle( TVertex( 300, 0, 0 ) );
break;
}
case ECameraTV1:
case ECameraTV2:
case ECameraTV3:
case ECameraTV4:
{
TVertex camPos;
switch( iCameraMode )
{
case ECameraTV1:
camPos = TVertex( KTileSize*10,-15000, KTileSize*1 );
break;
case ECameraTV2:
camPos = TVertex( KTileSize*10,-15000, KTileSize*10 );
break;
case ECameraTV3:
camPos = TVertex( KTileSize*15,-5000, KTileSize*15 );
break;
case ECameraTV4:
camPos = TVertex( KTileSize*8,-1000, KTileSize*16 );
break;
}
iRender->SetCameraPosition( camPos );
camPos -= iCarPosition;
if( camPos.iX == 0 ) camPos.iX = 1;
if( camPos.iY == 0 ) camPos.iY = 1;
TReal r;
Math::ATan( r, camPos.iZ, camPos.iX );
r = r * KSinTableSize/2.0 / KPi;
TInt32 a1;
Math::Int( a1, r );
a1 = -KSinTableSize / 4 -a1;
TReal n1 = camPos.iZ;
TReal n2 = camPos.iX;
Math::Sqrt( r, n1*n1 + n2*n2 );
Math::ATan( r, r, camPos.iY );
r = r * KSinTableSize/2.0 / KPi;
TInt32 a2;
Math::Int( a2, r );
a2 = -KSinTableSize / 4 + a2;
iRender->SetCameraAngle( TVertex( a2,a1,0 ) );
break;
}
}
// create some text about statistics to draw
TBuf8< 100 >text;
text.Format( _L8("%d FPS\n%d Tris"), iFps->Fps(), PolygonCount() );
DrawText( i3dText, text );
// and draw everything
iRender->Draw( aScreen );
// we really want to draw over everything
// so in OpenGL ES disable z-buffer
glDisable( GL_DEPTH_TEST );
// Draw statistics over everything
// on top left corner
TInt z = 32; // smaller z is nearer ( bigger ) screen
TInt i = 1 << KShift;
TMatrix m( i, 0, 0, -aScreen.iSize.iWidth/2 * z,
0, i, 0, -aScreen.iSize.iHeight/2 * z,
0, 0, i, z * i );
i3dText->Draw( aScreen, &m );
glEnable (GL_DEPTH_TEST);
// Update Frames Per Second counter
iFps->Update();
}
void CGame::Move( TUint8* aKey )
{
// check keys and update physics
TInt carLastSpeed = iCarSpeed;
//
// Move car to car angle direction by car speed
//
iCarPositionAdd = TVertex( iCarSpeed,0,0 );
iCarPositionAdd = i3DBase->RotateY( iCarPositionAdd, iCarAngle & (KSinTableSize-1) );
iCarPosition += iCarPositionAdd;
// VERY simple collision detection from tilemap
TBool collision = EFalse;
TInt tileX = ( iCarPosition.iX + KTileSize/2 ) / KTileSize;
TInt tileY = ( iCarPosition.iZ + KTileSize/2 ) / KTileSize;
// first check we stay on map:
if( ( tileX < 1 ) || ( tileX >= KMapWidth-1 ) ||
( tileY < 1 ) || ( tileY >= KMapHeight-1 ) )
{
collision = ETrue;
}
// then check collisions against buildings
TInt tile = KMap[ tileY ][ tileX ];
if( tile == 'a' ) // if tile is a building
{
collision = ETrue;
}
if( collision )
{
// move back
iCarPosition -= iCarPositionAdd;
// and stop
iCarSpeed = 0;
}
//
// Move car position with car speed
// car position is used to rotate wheels
//
iCarPos += iCarSpeed;
//
// Turn car with steering wheel
//
iCarAngleSpeed = ( -iSteerAngle * iCarSpeed ) / KCarTurnDivider;
iCarAngle += iCarAngleSpeed;
//
// Adjust steering wheel by accelerometer data if sensor mode is enabled
//
// OR
//
// by key presses if sensor mode is disabled
// arrow left and '4' are left turn
// arrow right and '6' are right turn
//
if ( iSensorSteeringMode )
{
#ifdef SENSOR_API_SUPPORT_ENABLED
TReal r;
Math::ATan( r, -iSensorDataY, -iSensorDataX );
r = r * 1.5 * KSteerLimit / KPi;
TInt32 i;
Math::Int( i, r );
iSteerAngle = i;
#endif //SENSOR_API_SUPPORT_ENABLED
}
else
{
if( aKey[ EStdKeyLeftArrow ] || aKey[ '4' ] || aKey[ EStdKeyDevice6 ] )
{
iSteerAngle -= KSteeringSpeed;
}
else if( aKey[ EStdKeyRightArrow ] || aKey[ '6' ] || aKey[ EStdKeyDevice7 ] )
{
iSteerAngle += KSteeringSpeed;
}
else
{
if( iSteerAngle > 0 ) iSteerAngle -= KSteeringSpeed;
if( iSteerAngle < 0 ) iSteerAngle += KSteeringSpeed;
}
}
//
// Adjust speed by accelerometer data if sensor mode is enabled
//
// OR
//
// by key presses if sensor mode is disabled
// arrow up and '2' are throttle
// arrow down and '8' are reverse ( brake )
//
if ( iSensorThrottleMode )
{
#ifdef SENSOR_API_SUPPORT_ENABLED
TReal r;
Math::ATan( r, -iSensorDataZ, -iSensorDataX );
r = r * 8 * KSteerLimit / KPi - 2 * KSteerLimit;
TInt32 i;
Math::Int( i, r );
iCarSpeed = i;
if ( iCarSpeed > 100 ) iCarSpeed = 100;
if ( iCarSpeed < -100 ) iCarSpeed = -100;
#endif //SENSOR_API_SUPPORT_ENABLED
}
else
{
if( aKey[ EStdKeyUpArrow ] || aKey[ '2' ] || aKey[ EStdKeyDevice8 ] )
{
iThrottle = 1;
}
else if( aKey[ EStdKeyDownArrow ] || aKey[ '8' ] || aKey[ EStdKeyDevice9 ] )
{
iThrottle = -1;
}
else
{
iThrottle = 0;
}
iCarSpeed += iThrottle;
if( iCarSpeed > 0 )
{
iCarSpeed -= iCarSpeed * iCarSpeed / KFriction;
}
if( iCarSpeed < 0 )
{
iCarSpeed += iCarSpeed * iCarSpeed / KFriction;
}
if( iThrottle == 0 )
{
if( iCarSpeed > 0 ) iCarSpeed -= 1;
if( iCarSpeed < 0 ) iCarSpeed += 1;
}
}
//
// Adjust steering wheel
//
if( iSteerAngle > KSteerLimit ) iSteerAngle = KSteerLimit;
if( iSteerAngle < -KSteerLimit ) iSteerAngle = -KSteerLimit;
//
// Adjust car tilting by speed changes
//
iCarTilt += ( iCarSpeed - carLastSpeed ) * KCarTiltForce;
if( iCarTilt > 0 )
{
iCarTilt -= ( iCarTilt * iCarTilt / KCarTiltSpringFactor );
if( iCarTilt < 0 ) iCarTilt = 0;
}
if( iCarTilt < 0 )
{
iCarTilt += ( iCarTilt * iCarTilt / KCarTiltSpringFactor );
if( iCarTilt > 0 ) iCarTilt = 0;
}
//
// Adjust camera angle with key presses
// '1' turns camera clockwise
// '3' turns camera counter-clockwise
//
if( aKey[ '1' ] )
{
iCameraAngle += 16;
}
else if ( aKey[ '3' ] )
{
iCameraAngle -= 16;
}
User::ResetInactivityTime();
}
//
// These functions demonstrate how to create 3D objects
// It should be easy to convert objects from your
// favourite 3D object file format to use in here
//
CPolygonObject* CGame::CreateWheel( TInt aRadius, TInt aWidth, TInt aNumPoints )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -