📄 cgame.cpp
字号:
TInt speed = iCarSpeed;
if( speed < 0 ) speed = -speed;
switch( iCameraMode )
{
case ECameraBehind:
case ECameraInCar:
{
TVertex camPos;
if( iCameraMode == ECameraBehind )
{
camPos = TVertex( 5000 + speed * 25, -( 3000 + speed * 15 ), 0 );
iRender->SetCameraAngle( TVertex( 300, -( iCarAngle - KSinTableSize/4 ), 0 ) );
}
else
{
camPos = TVertex( 500, -500, 0 );
iRender->SetCameraAngle( TVertex( -iCarTilt/5, -( iCarAngle - KSinTableSize/4 ), -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 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;
//
// Adjust throttle with key presses
// arrow up and '2' are throttle
// arrow down and '8' are reverse ( brake )
//
if( aKey[ EStdKeyUpArrow ] || aKey[ '2' ] || aKey[ EStdKeyDevice8 ] )
{
iThrottle = 1;
}
else if( aKey[ EStdKeyDownArrow ] || aKey[ '8' ] || aKey[ EStdKeyDevice9 ] )
{
iThrottle = -1;
}
else
{
iThrottle = 0;
}
//
// Turn car with steering wheel
//
iCarAngleSpeed = ( -iSteerAngle * iCarSpeed ) / KCarTurnDivider;
iCarAngle += iCarAngleSpeed;
//
// Adjust steering wheel with key presses
// arrow left and '4' are left turn
// arrow right and '6' are right turn
//
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 throttle
//
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;
}
}
//
// 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 )
{
CPolygonObject* o = CPolygonObject::NewL( i3DBase, 100,100 );
TInt16* cos = i3DBase->CosTable();
TInt16* sin = i3DBase->SinTable();
TInt i;
TInt z1 = -aWidth/2;
TInt z2 = aWidth/2;
o->AddVertex( TVertex( 0,0,0 ) );
const TInt KTexturePixels = 128;
for( i=0; i<aNumPoints; i++ )
{
TInt a1 = KSinTableSize * i / aNumPoints;
TInt a2 = ( a1 + KSinTableSize / aNumPoints ) & (KSinTableSize-1);
TInt x1 = ( aRadius * cos[ a1 ] ) >> KShift;
TInt y1 = ( aRadius * sin[ a1 ] ) >> KShift;
TInt x2 = ( aRadius * cos[ a2 ] ) >> KShift;
TInt y2 = ( aRadius * sin[ a2 ] ) >> KShift;
o->AddVertex( TVertex( x1,y1,z1 ) );
o->AddVertex( TVertex( x1,y1,z2 ) );
TInt n1 = i*2;
TInt n2 = n1 + 1;
TInt n3 = n1 + 2;
TInt n4 = n1 + 3;
if( n3 >= aNumPoints*2 ) n3 -= aNumPoints*2;
if( n4 >= aNumPoints*2 ) n4 -= aNumPoints*2;
n1 += 1;
n2 += 1;
n3 += 1;
n4 += 1;
o->AddFace( TFace( n1,n2,n3, 128,0, 255,0, 128,128 ) );
o->AddFace( TFace( n3,n2,n4, 128,128, 255,0, 255,128 ) );
// calculate texture pixel positions
// for wheel rim
TInt tx1 = KTexturePixels/2 + x1 * ( KTexturePixels/2-1 ) / aRadius;
TInt ty1 = KTexturePixels/2 + y1 * ( KTexturePixels/2-1 ) / aRadius;
TInt tx2 = KTexturePixels/2 + x2 * ( KTexturePixels/2-1 ) / aRadius;
TInt ty2 = KTexturePixels/2 + y2 * ( KTexturePixels/2-1 ) / aRadius;
o->AddFace( TFace( n1,n3,0, tx1,ty1, tx2,ty2, 64,64 ) );
}
return o;
}
CPolygonObject* CGame::CreateObject( const TInt* aVertexData, const TInt* aFaceData,
TInt aNumVertices, TInt aNumFaces,
const TPoint& aTexOffset, TInt aTexMul )
{
// leave some extra room for vertices and polygons
// otherwise renderer might not have enough space
// after clipping
CPolygonObject* o = CPolygonObject::NewL( i3DBase, aNumVertices*2+10, aNumFaces*2+10 );
TInt n=0;
TInt i;
for( i=0; i<aNumVertices; i++ )
{
o->AddVertex( TVertex( aVertexData[ n + 0 ],
aVertexData[ n + 1 ],
aVertexData[ n + 2 ]
) );
n += 3;
}
n=0;
for( i=0; i<aNumFaces; i++ )
{
o->AddFace( TFace( aFaceData[ n + 0 ],
aFaceData[ n + 1 ],
aFaceData[ n + 2 ],
aFaceData[ n + 3 ]*aTexMul+aTexOffset.iX,
aFaceData[ n + 4 ]*aTexMul+aTexOffset.iY,
aFaceData[ n + 5 ]*aTexMul+aTexOffset.iX,
aFaceData[ n + 6 ]*aTexMul+aTexOffset.iY,
aFaceData[ n + 7 ]*aTexMul+aTexOffset.iX,
aFaceData[ n + 8 ]*aTexMul+aTexOffset.iY
) );
n += 9;
}
return o;
}
void CGame::DrawText( CPolygonObject* aObject, const TDesC8& aStr )
{
TInt n = aStr.Length();
// reserve space for polygons in 3D-objects
aObject->Reset( n*4, n*3 );
TInt x = 0;
TInt y = 0;
// default font size in 3D-space
const TInt size = 500;
// go trough whole string
for( TInt i=0; i<n; i++ )
{
TInt c = aStr[ i ];
// check for line feed character:
if( c == '\n' )
{
x = 0;
y++;
}
else
{
TInt xx = x * size;
TInt yy = y * size;
TInt v1 = aObject->AddVertex( TVertex( xx, yy, 0 ) );
TInt v2 = aObject->AddVertex( TVertex( xx + size, yy, 0 ) );
TInt v3 = aObject->AddVertex( TVertex( xx + size, yy + size, 0 ) );
TInt v4 = aObject->AddVertex( TVertex( xx, yy + size, 0 ) );
// fonts are in 16x16 array in bitmap
// first 16 characters are on first line
// next 16 characters on second line and so on...
TInt tx = c & 15;
TInt ty = c >> 4;
// fonts are 16 pixels high and wide
// calculate top left ( x1, y1 ) and
// bottom right( x2, y2 ) pixel positions
// for current font
TInt x1 = tx * 16;
TInt y1 = ty * 16;
TInt x2 = x1 + 15;
TInt y2 = y1 + 15;
// each visible font consists of two triangles
// which make a textured rectangle with font picture
aObject->AddFace( TFace( v1,v2,v3, x1,y1, x2,y1, x2,y2 ) );
aObject->AddFace( TFace( v1,v3,v4, x1,y1, x2,y2, x1,y2 ) );
x++;
}
}
aObject->Init();
}
TInt CGame::PolygonCount()
{
return i3DBase->PolygonCount();
}
void CGame::Command( TInt aCommand )
{
switch( aCommand )
{
case EExample3DCamera1:
iCameraMode = ECameraBehind;
break;
case EExample3DCamera2:
iCameraMode = ECameraInCar;
break;
case EExample3DCamera3:
iCameraMode = ECameraSouth;
break;
case EExample3DCamera4:
iCameraMode = ECameraTV1;
break;
case EExample3DCamera5:
iCameraMode = ECameraTV2;
break;
case EExample3DCamera6:
iCameraMode = ECameraTV3;
break;
case EExample3DCamera7:
iCameraMode = ECameraTV4;
break;
case EExample3DCameraToggle:
iCameraMode++;
if( iCameraMode == ECameraNone )
{
iCameraMode = 0;
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -