kwin4view.cpp

Go to the documentation of this file.
00001 /*
00002    This file is part of the KDE games kwin4 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 // Standard includes
00022 #include <math.h>
00023 
00024 // Qt includes
00025 #include <QTimer>
00026 #include <QTimer>
00027 #include <QColor>
00028 
00029 // KDE includes
00030 #include <klocale.h>
00031 #include <kdebug.h>
00032 #include <kplayer.h>
00033 
00034 // Local includes
00035 #include "kwin4view.h"
00036 #include "displayintro.h"
00037 #include "displaygame.h"
00038 #include "spritenotify.h"
00039 #include "score.h"
00040 
00041 
00042 // Aspect ratio for the Scene in the window. The game is always displayed with this ratio.
00043 #define VIEW_ASPECT_RATIO 1.6
00044 
00045 // Our subclassed QGraphicsView paintEvent, see header file
00046 void KWinGraphicsView::paintEvent(QPaintEvent* event)
00047 {
00048     QPaintEvent* newEvent = new QPaintEvent(event->region().boundingRect());
00049     QGraphicsView::paintEvent(newEvent);
00050     delete newEvent;
00051 }
00052 
00053 // Constructor for the view
00054 KWin4View::KWin4View(QSize size, int advancePeriod, QGraphicsScene* scene, ThemeManager* theme, QWidget* parent)
00055           : KWinGraphicsView(scene, parent)
00056 {
00057   // Store attributes    
00058   mScene         = scene;
00059   mTheme         = theme;
00060   mAdvancePeriod = advancePeriod;
00061 
00062   // We do not need scrolling so switch it off
00063   setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00064   setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00065   setCacheMode(QGraphicsView::CacheBackground);
00066 
00067   // Choose a background color
00068   scene->setBackgroundBrush(QColor(0,0,128));
00069 
00070 
00071   // Update/advance view every 25ms
00072   QTimer* timer = new QTimer(this);
00073   connect(timer, SIGNAL(timeout()), this, SLOT(updateAndAdvance()));
00074   timer->start(advancePeriod);
00075 
00076   // Game status
00077   mIsRunning = false;
00078   
00079   // Set size and position of the view and the canvas:
00080   // they are reseized once a level is loaded
00081   resize(size);
00082   scene->setSceneRect(0, 0, this->width(), this->height()); 
00083   adjustSize();
00084 
00085   // Interact with user
00086   setInteractive(true);
00087   
00088   // Scale theme
00089   mTheme->rescale(this->width());
00090 
00091   // Start with the intro display
00092   mGameDisplay  = 0;
00093   mIntroDisplay = new DisplayIntro(advancePeriod, scene, mTheme, this);
00094   mIntroDisplay->start();
00095 }
00096 
00097 
00098 // Destruct the view object
00099 KWin4View::~KWin4View()
00100 {
00101   if (mIntroDisplay) delete mIntroDisplay;
00102   if (mGameDisplay) delete mGameDisplay;
00103 }
00104 
00105 
00106 // Advance and update canvas/scene
00107 void KWin4View::updateAndAdvance()
00108 {
00109   scene()->advance();
00110   // QGV takes care of updating dirty rects, no need to call update or the whole scene is dirtied and repainted
00111   // scene()->update();
00112 }
00113 
00114 
00115 // Stop intro display and init game display
00116 void KWin4View::initGame(Score* scoreData)
00117 {
00118   if (mIntroDisplay) delete mIntroDisplay;
00119   mIntroDisplay = 0;
00120   if (!mGameDisplay)
00121   {
00122      mGameDisplay = new DisplayGame(mAdvancePeriod, mScene, mTheme, this);
00123   }
00124   mGameDisplay->start();
00125 
00126   // Connect score and score sprite
00127   scoreData->setDisplay(mGameDisplay->score());
00128 
00129   mIsRunning = true;
00130 }
00131 
00132 
00133 // End the game
00134 void  KWin4View::endGame()
00135 {
00136   mIsRunning = false;
00137   mGameDisplay->displayEnd();
00138 }
00139 
00140 
00141 // Slot called by the framework when the view is resized.
00142 void KWin4View::resizeEvent (QResizeEvent* e)
00143 {
00144   kDebug() << "++++ KWin4View::resizeEvent "<<e->size().width()<<" , "<< e->size().height() <<endl;
00145   // Adapt the canvas size to the window size
00146   if (scene())
00147   {
00148     scene()->setSceneRect(0, 0, e->size().width(), e->size().height());
00149   }
00150   QSizeF size = QSizeF(e->size());
00151 
00152   // Rescale on minimum fitting aspect ratio either width or height limiting
00153   double aspect = size.width() / size.height();
00154   if (aspect > VIEW_ASPECT_RATIO) mTheme->rescale(int(e->size().height()*VIEW_ASPECT_RATIO));
00155   else mTheme->rescale(int(e->size().width()));
00156 }
00157 
00158 
00159 
00160 
00161 // This slot is called when a mouse key is pressed. As the mouse is used as
00162 // input for all players. It is called to generate a player move out of a mouse input, i.e.
00163 // it converts a QMouseEvent into a move for the game. 
00164 void KWin4View::mouseInput(KGameIO* input, QDataStream& stream, QMouseEvent* mouse, bool* eatevent)
00165 {
00166   // Only react to mouse pressed not released
00167   if (mouse->type()   != QEvent::MouseButtonPress ) return;
00168   if (mouse->button() != Qt::LeftButton) return ;
00169   if (!mIsRunning) return;
00170 
00171   // Our player
00172   KPlayer* player=input->player();
00173   if (!player->myTurn())
00174   {
00175     kDebug() <<" Kwin4View::TODO wrongPlayer " << endl;
00176   //  *eatevent=wrongPlayer(player,KGameIO::MouseIO);
00177     return;
00178   }
00179 
00180   // Calculate movement position from mouse position
00181   int x = -1;
00182   if (mGameDisplay) x = mGameDisplay->mapMouseToMove(mouse->pos());
00183   if (x<0) return;
00184 
00185   // Create a game move (pl id and move coordinate)
00186   qint32 move = x;
00187   qint32 pl   = player->userId();
00188   stream << pl << move;
00189   *eatevent=true;
00190 }
00191 
00192 
00193 // This slot is called when a key event is received. It then prduces a
00194 // valid move for the game.
00195 // This is analogous to the mouse event only it is called when a key is
00196 // pressed.
00197 void KWin4View::keyInput(KGameIO* input, QDataStream& stream, QKeyEvent* key, bool* eatevent)
00198 {
00199   // Ignore non running
00200   if (!mIsRunning) return;
00201 
00202   // Ignore non key press
00203   if (key->type() != QEvent::KeyPress) return ;
00204 
00205   // Check key code
00206   int code=key->key();
00207   if (code< Qt::Key_1 || code> Qt::Key_7) return ;
00208   
00209 
00210   // Our player
00211   KPlayer *player=input->player();
00212   if (!player->myTurn())
00213   {
00214     kDebug() <<" Kwin4View::TODO wrongPlayer " << endl;
00215    // *eatevent=wrongPlayer(player,KGameIO::KeyIO);
00216     return;
00217   }
00218 
00219   // Create a valid game move (player id and movement position)
00220   qint32 move = code-Qt::Key_1;
00221   qint32 pl   = player->userId();
00222   stream << pl << move;
00223   *eatevent=true;
00224 }
00225 
00226 
00227 
00228 // Displays a move on the game board. 
00229 void KWin4View::displayMove(int x, int y, int color, int xarrow, int colorarrow, int no, bool animation)
00230 {
00231   mGameDisplay->displayArrow(xarrow, colorarrow);
00232   // animation onyl if no redo
00233   SpriteNotify* notify = mGameDisplay->displayPiece(x, y, color, no, animation);
00234   if (notify && animation)
00235   {
00236     QObject::disconnect(notify,SIGNAL(signalNotify(QGraphicsItem*,int)),
00237                         this,SLOT(moveDone(QGraphicsItem*,int)));
00238     connect(notify,SIGNAL(signalNotify(QGraphicsItem*,int)),
00239             this,SLOT(moveDone(QGraphicsItem*,int)));
00240   }
00241   mGameDisplay->displayHint(0,0,false);
00242 }
00243 
00244 
00245 // Display a star of the given sprite number
00246 void KWin4View::displayStar(int x, int y, int no)
00247 {
00248   mGameDisplay->displayStar(x, y, no);
00249 }
00250 
00251 // Display a hint on the board
00252 void KWin4View::displayHint(int x, int y)
00253 {
00254   mGameDisplay->displayHint(x, y, true);
00255 }
00256 
00257 // Slot called when a sprite animation move is done.
00258 void KWin4View::moveDone(QGraphicsItem* /*item*/, int mode)
00259 {
00260   emit signalMoveDone(mode);
00261 }
00262 
00263 #include "kwin4view.moc"

Generated on Sun Mar 4 10:56:43 2007 for KWin4 by  doxygen 1.4.6