void PlayScene::DoFrame()

in agdk/agdktunnel/app/src/main/cpp/play_scene.cpp [311:433]


void PlayScene::DoFrame() {
    float deltaT = mFrameClock.ReadDelta();
    float previousY = mPlayerPos.y;

    // clear screen
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // rotate the view matrix according to current roll angle
    glm::vec3 upVec = glm::vec3(-sin(mRollAngle), 0, cos(mRollAngle));

    // set up view matrix according to player's ship position and direction
    mViewMat = glm::lookAt(mPlayerPos, mPlayerPos + mPlayerDir, upVec);

    // render tunnel walls
    RenderTunnel();

    // render obstacles
    RenderObstacles();

    if (mMenu) {
        RenderMenu();
        // nothing more to do
        return;
    }

    // render HUD (lives, score, etc)
    RenderHUD();

    // deduct from the time remaining to remove a sign from the screen
    if (mSignText && mSignExpires) {
        mSignTimeLeft -= deltaT;
        if (mSignTimeLeft < 0.0f) {
            mSignText = NULL;
        }
    }

    // if a "saved checkpoint" sign pending? Can we show it right now?
    if (!mSignText && mCheckpointSignPending) {
        mCheckpointSignPending = false;
        ShowSign(S_CHECKPOINT_SAVED, SIGN_DURATION);
    }

    // did we already show the howto?
    if (!mShowedHowto && mDifficulty == 0) {
        mShowedHowto = true;
        ShowSign(S_HOWTO_WITHOUT_JOY, SIGN_DURATION);
    }

    // deduct from the time remaining on the blinking heart animation
    if (mBlinkingHeart && Clock() > mBlinkingHeartExpire) {
        mBlinkingHeart = false;
    }

    // update speed
    float targetSpeed = PLAYER_SPEED + PLAYER_SPEED_INC_PER_LEVEL * mDifficulty;
    float accel = mPlayerSpeed >= 0.0f ? PLAYER_ACCELERATION_POSITIVE_SPEED :
                  PLAYER_ACCELERATION_NEGATIVE_SPEED;
    if (mLives <= 0) {
        targetSpeed = 0.0f;
    }
    mPlayerSpeed = Approach(mPlayerSpeed, targetSpeed, deltaT * accel);

    // apply noise filter on steering
    mFilteredSteerX = (mFilteredSteerX * (NOISE_FILTER_SAMPLES - 1) + mShipSteerX)
                      / NOISE_FILTER_SAMPLES;
    mFilteredSteerZ = (mFilteredSteerZ * (NOISE_FILTER_SAMPLES - 1) + mShipSteerZ)
                      / NOISE_FILTER_SAMPLES;

    // move player
    if (mLives > 0) {
        float steerX = mFilteredSteerX, steerZ = mFilteredSteerZ;
        if (mSteering == STEERING_TOUCH) {
            // touch steering
            mPlayerPos.x = Approach(mPlayerPos.x, steerX, PLAYER_MAX_LAT_SPEED * deltaT);
            mPlayerPos.z = Approach(mPlayerPos.z, steerZ, PLAYER_MAX_LAT_SPEED * deltaT);
        } else if (mSteering == STEERING_JOY) {
            // joystick steering
            mPlayerPos.x += deltaT * steerX;
            mPlayerPos.z += deltaT * steerZ;
        }
    }
    mPlayerPos.y += deltaT * mPlayerSpeed;

    // make sure player didn't leave tunnel
    mPlayerPos.x = Clamp(mPlayerPos.x, PLAYER_MIN_X, PLAYER_MAX_X);
    mPlayerPos.z = Clamp(mPlayerPos.z, PLAYER_MIN_Z, PLAYER_MAX_Z);

    // shift sections if needed
    ShiftIfNeeded();

    // generate more obstacles!
    GenObstacles();

    // detect collisions
    DetectCollisions(previousY);

    // update ship's roll speed according to level
    static float roll_speeds[] = ROLL_SPEEDS;
    int count = sizeof(roll_speeds) / sizeof(float);
    float speed = roll_speeds[mDifficulty % count];
    mRollAngle += deltaT * speed;
    while (mRollAngle < 0) {
        mRollAngle += 2 * M_PI;
    }
    while (mRollAngle > 2 * M_PI) {
        mRollAngle -= 2 * M_PI;
    }

    // did the game expire?
    if (mLives <= 0 && Clock() > mGameOverExpire) {
        SceneManager::GetInstance()->RequestNewScene(new WelcomeScene());

    }

    // produce the ambient sound
    int soundPoint = (int) floor(mPlayerPos.y / (TUNNEL_SECTION_LENGTH / 3));
    if (soundPoint % 3 != 0 && soundPoint > mLastAmbientBeepEmitted) {
        mLastAmbientBeepEmitted = soundPoint;
        SfxMan::GetInstance()->PlayTone(soundPoint % 2 ? TONE_AMBIENT_0 : TONE_AMBIENT_1);
    }
}