Пример #1
0
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);
}