display_two.cpp

Go to the documentation of this file.
00001 /*
00002    This file is part of the KDE games lskat program
00003    Copyright (c) 2006 Martin Heni <kde@heni-online.de>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 // Qt includes
00022 #include <QSize>
00023 #include <QPoint>
00024 #include <QPen>
00025 #include <QBrush>
00026 #include <QLinearGradient>
00027 
00028 // KDE includes
00029 #include <kdebug.h>
00030 #include <klocalizedstring.h>
00031 
00032 // Local includes
00033 #include "display_two.h"
00034 #include "abstractinput.h"
00035 #include "cardsprite.h"
00036 #include "textsprite.h"
00037 #include "pixmapsprite.h"
00038 #include "scoresprite.h"
00039 
00040 
00041 // Display defines
00042 #define TIME_DELAY_SHUFFLE       100 /* Delay time in shuffling in [ms] */
00043 #define TIME_DELAY_AFTER_SHUFFLE 100 /* Extra delay after shuffling [ms] */
00044 
00045 
00046 // Constructor for the engine
00047 DisplayTwo::DisplayTwo(Deck* deck, QGraphicsScene* theScene, ThemeManager* theme,
00048                        int advancePeriod, QGraphicsView* parent)
00049           : Themable("display_two",theme), AbstractDisplay(deck, theScene, theme, advancePeriod, parent)
00050 
00051 {
00052   // Choose a background color
00053   scene()->setBackgroundBrush(QColor(0,0,128));
00054 
00055   // Create move icon
00056   mMoveSprites[0] = new PixmapSprite("moveicon0", mTheme, mAdvancePeriod, 0, scene());
00057   if (!mMoveSprites[0]) kFatal() << "Cannot load sprite " << "moveicon" << endl;
00058   mSprites.append(mMoveSprites[0]);
00059 
00060   mMoveSprites[1] = new PixmapSprite("moveicon1", mTheme, mAdvancePeriod, 1, scene());
00061   if (!mMoveSprites[1]) kFatal() << "Cannot load sprite " << "moveicon" << endl;
00062   mSprites.append(mMoveSprites[1]);
00063 
00064   // Create score board
00065   mScoreBoard[0] = new ScoreSprite("scoreboard0", mTheme, mAdvancePeriod, 0, scene());
00066   if (!mScoreBoard[0]) kFatal() << "Cannot load sprite " << "scoreboard0" << endl;
00067   mSprites.append(mScoreBoard[0]);
00068 
00069   mScoreBoard[1] = new ScoreSprite("scoreboard1", mTheme, mAdvancePeriod, 1, scene());
00070   if (!mScoreBoard[1]) kFatal() << "Cannot load sprite " << "scoreboard0" << endl;
00071   mSprites.append(mScoreBoard[1]);
00072 
00073   // Create card area
00074   mCardArea[0] = new PixmapSprite("cardarea0", mTheme, mAdvancePeriod, 0, scene());
00075   if (!mCardArea[0]) kFatal() << "Cannot load sprite " << "cardarea0" << endl;
00076   mSprites.append(mCardArea[0]);
00077 
00078   mCardArea[1] = new PixmapSprite("cardarea1", mTheme, mAdvancePeriod, 1, scene());
00079   if (!mCardArea[1]) kFatal() << "Cannot load sprite " << "cardarea1" << endl;
00080   mSprites.append(mCardArea[1]);
00081 
00082   // Create play area
00083   mPlayArea = new PixmapSprite("playarea", mTheme, mAdvancePeriod, 0, scene());
00084   if (!mPlayArea) kFatal() << "Cannot load sprite " << "playarea" << endl;
00085   mSprites.append(mPlayArea);
00086 
00087   // Create text sprites
00088   mText[0] = new TextSprite("scoretext0", mTheme, scene());
00089   if (!mText[0]) kFatal() << "Cannot load sprite " << "scoretext0" << endl;
00090   mSprites.append(mText[0]);
00091 
00092   mText[1] = new TextSprite("scoretext1", mTheme, scene());
00093   if (!mText[1]) kFatal() << "Cannot load sprite " << "scoretext1" << endl;
00094   mSprites.append(mText[1]);
00095 
00096   mText[2] = new TextSprite("resulttext", mTheme, scene());
00097   if (!mText[2]) kFatal() << "Cannot load sprite " << "resulttext" << endl;
00098   mSprites.append(mText[2]);
00099 
00100     // Redraw
00101   if (theme) theme->updateTheme(this);
00102 }
00103 
00104 
00105 // Called by thememanager when theme or theme geometry changes. Redraw and resize
00106 // this display.
00107 void DisplayTwo::changeTheme()
00108 {
00109   // Retrieve theme data
00110   KConfigGroup config = thememanager()->config(id());
00111 
00112   // Retrieve background pixmap
00113   QString bgsvgid = config.readEntry("background-svgid");
00114   QPixmap pixmap  = thememanager()->getPixmap(bgsvgid, scene()->sceneRect().size().toSize());
00115   scene()->setBackgroundBrush(pixmap);
00116   mView->update();
00117 }
00118 
00119 
00120 // Start display
00121 void DisplayTwo::start()
00122 {
00123   // Stop all card sprites
00124   for (int i=0; i<mCards.size(); i++)
00125   {
00126     CardSprite* sprite = mCards[i];
00127     sprite->stop();
00128   }
00129 
00130   // Hide or show sprites
00131   mMoveSprites[0]->hide();
00132   mMoveSprites[1]->hide();
00133   mScoreBoard[0]->show();
00134   mScoreBoard[1]->show();
00135   mCardArea[0]->show();
00136   mCardArea[1]->show();
00137   mPlayArea->show();
00138   mText[0]->hide();
00139   mText[1]->hide();
00140   mText[2]->hide();
00141 
00142 }
00143 
00144 
00145 // Connect a player with the score widget
00146 void DisplayTwo::updatePlayer(Player* player)
00147 {
00148   int id = player->id();
00149   mScoreBoard[id]->setPlayerName(player->name());
00150   mScoreBoard[id]->setPoints(player->points());
00151   mScoreBoard[id]->setScore(player->score());
00152   mScoreBoard[id]->setGames(player->wonGames(), player->games());
00153   mScoreBoard[id]->setInput(player->input()->type());
00154   mScoreBoard[id]->setTrump(player->trump());
00155 }
00156 
00157 
00158 // Init a player on a given screen/board position (0,1)
00159 void DisplayTwo::deal(Player* player, int position)
00160 {
00161   if (position != 0 && position != 1)
00162   {
00163     kFatal() << "Wrong player position " << position << endl;
00164     return ;
00165   }
00166   if (!player)
00167   {
00168     kFatal() << "No player given " << endl;
00169     return ;
00170   }
00171 
00172   KConfigGroup config = thememanager()->config(id());
00173   QPointF deck_pos       = config.readEntry("deck-pos", QPointF(1.0,1.0));
00174 
00175   // Start offset for display
00176   QPointF board_pos       = config.readEntry("board-pos1", QPointF(1.0,1.0));
00177   QPointF board_sep       = config.readEntry("board-sep", QPointF(1.0,1.0));
00178   QPointF board_shift     = config.readEntry("board-shift", QPointF(1.0,1.0));
00179   // Offset for second player
00180   if (position == 1)
00181   {
00182     board_pos  = config.readEntry("board-pos2", QPointF(1.0,1.0));
00183   }
00184 
00185 
00186   // Two height level of cards
00187   for (int h=0; h<2; h++)
00188   {
00189     // Two rows of cards
00190     for (int y=0; y<2; y++)
00191     {
00192       // Four columns of cards
00193       for (int x=0; x<4; x++)
00194       {
00195         // Get playerNumber on game board (0 1 2 3)
00196         //                                (4 5 6 7)
00197         int cardPos = x + 4*y + 8*h;
00198         // Get card of player belonging to this playerNumber
00199         int cardNo  = player->getCard(cardPos);
00200         // Create sprite with card correct card image
00201         CardSprite* sprite = mCards[cardNo];
00202         // Move sprite to correct board playerNumber
00203         QPointF pos = board_pos + QPointF(x*board_sep.x(),y*board_sep.y());
00204         // Add shift for stacked cards
00205         pos += h*board_shift;
00206         sprite->setZValue(50-10*h);
00207         sprite->setPosition(deck_pos);
00208         sprite->show();
00209         double delay = position + 2*x + 8*y + 16*(1-h);
00210         delay *=  TIME_DELAY_SHUFFLE; // [ms]
00211         // Move to the target position. The setPos is started with
00212         // a little delay and depending on the last argument the
00213         // backside or frontside is shown after the setPos
00214         sprite->setShuffleMove(pos, delay, h==0);
00215         // Store sprite
00216       }// next x
00217     }// next y
00218   }// next h
00219 }// end initPlayer
00220 
00221 
00222 // Returns the time in milliseconds used for shuffling the initial cards
00223 int DisplayTwo::shuffleTime()
00224 {
00225   return 32*TIME_DELAY_SHUFFLE + TIME_DELAY_AFTER_SHUFFLE;
00226 }
00227 
00228 
00229 // Convert a mouse coordinate back to card numbers
00230 void DisplayTwo::convertMousePress(QPoint mouse, int& playerNumber, int& cardNumber)
00231 {
00232   double scale = thememanager()->getScale();
00233   double x = mouse.x() / scale;
00234   double y = mouse.y() / scale;
00235 
00236   // Check play area 1
00237   KConfigGroup config0 = thememanager()->config("cardarea0");
00238   QPointF pos0         = config0.readEntry("pos", QPointF(1.0,1.0));
00239   double  width0       = config0.readEntry("width", 1.0);
00240   double  height0      = config0.readEntry("height", 1.0);
00241 
00242   double x0 = (x-pos0.x())/width0;
00243   double y0 = (y-pos0.y())/height0;
00244 
00245   // Check play area 2
00246   KConfigGroup config1 = thememanager()->config("cardarea1");
00247   QPointF pos1         = config1.readEntry("pos", QPointF(1.0,1.0));
00248   double  width1       = config1.readEntry("width", 1.0);
00249   double  height1      = config1.readEntry("height", 1.0);
00250 
00251   double x1 = (x-pos1.x())/width1;
00252   double y1 = (y-pos1.y())/height1;
00253 
00254 
00255   // Check in area 1
00256   if (x0>=0.0 && x0<1.0 && y0>=0.0 && y0<1.0)
00257   {
00258     int dx = int(x0*4.0);
00259     int dy = int(y0*2.0);
00260     playerNumber = 0;
00261     cardNumber = dx + 4*dy;
00262     return;
00263   }
00264 
00265   // Check in area 2
00266   if (x1>=0.0 && x1<1.0 && y1>=0.0 && y1<1.0)
00267   {
00268     int dx = int(x1*4.0);
00269     int dy = int(y1*2.0);
00270     playerNumber = 1;
00271     cardNumber = dx + 4*dy;
00272     return;
00273   }
00274 
00275   playerNumber = -1;
00276   return;
00277 }
00278 
00279 
00280 // Get x (0-3) y(0-1) board coordinates from card number (0-7)
00281 void DisplayTwo::calcXYFromNumber(int cardNumber, int& x, int& y)
00282 {
00283   x = cardNumber % 4;
00284   y = cardNumber / 4;
00285 }
00286 
00287 
00288 // Get a cardsprite given the card value
00289 CardSprite* DisplayTwo::getCardSprite(int cardValue)
00290 {
00291   CardSprite* sprite =  mCards[cardValue];
00292   if (!sprite)
00293   {
00294     kFatal() << "Could not find cardsprite for card value " << cardValue 
00295               << " Stored are " << mCards.size() << " sprites " 
00296               << endl;
00297     return 0;
00298   }
00299   return sprite;
00300 }
00301 
00302 
00303 // Play a frontside card to the play area
00304 void DisplayTwo::play(int cardNumber, int playerNumber, int phase)
00305 {
00306   KConfigGroup config = thememanager()->config(id());
00307   QPointF play_pos_1     = config.readEntry("play-pos1", QPointF(1.0,1.0));
00308   QPointF play_pos_2     = config.readEntry("play-pos2", QPointF(1.0,1.0));
00309   double deal_move_time  = config.readEntry("deal-move-time", 1.0);
00310 
00311   CardSprite* sprite = getCardSprite(cardNumber);
00312   // Set z coordinate depending on setPos phase, that is latter cards will
00313   // be put on top
00314   sprite->setZValue(100 + 5*phase);
00315   if (playerNumber == 0)
00316   {
00317     sprite->setMove(play_pos_1, deal_move_time);
00318   }
00319   else
00320   {
00321     sprite->setMove(play_pos_2, deal_move_time);
00322   }
00323 }
00324 
00325 
00326 // Turn a backside card to the front
00327 void DisplayTwo::turn(int cardNumber)
00328 {
00329   CardSprite* sprite = getCardSprite(cardNumber);
00330   sprite->setTurning(true);
00331 }
00332 
00333 
00334 // Remove the given card from the display.
00335 void DisplayTwo::remove(int winnerPosition, int cardNumber, int delta)
00336 {
00337   KConfigGroup config = thememanager()->config(id());
00338   QPointF stack_pos1  = config.readEntry("stack-pos1", QPointF(1.0,1.0));
00339   QPointF stack_pos2  = config.readEntry("stack-pos2", QPointF(1.0,1.0));
00340   QPointF stack_shift = config.readEntry("stack-shift", QPointF(1.0,1.0));
00341   double remove_time  = config.readEntry("remove-time", 1.0);
00342   CardSprite* sprite  = getCardSprite(cardNumber);
00343   // Pile cards on top of each other
00344   sprite->setZValue(100 + delta);
00345   QPointF pos;
00346   if (winnerPosition == 0)
00347   {
00348     pos = QPointF(stack_pos1.x() + delta*stack_shift.x(),
00349                   stack_pos1.y() + delta*stack_shift.y());
00350   }
00351   else
00352   {
00353     pos = QPointF(stack_pos2.x() + delta*stack_shift.x(),
00354                   stack_pos2.y() + delta*stack_shift.y());
00355   }
00356   sprite->setRemove(pos, remove_time);
00357 }
00358 
00359 
00360 // Display a text on the game board.
00361 void DisplayTwo::showText(QString s)
00362 {
00363   mText[2]->setText(s);
00364   mText[2]->show();
00365 }
00366 
00367 
00368 // Display the score on the game board
00369 void DisplayTwo::showScore(int position, int score)
00370 {
00371   if (position<0 || position>1)
00372   {
00373     kFatal() << "Wrong position (0,1) for showScore = " << position<< endl;
00374   }
00375   mText[position]->setText(i18nc("Resulting score of a game","%1 points", score));
00376   mText[position]->show();
00377 }
00378 
00379 
00380 // Show the setPos icon for the given player
00381 void DisplayTwo::showMove(int no)
00382 {
00383   QHashIterator<int,PixmapSprite*> it(mMoveSprites);
00384   while(it.hasNext())
00385   {
00386     it.next();
00387     PixmapSprite* sprite = it.value();
00388     sprite->hide();
00389   }
00390 
00391   if (no>=0)
00392   {
00393     mMoveSprites[no]->show();
00394   }
00395 }
00396 
00397 
00398 #include "display_two.moc"

Generated on Tue May 1 09:34:40 2007 for LSkat by  doxygen 1.4.6