Table of contents
Introduction
This is a very simple class that was written in less than 2 hours but is very useful in providing a simple, cool effect. This class is inspired by another code snippet - Simple text. So I took some of the code and merged it with my own and... tadaa... here we are!
The class basically will have 3 lines of messages which can be added by calling the addText() member function. So the old lines (the original line 1, 2 and 3) will be scrolled down and line 3 will be slowly faded out and new comes at the top. Of course you do not have to limit to 3 lines of messages - feel free to increase or decrease the number as the source code is extremely simple ๐
Usage
Firstly, you have to call init() prior to using the class. I didn't include it in the constructor because Ogre may not have been initialized yet.
And then in any of the FrameListener's frameStarted(), call loop member function for example:
mScrollingMessage.loop(evt.timeSinceLastFrame);
Since this is a singleton, you can call the class anywhere and add text to it, eg:
ScrollingMessage::getSingleton().addText("Hello Moto!");
That's all about it.
ScrollingMessage.h
#pragma once #include <Ogre.h> class ScrollingMessage : public Ogre::Singleton<ScrollingMessage> { protected: Ogre::OverlayContainer* mPanel; Ogre::Overlay* mOverlay; Ogre::OverlayElement* mTextBox[3]; Ogre::Real mTimeToGo; bool mJustAdded; // all are in pixel enum { POSITION_TOP_X = 5, POSITION_TOP_Y = 30, SPACING = 30 }; public: ScrollingMessage(); void init(); void addText(const Ogre::String& text); void loop(Ogre::Real time); };
ScrollingMessage.cpp
#include "ScrollingMessage.h" using namespace Ogre; template<> ScrollingMessage* Singleton<ScrollingMessage>::ms_Singleton = 0; ScrollingMessage::ScrollingMessage() { mTimeToGo = 0.0; mJustAdded = false; } void ScrollingMessage::init() { mOverlay = OverlayManager::getSingleton().create("ScrollingOverlay"); mPanel = static_cast<OverlayContainer*>(OverlayManager::getSingleton().createOverlayElement("Panel", "container1")); mPanel->setMetricsMode(GMM_PIXELS); mPanel->setDimensions(800, 400); mPanel->setPosition(5, 30); // now create the text... String name; for (int i = 0; i < 3; ++i) { name = "ScrollingMessage"+StringConverter::toString(i); mTextBox[i] = OverlayManager::getSingleton().createOverlayElement("TextArea", name); mTextBox[i]->setMetricsMode(Ogre::GMM_PIXELS); mTextBox[i]->setDimensions(20, 5); mTextBox[i]->setWidth(20); mTextBox[i]->setHeight(5); mTextBox[i]->setPosition(POSITION_TOP_X, POSITION_TOP_Y+i*SPACING); mTextBox[i]->setParameter("font_name", "StarWars"); mTextBox[i]->setParameter("char_height", "16"); mTextBox[i]->setColour(ColourValue::White); mTextBox[i]->setCaption(" "); mPanel->addChild(mTextBox[i]); } mOverlay->add2D(mPanel); mOverlay->show(); } void ScrollingMessage::addText(const String& text) { // first swap the content... mTextBox[2]->setCaption(mTextBox[1]->getCaption()); mTextBox[1]->setCaption(mTextBox[0]->getCaption()); mTextBox[0]->setCaption(text); // but hide the first textbox first... mTextBox[0]->hide(); // and move the others to upper coordinate... mTextBox[1]->setPosition(POSITION_TOP_X, POSITION_TOP_Y); mTextBox[2]->setPosition(POSITION_TOP_X, POSITION_TOP_Y+SPACING); mTimeToGo = 1.5; // 1.5 seconds... mJustAdded = true; } void ScrollingMessage::loop(Real time) { if (mJustAdded) { mTimeToGo -= time; if (mTimeToGo <= 1.0) mTextBox[0]->show(); if (mTimeToGo < 1e-3) { mTimeToGo = 0.0; mJustAdded = false; } // scroll the textbox by this much.. Real progress = (1.5-mTimeToGo)/1.5; Real y = POSITION_TOP_Y+SPACING*progress; mTextBox[1]->setPosition(POSITION_TOP_X, y); mTextBox[1]->setColour(ColourValue(1,1,1,1.0-progress/4)); mTextBox[2]->setPosition(POSITION_TOP_X, y+SPACING); mTextBox[2]->setColour(ColourValue(1,1,1,1.0-progress*progress)); } }