in agdk/agde/endless-tunnel/endless-tunnel/Android/app/src/main/cpp/play_scene.cpp [285:407]
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);
}
}