⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgame.cpp

📁 一个基于symbian s60 3rd 的3D汽车游戏演示程序,模拟器上编译通过。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
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 + -