added Reward and Expiration to task list

moved text scroller into DeckMenu class since it is specific to DeckMenu and not GameStateDuel
added new util function "wordWrap"
This commit is contained in:
techdragon.nguyen@gmail.com
2010-11-03 00:15:12 +00:00
parent 685626128a
commit 4a3d7faf0a
8 changed files with 133 additions and 71 deletions
+10 -9
View File
@@ -5,18 +5,19 @@
#define _DeckMenu_H_ #define _DeckMenu_H_
#include <string> #include <string>
#include <JGui.h>
#include "WFont.h" #include "WFont.h"
#include "hge/hgeparticle.h" #include "hge/hgeparticle.h"
#include "DeckMetaData.h" #include "DeckMetaData.h"
#include "TextScroller.h"
class DeckMenu:public JGuiController{ class DeckMenu:public JGuiController{
private: protected:
int mHeight, mWidth, mX, mY; int mHeight, mWidth, mX, mY;
int titleX, titleY, titleWidth; int titleX, titleY, titleWidth;
int descX, descY, descHeight, descWidth; int descX, descY, descHeight, descWidth;
int statsX, statsY, statsHeight, statsWidth; int statsX, statsY, statsHeight, statsWidth;
int avatarX, avatarY;
int fontId; int fontId;
std::string title; std::string title;
@@ -26,23 +27,23 @@ class DeckMenu:public JGuiController{
float timeOpen; float timeOpen;
static unsigned int refCount; static unsigned int refCount;
JQuad *background;
JTexture *backgroundTexture;
static WFont* titleFont; static WFont* titleFont;
static hgeParticleSystem* stars; static hgeParticleSystem* stars;
// This works only because of no multithreading // This works only because of no multithreading
static PIXEL_TYPE jewelGraphics[9]; static PIXEL_TYPE jewelGraphics[9];
inline void MogrifyJewel();
public: public:
TextScroller * scroller;
bool autoTranslate; bool autoTranslate;
DeckMenu(int id, JGuiListener* listener, int fontId, const char * _title = "");
DeckMenu(int id, JGuiListener* listener, int fontId, const string _title = "");
~DeckMenu();
void Render(); void Render();
void Update(float dt); void Update(float dt);
void Add(int id, const char * Text, string desc = "", bool forceFocus = false, DeckMetaData *deckMetaData = NULL); void Add(int id, const char * Text, string desc = "", bool forceFocus = false, DeckMetaData *deckMetaData = NULL);
void Close(); void Close();
void updateScroller();
float selectionTargetY; float selectionTargetY;
bool closed; bool closed;
-2
View File
@@ -7,7 +7,6 @@
#include "DeckMenu.h" #include "DeckMenu.h"
#include "MTGDeck.h" #include "MTGDeck.h"
#include "GameObserver.h" #include "GameObserver.h"
#include "TextScroller.h"
#define CHOOSE_OPPONENT 7 #define CHOOSE_OPPONENT 7
@@ -33,7 +32,6 @@ class GameStateDuel: public GameState, public JGuiListener
DeckMenu * deckmenu; DeckMenu * deckmenu;
DeckMenu * opponentMenu; DeckMenu * opponentMenu;
SimpleMenu * menu; SimpleMenu * menu;
TextScroller * scroller;
bool premadeDeck; bool premadeDeck;
int OpponentsDeckid; int OpponentsDeckid;
string musictrack; string musictrack;
+3 -1
View File
@@ -18,6 +18,8 @@ protected:
float mY; float mY;
float start; float start;
int timer; int timer;
int minimumItems;
vector<string> strings; vector<string> strings;
unsigned int currentId; unsigned int currentId;
int mRandom; int mRandom;
@@ -27,7 +29,7 @@ public:
void Add(string text); void Add(string text);
void Reset(); void Reset();
void setRandom(int mode = 1); void setRandom(int mode = 1);
TextScroller(int fontId, float x, float y, float width, float speed = 30, int scrollerType = 0); TextScroller(int fontId, float x, float y, float width, float speed = 30, int scrollerType = 0, int _minimumItems = 2);
void Render(); void Render();
void Update(float dt); void Update(float dt);
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
+1
View File
@@ -41,6 +41,7 @@ string& rtrim(string &str);
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems); std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
std::vector<std::string> split(const std::string &s, char delim); //splits a string with "delim" and returns a vector of strings. std::vector<std::string> split(const std::string &s, char delim); //splits a string with "delim" and returns a vector of strings.
std::string wordWrap(std::string s, int width);
int loadRandValues(string s); int loadRandValues(string s);
+72 -29
View File
@@ -6,13 +6,16 @@
#include "JTypes.h" #include "JTypes.h"
#include "GameApp.h" #include "GameApp.h"
#include "Translate.h" #include "Translate.h"
#include "TextScroller.h"
#include "Tasks.h"
#include <iomanip>
namespace namespace
{ {
const unsigned int kPoleWidth = 7;
const unsigned int kVerticalMargin = 16; const unsigned int kVerticalMargin = 16;
const unsigned int kHorizontalMargin = 30; const unsigned int kHorizontalMargin = 30;
const signed int kLineHeight = 20; const signed int kLineHeight = 20;
const signed int kDescriptionVerticalBoxPadding = 5;
const signed int kDescriptionHorizontalBoxPadding = 5;
} }
WFont* DeckMenu::titleFont = NULL; WFont* DeckMenu::titleFont = NULL;
@@ -30,45 +33,60 @@ PIXEL_TYPE DeckMenu::jewelGraphics[9] = {0x3FFFFFFF,0x63645AEA,0x610D0D98,
// used fixed locations where the menu, title and descriptive text are located. // used fixed locations where the menu, title and descriptive text are located.
// * menu at (125, 60 ) // * menu at (125, 60 )
// * descriptive information 125 // * descriptive information 125
// *** Need to make this configurable in a file somewhere to allow for class reuse
DeckMenu::DeckMenu(int id, JGuiListener* listener, int fontId, const char * _title) DeckMenu::DeckMenu(int id, JGuiListener* listener, int fontId, const string _title)
: JGuiController(id, listener), : JGuiController(id, listener),
fontId(fontId) { fontId(fontId) {
background = NULL;
mX = 120;
mY = 55;
titleX = 125; // center point in title box
titleY = 28;
titleWidth = 180; // width of inner box of title
descX = 230 + kDescriptionVerticalBoxPadding;
descY = 65 + kDescriptionHorizontalBoxPadding;
descHeight = 145;
descWidth = 220;
statsX = 280;
statsY = 8;
statsHeight = 50;
statsWidth = 227;
avatarX = 230;
avatarY = 8;
int scrollerWidth = 80;
scroller = NEW TextScroller(Fonts::MAIN_FONT, 40 , 230, scrollerWidth, 100, 1, 1);
autoTranslate = true; autoTranslate = true;
maxItems = 7; maxItems = 7;
mHeight = 2 * kVerticalMargin + ( maxItems * kLineHeight ); mHeight = 2 * kVerticalMargin + ( maxItems * kLineHeight );
mWidth = 0; mWidth = 0;
mX = 125;
mY = 60;
// where to place the title of the menu // we want to cap the deck titles to 15 characters to avoid overflowing deck names
titleX = mX;
titleY = mY - 30;
title = _(_title); title = _(_title);
// where stats information goes
statsX = 280;
statsY = 8 + kVerticalMargin;
statsHeight = 50;
statsWidth = SCREEN_WIDTH / 2 - 40; // 40 is the width of the right border
// where to place the descripiton information
descX = 229;
descY = 70;
startId = 0; startId = 0;
selectionT = 0; selectionT = 0;
timeOpen = 0; timeOpen = 0;
closed = false; closed = false;
++refCount; ++refCount;
selectionTargetY = selectionY = kVerticalMargin; selectionTargetY = selectionY = kVerticalMargin;
if (NULL == stars) if (NULL == stars)
stars = NEW hgeParticleSystem(resources.RetrievePSI("stars.psi", resources.GetQuad("stars"))); stars = NEW hgeParticleSystem(resources.RetrievePSI("stars.psi", resources.GetQuad("stars")));
stars->FireAt(mX, mY); stars->FireAt(mX, mY);
updateScroller();
} }
// TODO: Make this configurable, perhaps by user as part of the theme options. // TODO: Make this configurable, perhaps by user as part of the theme options.
@@ -80,10 +98,11 @@ JQuad* getBackground()
} }
void DeckMenu::Render() { void DeckMenu::Render()
{
JRenderer * renderer = JRenderer::GetInstance(); JRenderer * renderer = JRenderer::GetInstance();
WFont * titleFont = resources.GetWFont(Fonts::SMALLFACE_FONT); WFont * titleFont = resources.GetWFont(Fonts::MAGIC_FONT);
WFont * mFont = resources.GetWFont(fontId); WFont * mFont = resources.GetWFont(fontId);
// figure out where to place the stars initially // figure out where to place the stars initially
@@ -123,15 +142,15 @@ void DeckMenu::Render() {
for (int i = startId; i < startId + maxItems ; i++){ for (int i = startId; i < startId + maxItems ; i++){
if (i > mCount-1) break; if (i > mCount-1) break;
if ( static_cast<DeckMenuItem*>(mObjects[i])->mY - kLineHeight * startId < mY + height - kLineHeight + 7) { DeckMenuItem *currentMenuItem = static_cast<DeckMenuItem*>(mObjects[i]);
DeckMenuItem *currentMenuItem = static_cast<DeckMenuItem*>(mObjects[i]); if ( currentMenuItem->mY - kLineHeight * startId < mY + height - kLineHeight + 7) {
if ( currentMenuItem->hasFocus()){ if ( currentMenuItem->hasFocus()){
// display the avatar image // display the avatar image
if ( currentMenuItem->imageFilename.size() > 0 ) if ( currentMenuItem->imageFilename.size() > 0 )
{ {
JQuad * quad = resources.RetrieveTempQuad( currentMenuItem->imageFilename, TEXTURE_SUB_AVATAR ); JQuad * quad = resources.RetrieveTempQuad( currentMenuItem->imageFilename, TEXTURE_SUB_AVATAR );
if (quad) { if (quad) {
renderer->RenderQuad(quad, 232, 10, 0, 0.9f, 0.9f); renderer->RenderQuad(quad, avatarX, avatarY);
} }
} }
// fill in the description part of the screen // fill in the description part of the screen
@@ -147,11 +166,8 @@ void DeckMenu::Render() {
oss << "Deck: " << currentMenuItem->meta->getName() << endl; oss << "Deck: " << currentMenuItem->meta->getName() << endl;
oss << currentMenuItem->meta->getStatsSummary(); oss << currentMenuItem->meta->getStatsSummary();
mainFont->DrawString( oss.str(), statsX, statsY - kVerticalMargin ); mainFont->DrawString( oss.str(), statsX, statsY );
} }
// fill in the bottom section of the screen.
// TODO: add text scroller of Tasks.
} }
else { else {
mFont->SetColor(ARGB(150,255,255,255)); mFont->SetColor(ARGB(150,255,255,255));
@@ -161,6 +177,10 @@ void DeckMenu::Render() {
if (!title.empty()) if (!title.empty())
titleFont->DrawString(title.c_str(), titleX, titleY, JGETEXT_CENTER); titleFont->DrawString(title.c_str(), titleX, titleY, JGETEXT_CENTER);
scroller->Render();
renderer->RenderQuad(getBackground(), 0, 0 );
} }
} }
@@ -181,6 +201,8 @@ void DeckMenu::Update(float dt){
closed = false; closed = false;
timeOpen += dt * 10; timeOpen += dt * 10;
} }
scroller->Update(dt);
} }
void DeckMenu::Add(int id, const char * text,string desc, bool forceFocus, DeckMetaData * deckMetaData) { void DeckMenu::Add(int id, const char * text,string desc, bool forceFocus, DeckMetaData * deckMetaData) {
@@ -196,6 +218,22 @@ void DeckMenu::Add(int id, const char * text,string desc, bool forceFocus, DeckM
} }
} }
void DeckMenu::updateScroller()
{
// add all the items from the Tasks db.
TaskList *taskList = NEW TaskList();
scroller->Reset();
for (vector<Task*>::iterator it = taskList->tasks.begin(); it!=taskList->tasks.end(); it++)
{
ostringstream taskDescription;
taskDescription << "[ " << setw(4) << (*it)->getReward() << " / " << (*it)->getExpiration() << " ] " << (*it)->getDesc() << ". " << endl;
scroller->Add( taskDescription.str() );
}
SAFE_DELETE(taskList);
}
void DeckMenu::Close() void DeckMenu::Close()
{ {
timeOpen = -1.0; timeOpen = -1.0;
@@ -206,3 +244,8 @@ void DeckMenu::Close()
void DeckMenu::destroy(){ void DeckMenu::destroy(){
SAFE_DELETE(DeckMenu::stars); SAFE_DELETE(DeckMenu::stars);
} }
DeckMenu::~DeckMenu()
{
SAFE_DELETE(scroller);
}
+2 -25
View File
@@ -15,7 +15,6 @@
#include "Credits.h" #include "Credits.h"
#include "Translate.h" #include "Translate.h"
#include "Rules.h" #include "Rules.h"
#include "TextScroller.h"
#ifdef TESTSUITE #ifdef TESTSUITE
#include "TestSuiteAI.h" #include "TestSuiteAI.h"
@@ -66,12 +65,10 @@ GameStateDuel::GameStateDuel(GameApp* parent): GameState(parent) {
credits = NULL; credits = NULL;
rules = NULL; rules = NULL;
initScroller();
} }
GameStateDuel::~GameStateDuel() { GameStateDuel::~GameStateDuel() {
End(); End();
SAFE_DELETE(scroller);
} }
@@ -97,7 +94,7 @@ void GameStateDuel::Start()
if (mParent->players[i] == PLAYER_TYPE_HUMAN){ if (mParent->players[i] == PLAYER_TYPE_HUMAN){
decksneeded = 1; decksneeded = 1;
deckmenu = NEW DeckMenu(DUEL_MENU_CHOOSE_DECK, this, Fonts::MENU_FONT, "Choose a Deck"); deckmenu = NEW DeckMenu(DUEL_MENU_CHOOSE_DECK, this, Fonts::MAGIC_FONT, "Choose a Deck");
DeckManager *deckManager = DeckManager::GetInstance(); DeckManager *deckManager = DeckManager::GetInstance();
vector<DeckMetaData *> playerDeckList = getValidDeckMetaData( options.profileFile() ); vector<DeckMetaData *> playerDeckList = getValidDeckMetaData( options.profileFile() );
@@ -242,7 +239,7 @@ bool GameStateDuel::MusicExist(string FileName){
void GameStateDuel::ensureOpponentMenu(){ void GameStateDuel::ensureOpponentMenu(){
if (!opponentMenu){ if (!opponentMenu){
opponentMenu = NEW DeckMenu(DUEL_MENU_CHOOSE_OPPONENT, this, Fonts::MENU_FONT, "Choose Your Opponent"); opponentMenu = NEW DeckMenu(DUEL_MENU_CHOOSE_OPPONENT, this, Fonts::MAGIC_FONT, "Choose Your Opponent");
opponentMenu->Add( MENUITEM_RANDOM_AI, "Random"); opponentMenu->Add( MENUITEM_RANDOM_AI, "Random");
if (options[Options::EVILTWIN_MODE_UNLOCKED].number) if (options[Options::EVILTWIN_MODE_UNLOCKED].number)
opponentMenu->Add( MENUITEM_EVIL_TWIN, "Evil Twin", _("Can you play against yourself?").c_str()); opponentMenu->Add( MENUITEM_EVIL_TWIN, "Evil Twin", _("Can you play against yourself?").c_str());
@@ -254,21 +251,6 @@ void GameStateDuel::ensureOpponentMenu(){
} }
} }
void GameStateDuel::initScroller()
{
scroller = NEW TextScroller(Fonts::MAIN_FONT, 40 , 230, 400, 100, 1);
// add all the items from the Tasks db.
TaskList *taskList = NEW TaskList();
scroller->Reset();
for (vector<Task*>::iterator it = taskList->tasks.begin(); it!=taskList->tasks.end(); it++)
{
ostringstream taskDescription;
taskDescription << (*it)->getDesc() <<endl;
scroller->Add( taskDescription.str() );
}
SAFE_DELETE(taskList);
}
void GameStateDuel::Update(float dt) void GameStateDuel::Update(float dt)
{ {
switch (mGamePhase) switch (mGamePhase)
@@ -433,7 +415,6 @@ void GameStateDuel::Update(float dt)
PlayerData * playerdata = NEW PlayerData(mParent->collection); PlayerData * playerdata = NEW PlayerData(mParent->collection);
playerdata->taskList->passOneDay(); playerdata->taskList->passOneDay();
playerdata->taskList->save(); playerdata->taskList->save();
initScroller();
SAFE_DELETE(playerdata); SAFE_DELETE(playerdata);
SAFE_DELETE(menu); SAFE_DELETE(menu);
} }
@@ -445,9 +426,6 @@ void GameStateDuel::Update(float dt)
if (JGE_BTN_OK == mEngine->ReadButton()) if (JGE_BTN_OK == mEngine->ReadButton())
mParent->SetNextState(GAME_STATE_MENU); mParent->SetNextState(GAME_STATE_MENU);
} }
// Update the scroller
scroller->Update(dt);
} }
@@ -511,7 +489,6 @@ void GameStateDuel::Render()
else if (deckmenu) else if (deckmenu)
deckmenu->Render(); deckmenu->Render();
scroller->Render();
} }
break; break;
case DUEL_STATE_ERROR_NO_DECK: case DUEL_STATE_ERROR_NO_DECK:
+5 -4
View File
@@ -11,9 +11,10 @@ enum {
}; };
TextScroller::TextScroller(int fontId, float x, float y, float width, float speed, int scrollerType ): JGuiObject(0), fontId(fontId){ TextScroller::TextScroller(int fontId, float x, float y, float width, float speed, int scrollerType, int numItems ): JGuiObject(0), fontId(fontId){
mWidth = width; mWidth = width;
mSpeed = speed; mSpeed = speed;
minimumItems = numItems;
mX = x; mX = x;
mY = y; mY = y;
start = -width; start = -width;
@@ -60,18 +61,18 @@ void TextScroller::Update(float dt){
} }
else else
{ {
// we want to display 3 at a time // we want to display 2 at a time
ostringstream scrollerText; ostringstream scrollerText;
if ( timer == 0 ) if ( timer == 0 )
{ {
for ( size_t idx = 0; idx < (MIN(2, strings.size())); idx ++ ) for ( size_t idx = 0; idx < (MIN(minimumItems, strings.size())); idx ++ )
{ {
scrollerText << strings[currentId + idx]; scrollerText << strings[currentId + idx];
} }
currentId++; currentId++;
if ( currentId >= (strings.size()-1) ) if ( currentId >= (strings.size()-1) )
currentId = 0; currentId = 0;
mText = scrollerText.str(); mText = wordWrap( scrollerText.str(), mWidth );
} }
timer = ++timer % ((int) mSpeed); timer = ++timer % ((int) mSpeed);
} }
+39
View File
@@ -217,3 +217,42 @@ std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems; std::vector<std::string> elems;
return split(s, delim, elems); return split(s, delim, elems);
} }
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (*it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
// check if done
if (it == sentence.end())
{
return sentence;
}
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
++it;
}
return sentence;
}