void SpaceshipGame::update(long elapsedTime) { // Calculate elapsed time in seconds float t = (float)elapsedTime / 1000.0; if (!_finished) { _time += t; // Play the background track if (_backgroundSound->getState() != AudioSource::PLAYING) _backgroundSound->play(); } else { // Stop the background track if (_backgroundSound->getState() != AudioSource::STOPPED) _backgroundSound->stop(); _throttle = 0.0f; } // Set initial force due to gravity _force.set(0, -GRAVITATIONAL_FORCE); // While we are pushing/touching the screen, apply a push force vector based on the distance from // the touch point to the center of the space ship. if (_pushing) { // Get the center point of the space ship in screen coordinates Vector3 shipCenterScreen; _scene->getActiveCamera()->project(getViewport(), _shipGroupNode->getBoundingSphere().center, &shipCenterScreen.x, &shipCenterScreen.y); // Compute a screen-space vector between the center point of the ship and the touch point. // We will use this vector to apply a "pushing" force to the space ship, similar to what // happens when you hold a magnet close to an object with opposite polarity. Vector2 pushForce((shipCenterScreen.x - _pushPoint.x), -(shipCenterScreen.y - _pushPoint.y)); // Transform the vector so that a smaller magnitude emits a larger force and applying the // maximum touch distance. float distance = (std::max)(TOUCH_DISTANCE_MAX - pushForce.length(), 0.0f); pushForce.normalize(); pushForce.scale(distance * FORCE_SCALE); _force.add(pushForce); // Compute a throttle value based on our force vector, minus gravity Vector2 throttleVector(_force.x, _force.y + GRAVITATIONAL_FORCE); _throttle += throttleVector.length() / FORCE_MAX * t; } else { // Gradually decrease the throttle if (_throttle > 0.0f) { _throttle *= 1.0f - t; } } // Clamp the throttle _throttle = CLAMP(_throttle, 0.0f, 1.0f); // Update acceleration (a = F/m) _acceleration.set(_force.x / MASS, _force.y / MASS); // Update velocity (v1 = v0 + at) _velocity.x += _acceleration.x * t; _velocity.y += _acceleration.y * t; // Clamp velocity to its maximum range _velocity.x = CLAMP(_velocity.x, -VELOCITY_MAX, VELOCITY_MAX); _velocity.y = CLAMP(_velocity.y, -VELOCITY_MAX, VELOCITY_MAX); // Move the spaceship based on its current velocity (x1 = x0 + vt) _shipGroupNode->translate(_velocity.x * t, _velocity.y * t, 0); // Check for collisions handleCollisions(t); // Update camera updateCamera(); // Reset ship rotation _shipGroupNode->setRotation(_initialShipRot); // Apply ship tilt if (_force.x != 0 && fabs(_velocity.x) > 0.1f) { // Compute an angle based on the dot product between the force vector and the Y axis Vector2 fn; _force.normalize(&fn); float angle = MATH_RAD_TO_DEG(acos(Vector2::dot(Vector2(0, 1), fn))); if (_force.x > 0) angle = -angle; angle *= _throttle * t; _shipTilt += angle; _shipTilt = _shipTilt < -SHIP_TILT_MAX ? -SHIP_TILT_MAX : (_shipTilt > SHIP_TILT_MAX ? SHIP_TILT_MAX : _shipTilt); } else { // Interpolate tilt back towards zero when no force is applied _shipTilt = (_shipTilt + ((0 - _shipTilt) * t * 2.0f)); } _shipGroupNode->rotateZ(MATH_DEG_TO_RAD(_shipTilt)); if (_throttle > MATH_EPSILON) { // Apply ship spin _shipNode->rotateY(MATH_DEG_TO_RAD(SHIP_ROTATE_SPEED_MAX * t * _throttle)); // Play sound effect if (_spaceshipSound->getState() != AudioSource::PLAYING) _spaceshipSound->play(); // Set the pitch based on the throttle _spaceshipSound->setPitch(_throttle * SOUND_PITCH_SCALE); } else { // Stop sound effect _spaceshipSound->stop(); } // Modify ship glow effect based on the throttle _glowDiffuseParameter->setValue(Vector4(1, 1, 1, _throttle * ENGINE_POWER)); _shipSpecularParameter->setValue(SPECULAR - ((SPECULAR-2.0f) * _throttle)); }
void EntityManager::update() { m_isUpdating = true; handleCollisions(); // Update existing entities. for(std::list<Entity *>::iterator iter = m_entities.begin(); iter != m_entities.end(); iter++) { (*iter)->update(); if((*iter)->isExpired()) { *iter = NULL; } } m_isUpdating = false; // Add new entities. for(std::list<Entity *>::iterator iter = m_addedEntities.begin(); iter != m_addedEntities.end(); iter++) { addEntity(*iter); } // Clear new entities list. m_addedEntities.clear(); // Remove all NULL elements. m_entities.remove(NULL); // Walk the bullet list. for(std::list<Bullet *>::iterator iter = m_bullets.begin(); iter != m_bullets.end(); iter++) { if((*iter)->isExpired()) { delete *iter; *iter = NULL; } } m_bullets.remove(NULL); // Walk the enemies list. for(std::list<Enemy *>::iterator iter = m_enemies.begin(); iter != m_enemies.end(); iter++) { if((*iter)->isExpired()) { delete *iter; *iter = NULL; } } m_enemies.remove(NULL); // Walk the enemies list. for(std::list<BlackHole *>::iterator iter = m_blackHoles.begin(); iter != m_blackHoles.end(); iter++) { if((*iter)->isExpired()) { delete *iter; *iter = NULL; } } m_blackHoles.remove(NULL); }