Beispiel #1
0
void Game::shutdown()
{
    // Call user finalization.
    if (_state != UNINITIALIZED)
    {
        GP_ASSERT(_animationController);
        GP_ASSERT(_audioController);
        GP_ASSERT(_physicsController);
        GP_ASSERT(_aiController);

        Platform::signalShutdown();

		// Call user finalize
        finalize();

        // Call script finalize
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, finalize));

        // Destroy script target so no more script events are fired
        SAFE_DELETE(_scriptTarget);

		// Shutdown scripting system first so that any objects allocated in script are released before our subsystems are released
		_scriptController->finalize();

        unsigned int gamepadCount = Gamepad::getGamepadCount();
        for (unsigned int i = 0; i < gamepadCount; i++)
        {
            Gamepad* gamepad = Gamepad::getGamepad(i, false);
            SAFE_DELETE(gamepad);
        }

        _animationController->finalize();
        SAFE_DELETE(_animationController);

        _audioController->finalize();
        SAFE_DELETE(_audioController);

        _physicsController->finalize();
        SAFE_DELETE(_physicsController);
        _aiController->finalize();
        SAFE_DELETE(_aiController);
        
        ControlFactory::finalize();

        Theme::finalize();

        // Note: we do not clean up the script controller here
        // because users can call Game::exit() from a script.

        SAFE_DELETE(_audioListener);

        FrameBuffer::finalize();
        RenderState::finalize();

        SAFE_DELETE(_properties);

		_state = UNINITIALIZED;
    }
}
Beispiel #2
0
bool Game::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
{
    if (mouseEvent(evt, x, y, wheelDelta))
        return true;

    if (_scriptTarget)
        return _scriptTarget->fireScriptEvent<bool>(GP_GET_SCRIPT_EVENT(GameScriptTarget, mouseEvent), evt, x, y, wheelDelta);

    return false;
}
Beispiel #3
0
void Game::resizeEventInternal(unsigned int width, unsigned int height)
{
    // Update the width and height of the game
    if (_width != width || _height != height)
    {
        _width = width;
        _height = height;
        resizeEvent(width, height);
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, resizeEvent), width, height);
    }
}
Beispiel #4
0
void Transform::transformChanged()
{
    if (_listeners)
    {
        for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); ++itr)
        {
            TransformListener& l = *itr;
            GP_ASSERT(l.listener);
            l.listener->transformChanged(this, l.cookie);
        }
    }
    fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(Transform, transformChanged), dynamic_cast<void*>(this));
}
Beispiel #5
0
void Game::updateOnce()
{
    GP_ASSERT(_animationController);
    GP_ASSERT(_audioController);
    GP_ASSERT(_physicsController);
    GP_ASSERT(_aiController);

    // Update Time.
    static double lastFrameTime = getGameTime();
    double frameTime = getGameTime();
    float elapsedTime = (frameTime - lastFrameTime);
    lastFrameTime = frameTime;

    // Update the internal controllers.
    _animationController->update(elapsedTime);
    _physicsController->update(elapsedTime);
    _aiController->update(elapsedTime);
    _audioController->update(elapsedTime);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, update), elapsedTime);
}
Beispiel #6
0
void AnimationClip::onBegin()
{
    this->addRef();

    // Initialize animation to play.
    setClipStateBit(CLIP_IS_STARTED_BIT);
    if (_speed >= 0)
    {
        _elapsedTime = (Game::getGameTime() - _timeStarted) * _speed;

        if (_listeners)
            *_listenerItr = _listeners->begin();
    }
    else
    {
        _elapsedTime = _activeDuration + (Game::getGameTime() - _timeStarted) * _speed;

        if (_listeners)
            *_listenerItr = _listeners->end();
    }

    // Notify begin listeners if any.
    if (_beginListeners)
    {
        std::vector<Listener*>::iterator listener = _beginListeners->begin();
        while (listener != _beginListeners->end())
        {
            GP_ASSERT(*listener);
            (*listener)->animationEvent(this, Listener::BEGIN);
            listener++;
        }
    }

    // Fire script begin event
    fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(AnimationClip, clipBegin), this);

    this->release();
}
Beispiel #7
0
void AnimationClip::onEnd()
{
    this->addRef();

    _blendWeight = 1.0f;
    resetClipStateBit(CLIP_ALL_BITS);

    // Notify end listeners if any.
    if (_endListeners)
    {
        std::vector<Listener*>::iterator listener = _endListeners->begin();
        while (listener != _endListeners->end())
        {
            GP_ASSERT(*listener);
            (*listener)->animationEvent(this, Listener::END);
            listener++;
        }
    }

    // Fire script end event
    fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(AnimationClip, clipEnd), this);

    this->release();
}
Beispiel #8
0
void Game::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad)
{
    gamepadEvent(evt, gamepad);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, gamepadEvent), evt, gamepad);
}
Beispiel #9
0
void Game::gestureDropEventInternal(int x, int y)
{
    gestureDropEvent(x, y);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, gestureDropEvent), x, y);
}
Beispiel #10
0
void Game::gestureLongTapEventInternal(int x, int y, float duration)
{
    gestureLongTapEvent(x, y, duration);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, gestureLongTapevent), x, y, duration);
}
Beispiel #11
0
void Game::gesturePinchEventInternal(int x, int y, float scale)
{
    gesturePinchEvent(x, y, scale);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, gesturePinchEvent), x, y, scale);
}
Beispiel #12
0
void Game::gestureSwipeEventInternal(int x, int y, int direction)
{
    gestureSwipeEvent(x, y, direction);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, gestureSwipeEvent), x, y, direction);
}
Beispiel #13
0
void Game::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    touchEvent(evt, x, y, contactIndex);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, touchEvent), evt, x, y, contactIndex);
}
Beispiel #14
0
void Game::keyEventInternal(Keyboard::KeyEvent evt, int key)
{
    keyEvent(evt, key);
    if (_scriptTarget)
        _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, keyEvent), evt, key);
}
Beispiel #15
0
void Game::frame()
{
    if (!_initialized)
    {
        // Perform lazy first time initialization
        initialize();
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, initialize));
        _initialized = true;

        // Fire first game resize event
        Platform::resizeEventInternal(_width, _height);
    }

	static double lastFrameTime = Game::getGameTime();
	double frameTime = getGameTime();

    // Fire time events to scheduled TimeListeners
    fireTimeEvents(frameTime);

    if (_state == Game::RUNNING)
    {
        GP_ASSERT(_animationController);
        GP_ASSERT(_audioController);
        GP_ASSERT(_physicsController);
        GP_ASSERT(_aiController);

        // Update Time.
        float elapsedTime = (frameTime - lastFrameTime);
        lastFrameTime = frameTime;

        // Update the scheduled and running animations.
        _animationController->update(elapsedTime);

        // Update the physics.
        _physicsController->update(elapsedTime);

        // Update AI.
        _aiController->update(elapsedTime);

        // Update gamepads.
        Gamepad::updateInternal(elapsedTime);

        // Application Update.
        update(elapsedTime);

        // Update forms.
        Form::updateInternal(elapsedTime);

        // Run script update.
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, update), elapsedTime);

        // Audio Rendering.
        _audioController->update(elapsedTime);

        // Graphics Rendering.
        render(elapsedTime);

        // Run script render.
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, render), elapsedTime);

        // Update FPS.
        ++_frameCount;
        if ((Game::getGameTime() - _frameLastFPS) >= 1000)
        {
            _frameRate = _frameCount;
            _frameCount = 0;
            _frameLastFPS = getGameTime();
        }
    }
	else if (_state == Game::PAUSED)
    {
        // Update gamepads.
        Gamepad::updateInternal(0);

        // Application Update.
        update(0);

        // Update forms.
        Form::updateInternal(0);

        // Script update.
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, update), 0);

        // Graphics Rendering.
        render(0);

        // Script render.
        if (_scriptTarget)
            _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, render), 0);
    }
}
Beispiel #16
0
bool AnimationClip::update(float elapsedTime)
{
    if (isClipStateBitSet(CLIP_IS_PAUSED_BIT))
    {
        return false;
    }

    if (isClipStateBitSet(CLIP_IS_MARKED_FOR_REMOVAL_BIT))
    {
        // If the marked for removal bit is set, it means stop() was called on the AnimationClip at some point
        // after the last update call. Reset the flag, and return true so the AnimationClip is removed from the
        // running clips on the AnimationController.
        onEnd();
        return true;
    }

    if (!isClipStateBitSet(CLIP_IS_STARTED_BIT))
    {
        // Clip is just starting
        onBegin();
    }
    else
    {
        // Clip was already running
        _elapsedTime += elapsedTime * _speed;

        if (_repeatCount == REPEAT_INDEFINITE && _elapsedTime <= 0)
        {
            // Elapsed time is moving backwards, so wrap it back around the end when it falls below zero
            _elapsedTime = _activeDuration + _elapsedTime;

            // TODO: account for _loopBlendTime
        }
    }

    // Current time within a loop of the clip
    float currentTime = 0.0f;

    // Check to see if clip is complete.
    if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0.0f && _elapsedTime >= _activeDuration) || (_speed <= 0.0f && _elapsedTime <= 0.0f)))
    {
        // We finished our active duration (including repeats), so clamp to our end value.
        resetClipStateBit(CLIP_IS_STARTED_BIT);

        // Ensure we end off at the endpoints of our clip (-speed==0, +speed==_duration)
        currentTime = _speed < 0.0f ? 0.0f : _duration;
    }
    else
    {
        // If _duration == 0, we have a "pose". Just set currentTime to 0.
        if (_duration == 0)
        {
            currentTime = 0.0f;
        }
        else
        {
            // Animation is running normally.
            currentTime = fmodf(_elapsedTime, _duration + _loopBlendTime);
        }
    }

    // Notify any listeners of Animation events.
    if (_listeners)
    {
        GP_ASSERT(_listenerItr);

        if (_speed >= 0.0f)
        {
            while (*_listenerItr != _listeners->end() && _elapsedTime >= (long) (**_listenerItr)->_eventTime)
            {
                GP_ASSERT(_listenerItr);
                GP_ASSERT(**_listenerItr);
                GP_ASSERT((**_listenerItr)->_listener);

                (**_listenerItr)->_listener->animationEvent(this, Listener::TIME);
                ++(*_listenerItr);
            }
        }
        else
        {
            while (*_listenerItr != _listeners->begin() && _elapsedTime <= (long) (**_listenerItr)->_eventTime)
            {
                GP_ASSERT(_listenerItr);
                GP_ASSERT(**_listenerItr);
                GP_ASSERT((**_listenerItr)->_listener);

                (**_listenerItr)->_listener->animationEvent(this, Listener::TIME);
                --(*_listenerItr);
            }
        }
    }

    // Fire script update event
    fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(AnimationClip, clipUpdate), this, _elapsedTime);

    // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
    GP_ASSERT(_animation);

    // Compute percentage complete for the current loop (prevent a divide by zero if _duration==0).
    // Note that we don't use (currentTime/(_duration+_loopBlendTime)). That's because we want a
    // % value that is outside the 0-1 range for loop smoothing/blending purposes.
    float percentComplete = _duration == 0 ? 1 : currentTime / (float)_duration;

    if (_loopBlendTime == 0.0f)
        percentComplete = MATH_CLAMP(percentComplete, 0.0f, 1.0f);

    // If we're cross fading, compute blend weights
    if (isClipStateBitSet(CLIP_IS_FADING_OUT_BIT))
    {
        GP_ASSERT(_crossFadeToClip);
        GP_ASSERT(_crossFadeOutDuration > 0);

        if (isClipStateBitSet(CLIP_IS_FADING_OUT_STARTED_BIT)) // Calculate elapsed time since the fade out begin.
        {
            GP_ASSERT(_crossFadeToClip);
            _crossFadeOutElapsed = (Game::getGameTime() - _crossFadeToClip->_timeStarted) * fabs(_speed);
            resetClipStateBit(CLIP_IS_FADING_OUT_STARTED_BIT);
        }
        else
        {
            // continue tracking elapsed time.
            _crossFadeOutElapsed += elapsedTime * fabs(_speed);
        }

        if (_crossFadeOutElapsed < _crossFadeOutDuration)
        {
            // Calculate this clip's blend weight.
            float tempBlendWeight = ((float)_crossFadeOutDuration - _crossFadeOutElapsed) / (float)_crossFadeOutDuration;

            // If this clip is fading in, adjust the crossfade clip's weight to be a percentage of your current blend weight
            if (isClipStateBitSet(CLIP_IS_FADING_IN_BIT))
            {
                _crossFadeToClip->_blendWeight = (1.0f - tempBlendWeight) * _blendWeight;
                _blendWeight -= _crossFadeToClip->_blendWeight;
            }
            else
            {
                // Just set the blend weight.
                _crossFadeToClip->_blendWeight = (1.0f - tempBlendWeight);
                _blendWeight = tempBlendWeight;
            }
        }
        else
        {
            // Fade is done.
            _crossFadeToClip->_blendWeight = 1.0f;
            _blendWeight = 0.0f;
            resetClipStateBit(CLIP_IS_STARTED_BIT);
            resetClipStateBit(CLIP_IS_FADING_OUT_BIT);
            _crossFadeToClip->resetClipStateBit(CLIP_IS_FADING_IN_BIT);
            SAFE_RELEASE(_crossFadeToClip);
        }
    }

    // Evaluate this clip.
    Animation::Channel* channel = NULL;
    AnimationValue* value = NULL;
    AnimationTarget* target = NULL;
    size_t channelCount = _animation->_channels.size();
    float percentageStart = (float)_startTime / (float)_animation->_duration;
    float percentageEnd = (float)_endTime / (float)_animation->_duration;
    float percentageBlend = (float)_loopBlendTime / (float)_animation->_duration;
    for (size_t i = 0; i < channelCount; i++)
    {
        channel = _animation->_channels[i];
        GP_ASSERT(channel);
        target = channel->_target;
        GP_ASSERT(target);
        value = _values[i];
        GP_ASSERT(value);

        // Evaluate the point on Curve
        GP_ASSERT(channel->getCurve());
        channel->getCurve()->evaluate(percentComplete, percentageStart, percentageEnd, percentageBlend, value->_value);

        // Set the animation value on the target property.
        target->setAnimationPropertyValue(channel->_propertyId, value, _blendWeight);
    }

    // When ended. Probably should move to it's own method so we can call it when the clip is ended early.
    if (isClipStateBitSet(CLIP_IS_MARKED_FOR_REMOVAL_BIT) || !isClipStateBitSet(CLIP_IS_STARTED_BIT))
    {
        onEnd();
        return true;
    }

    return false;
}