Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

referee.cpp

Go to the documentation of this file.
00001 
00002 #include "portable.h"
00003 
00004 #if defined( KDE2_PORT )
00005 #include <kapp.h>
00006 #include <kconfig.h>
00007 #include <kstddirs.h>
00008 #include <kaccel.h>
00009 #include <referee.h>
00010 #include <referee.moc>
00011 #elif defined( QPE_PORT )
00012 #include <qaccel.h>
00013 #include <qpe/qpeapplication.h>
00014 #include <qpe/config.h>
00015 #include "referee.h"
00016 #endif
00017 
00018 #include <stdlib.h>
00019 #include <qtimer.h>
00020 #include <qfileinfo.h>
00021 
00022 
00023 Referee::Referee( QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font)
00024     : QWidget( parent, name )
00025 {
00026     gameState.resize(12);
00027     gameTimer = 0;
00028     energizerTimer = 0;
00029 
00030     focusedPause = FALSE;
00031     setFocusPolicy(QWidget::StrongFocus);
00032 
00033     initKeys();
00034 
00035     scheme = Scheme;
00036     mode = Mode;
00037     confScheme();
00038 
00039     board = new Board(BoardWidth*BoardHeight);
00040 
00041     pix = new Painter(board, this, scheme, mode, font);
00042     setFixedSize(pix->levelPix().size());
00043 
00044     pacman = new Pacman(board);
00045 
00046     fruit = new Fruit(board);
00047 
00048     monsters = new QList<Monster>;
00049     monsters->setAutoDelete(TRUE);
00050 
00051     monsterRect = new QList<QRect>;
00052     monsterRect->setAutoDelete(TRUE);
00053 
00054     energizers = new QList<Energizer>;
00055     energizers->setAutoDelete(TRUE);
00056 
00057     energizerRect = new QList<QRect>;
00058     energizerRect->setAutoDelete(TRUE);
00059 
00060     pacmanRect.setRect(0, 0, 0, 0);
00061     fruitRect.setRect(0, 0, 0, 0);
00062 
00063     QTime midnight( 0, 0, 0 );
00064     srand( midnight.secsTo(QTime::currentTime()) );
00065 
00066     lifes = 0;
00067     points = 0;
00068 
00069     emit setLifes(lifes);
00070     emit setPoints(points);
00071 
00072     intro();
00073 }
00074 
00075 void Referee::paintEvent( QPaintEvent *e)
00076 {
00077     if (gameState.testBit(HallOfFame))
00078         return;
00079 
00080     QRect rect = e->rect();
00081 
00082     if (!rect.isEmpty()) {
00083         QPixmap p = pix->levelPix();
00084         bitBlt(this, rect.x(), rect.y(),
00085                &p, rect.x(), rect.y(), rect.width(), rect.height());
00086     }
00087 
00088     if ((gameState.testBit(GameOver) || gameState.testBit(Demonstration)) &&
00089         rect.intersects(pix->rect(board->position(fruithome), tr("GAME  OVER"))))
00090         pix->draw(board->position(fruithome), Widget, tr("GAME  OVER"), RED);
00091 
00092     for (Energizer *e = energizers->first(); e != 0; e = energizers->next()) {
00093         if (e && e->state() == on &&
00094             rect.intersects(pix->rect(e->position(), EnergizerPix)) &&
00095             !(e->position() == pacman->position() && gameState.testBit(Scoring))) {
00096             if (e->pix() != -1)
00097                 pix->draw(e->position(), Widget, EnergizerPix, e->pix());
00098         }
00099     }
00100 
00101     if (!gameState.testBit(Init)) {
00102 
00103         if (!gameState.testBit(Dying) && (fruit->pix() != -1))
00104             if (fruit->state() != active) {
00105                 if (rect.intersects(pix->rect(fruit->position(), FruitScorePix, fruit->pix())))
00106                     pix->draw(fruit->position(), Widget, FruitScorePix, fruit->pix());
00107             } else {
00108                 if (rect.intersects(pix->rect(fruit->position(), FruitPix, fruit->pix())))
00109                     pix->draw(fruit->position(), Widget, FruitPix, fruit->pix());
00110             }
00111 
00112         for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00113             if (m && m->state() == harmless &&
00114                 rect.intersects(pix->rect(m->position(), MonsterPix)) &&
00115                 !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
00116                 if (m->body() != -1)
00117                     pix->draw(m->position(), Widget, MonsterPix, m->body());
00118                 if (m->eyes() != -1)
00119                     pix->draw(m->position(), Widget, EyesPix, m->eyes());
00120             }
00121 
00122         if (!gameState.testBit(Scoring) && !gameState.testBit(LevelDone) &&
00123             rect.intersects(pix->rect(pacman->position(), PacmanPix)) && pacman->pix() != -1)
00124             pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
00125 
00126         for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00127             if (m && m->state() != harmless &&
00128                 rect.intersects(pix->rect(m->position(), MonsterPix)) &&
00129                 !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
00130                 if (m->body() != -1)
00131                     pix->draw(m->position(), Widget, MonsterPix, m->body());
00132                 if (m->eyes() != -1)
00133                     pix->draw(m->position(), Widget, EyesPix, m->eyes());
00134             }
00135     }
00136 
00137     if (gameState.testBit(Scoring) &&
00138         rect.intersects(pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)))
00139         pix->draw(pacman->position(), Widget, MonsterScorePix, monstersEaten-1);
00140 
00141     if (gameState.testBit(Init) && gameState.testBit(Dying) &&
00142         timerCount < pix->maxPixmaps(DyingPix) &&
00143         rect.intersects(pix->rect(pacman->position(), PacmanPix)))
00144         pix->draw(pacman->position(), Widget, DyingPix, timerCount);
00145 
00146     if (gameState.testBit(LevelDone) &&
00147         rect.intersects(pix->rect(pacman->position(), PacmanPix)))
00148         pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
00149 
00150     if (gameState.testBit(Player) &&
00151         rect.intersects(pix->rect(board->position(monsterhome, 0), tr("PLAYER ONE"))))
00152         pix->draw(board->position(monsterhome, 0), Widget, tr("PLAYER ONE"), CYAN);
00153 
00154     if (gameState.testBit(Ready) &&
00155         rect.intersects(pix->rect(board->position(fruithome), tr("READY!"))))
00156         pix->draw(board->position(fruithome), Widget, tr("READY!"), YELLOW);
00157 
00158     if (gameState.testBit(Paused) &&
00159         rect.intersects(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, tr("PAUSED"))))
00160         pix->draw((BoardWidth*BoardHeight)/2-BoardWidth, Widget, tr("PAUSED"), RED, BLACK);
00161 }
00162 
00163 void Referee::timerEvent( QTimerEvent *e )
00164 {
00165     if (gameState.testBit(HallOfFame))
00166         return;
00167 
00168     QRect lastRect;
00169     int lastPix;
00170     bool moved = FALSE;
00171     int eated = 0;
00172 
00173     if (e->timerId() == energizerTimer) {
00174         for (int e = 0; e < board->energizers(); e++) {
00175             lastRect = pix->rect(energizers->at(e)->position(), EnergizerPix);
00176             lastPix = energizers->at(e)->pix();
00177             if (energizers->at(e)->move()) {
00178                 moved = TRUE;
00179                 *energizerRect->at(e) = pix->rect(energizers->at(e)->position(), EnergizerPix);
00180                 if (lastPix == energizers->at(e)->pix() &&
00181                     lastRect == pix->rect(energizers->at(e)->position(), EnergizerPix))
00182                     energizerRect->at(e)->setRect(0, 0, 0, 0);
00183                 else
00184                     *energizerRect->at(e) = pix->rect(*energizerRect->at(e), lastRect);
00185             }
00186         }
00187 
00188         for (int e = 0; e < board->energizers(); e++)
00189             if (!energizerRect->at(e)->isNull())
00190                 repaint(*energizerRect->at(e), FALSE);
00191 
00192         return;
00193     }
00194 
00195     timerCount++;
00196 
00197     lastRect = pix->rect(pacman->position(), PacmanPix);
00198     lastPix = pacman->pix();
00199 
00200     if (moved = pacman->move()) {       // pacman really moved
00201         pacmanRect = pix->rect(pacman->position(), PacmanPix);
00202         if (lastPix == pacman->pix() &&
00203             lastRect == pix->rect(pacman->position(), PacmanPix))
00204             pacmanRect.setRect(0, 0, 0, 0);     // nothing to do, because the pixmap
00205         else                                    // and the position isn't changed.
00206             pacmanRect = pix->rect(pacmanRect, lastRect);
00207     } else
00208         pacmanRect.setRect(0, 0, 0, 0);
00209 
00210     int pos = pacman->position();
00211 
00212     if (moved && board->isMonster(pos) && !gameState.testBit(Dying)) {
00213         for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00214             if (m  && m->position() == pos) {
00215                 if (m->state() == harmless && !gameState.testBit(Dying)) {
00216                     m->setREM(remTicks[level]);
00217                     m->setDirection(X); // prevent movement before eaten()
00218                     eated++;
00219                     if (gameState.testBit(Introducing))
00220                         m->setPosition(OUT);
00221                 }
00222                 if (m->state() == dangerous && !gameState.testBit(Dying))
00223                     killed();
00224             }
00225     }
00226 
00227     if (moved && !gameState.testBit(Dying)) {
00228         if (board->isPoint(pos)) {
00229             board->reset(pos, Point);
00230             score(pointScore);
00231             pix->erase(pos, PointPix);
00232         }
00233         if (board->isEnergizer(pos)) {
00234             for (int e = 0; e < board->energizers();e++) {
00235                 if (energizers->at(e)->position() == pos) {
00236                     energizers->at(e)->setOff();
00237                   energizers->remove(e);
00238                   energizerRect->remove(e);
00239                   e = board->energizers();
00240                 }
00241             }
00242             board->reset(pos, energizer);
00243             score(energizerScore);
00244             monstersEaten = 0;
00245             for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00246                 if (m && m->state() != rem) {
00247                     m->setHarmless(harmlessTicks[level], harmlessDurTicks[level],
00248                                    harmlessWarnTicks[level]);
00249                     if (gameState.testBit(Introducing))
00250                         m->setDirection(board->turn(m->direction()));
00251                 }
00252         }
00253         if (pos == fruit->position() && fruit->state() == active) {
00254             fruit->setEaten(fruitScoreDurTicks[level]);
00255             initFruit(FALSE);
00256             score(fruitScore[fruit->pix()]);
00257         }
00258     }
00259 
00260     if (!gameState.testBit(Introducing)) {
00261         if (fruit->state() != active && fruit->pix() >= 0)
00262             lastRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
00263         else
00264             lastRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
00265 
00266         lastPix = fruit->pix();
00267         if (fruit->move()) {
00268             if (pos == fruit->position() && fruit->state() == active) {
00269                 fruit->setEaten(fruitScoreDurTicks[level]);
00270                 initFruit(FALSE);
00271                 score(fruitScore[fruit->pix()]);
00272             }
00273             if (fruit->state() != active && fruit->pix() >= 0)
00274                 fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
00275             else
00276                 fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
00277             if (lastPix == fruit->pix() && lastRect == fruitRect)
00278                 fruitRect.setRect(0, 0, 0, 0);
00279             else
00280                 fruitRect = pix->rect(fruitRect, lastRect);
00281         } else
00282             fruitRect.setRect(0, 0, 0, 0);
00283     } else
00284         fruitRect.setRect(0, 0, 0, 0);
00285 
00286     int lastBodyPix;
00287     int lastEyesPix;
00288 
00289     for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00290         if (m) {
00291             lastRect = pix->rect(m->position(), MonsterPix);
00292             lastBodyPix = m->body();
00293             lastEyesPix = m->eyes();
00294             if (m->move()) {
00295                 moved = TRUE;
00296                 *monsterRect->at(m->id()) = pix->rect(m->position(), MonsterPix);
00297                 if (lastBodyPix == m->body() && lastEyesPix == m->eyes() &&
00298                     lastRect == pix->rect(m->position(), MonsterPix))
00299                     monsterRect->at(m->id())->setRect(0, 0, 0, 0);
00300                 else
00301                     *monsterRect->at(m->id()) = pix->rect(*monsterRect->at(m->id()), lastRect);
00302                 if (m->position() == pos && !gameState.testBit(Dying)) {
00303                     if (m->state() == harmless && !gameState.testBit(Dying)) {
00304                         m->setREM(remTicks[level]);
00305                         eated++;
00306                         if (gameState.testBit(Introducing)) {
00307                             m->setPosition(OUT);
00308                             m->setDirection(X);
00309                         }
00310                     }
00311                     if (m->state() == dangerous && !gameState.testBit(Dying))
00312                         killed();
00313                 }
00314             } else
00315                 monsterRect->at(m->id())->setRect(0, 0, 0, 0);
00316         }
00317 
00318     for (int m = 0; m < board->monsters(); m++)
00319         if (pacmanRect.intersects(*monsterRect->at(m))) {
00320             pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
00321             monsterRect->at(m)->setRect(0, 0, 0, 0);
00322         } else
00323             for (int im = m+1; im < board->monsters(); im++)
00324                 if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
00325                     *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
00326                     monsterRect->at(im)->setRect(0, 0, 0, 0);
00327                 }
00328 
00329     if (!pacmanRect.isNull())
00330         repaint(pacmanRect, FALSE);
00331 
00332     if (!fruitRect.isNull())
00333         repaint(fruitRect, FALSE);
00334 
00335     for (int m = 0; m < board->monsters(); m++)
00336         if (!monsterRect->at(m)->isNull())
00337             repaint(*monsterRect->at(m), FALSE);
00338 
00339     if (board->points() == 0 && !gameState.testBit(Dying))
00340         levelUp();
00341 
00342     if (eated > 0 && !gameState.testBit(Dying)) {
00343         timerCount = eated;
00344         eaten();
00345     }
00346 
00347     if (gameState.testBit(Introducing) && moved)
00348         introPlay();
00349 }
00350 
00351 void Referee::repaintFigures()
00352 {
00353     pacmanRect = pix->rect(pacman->position(), PacmanPix);
00354 
00355     for (int e = 0; e < board->energizers(); e++) {
00356         *energizerRect->at(e) = pix->rect(board->position(energizer, e), EnergizerPix);
00357 
00358         if (pacmanRect.intersects(*energizerRect->at(e))) {
00359             pacmanRect = pix->rect(pacmanRect, *energizerRect->at(e));
00360             energizerRect->at(e)->setRect(0, 0, 0, 0);
00361         } else
00362             for (int ie = e+1; ie < board->energizers(); ie++)
00363                 if (energizerRect->at(e)->intersects(*energizerRect->at(ie))) {
00364                     *energizerRect->at(e) = pix->rect(*energizerRect->at(e), *energizerRect->at(ie));
00365                     energizerRect->at(ie)->setRect(0, 0, 0, 0);
00366                 }
00367     }
00368 
00369     if (fruit->pix() != -1 && fruit->state() != active)
00370         fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
00371     else
00372         fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
00373 
00374     if (pacmanRect.intersects(fruitRect)) {
00375         pacmanRect = pix->rect(pacmanRect, fruitRect);
00376         fruitRect.setRect(0, 0, 0, 0);
00377     }
00378 
00379     for (int m = 0; m < board->monsters(); m++) {
00380         *monsterRect->at(m) = pix->rect(board->position(monster, m), MonsterPix);
00381 
00382         if (pacmanRect.intersects(*monsterRect->at(m))) {
00383             pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
00384             monsterRect->at(m)->setRect(0, 0, 0, 0);
00385         } else
00386             for (int im = m+1; im < board->monsters(); im++)
00387                 if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
00388                     *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
00389                     monsterRect->at(im)->setRect(0, 0, 0, 0);
00390                 }
00391     }
00392 
00393     if (!pacmanRect.isNull())
00394         repaint(pacmanRect, FALSE);
00395 
00396     if (!fruitRect.isNull())
00397         repaint(fruitRect, FALSE);
00398 
00399     for (int m = 0; m < board->monsters(); m++)
00400         if (!monsterRect->at(m)->isNull())
00401             repaint(*monsterRect->at(m), FALSE);
00402 
00403     for (int e = 0; e < board->energizers(); e++)
00404         if (!energizerRect->at(e)->isNull())
00405             repaint(*energizerRect->at(e), FALSE);
00406 
00407 }
00408 
00409 void Referee::initKeys()
00410 {
00411     APP_CONFIG_BEGIN( cfg );
00412     QString up("Up");
00413     up = cfg->readEntry("upKey", (const char*) up);
00414     UpKey    = KAccel::stringToKey(up);
00415 
00416     QString down("Down");
00417     down = cfg->readEntry("downKey", (const char*) down);
00418     DownKey  = KAccel::stringToKey(down);
00419 
00420     QString left("Left");
00421     left = cfg->readEntry("leftKey", (const char*) left);
00422     LeftKey  = KAccel::stringToKey(left);
00423 
00424     QString right("Right");
00425     right = cfg->readEntry("rightKey", (const char*) right);
00426     RightKey = KAccel::stringToKey(right);
00427     APP_CONFIG_END( cfg );
00428 }
00429 
00430 void Referee::fillArray(QArray<int> &array, QString values, int max)
00431 {
00432     if (max < 0)
00433         max = values.contains(',')+1;
00434 
00435     array.resize(max);
00436     int last = 0;
00437     bool ok;
00438     QString value;
00439 
00440     for (uint i = 0; i < array.size(); i++) {
00441         if (values.find(',') < 0 &&  values.length() > 0) {
00442             value = values;
00443             values = "";
00444         }
00445         if (values.find(',') >= 0) {
00446             value = values.left(values.find(','));
00447             values.remove(0,values.find(',')+1);
00448         }
00449         array[i] = value.toInt(&ok);
00450         if (ok)
00451             last = array[i];
00452         else
00453             array[i] = last;
00454     }
00455 }
00456 
00457 void Referee::fillStrList(QStrList &list, QString values, int max)
00458 {
00459     if (!list.isEmpty())
00460         list.clear();
00461 
00462     QString last = "";
00463     QString value;
00464 
00465     for (uint i = 0; i < (uint) max; i++) {
00466         if (values.find(',') < 0 &&  values.length() > 0) {
00467             value = values;
00468             values = "";
00469         }
00470         if (values.find(',') >= 0) {
00471             value = values.left(values.find(','));
00472             values.remove(0,values.find(',')+1);
00473         }
00474         if (!value.isEmpty())
00475             last = value;
00476 
00477         list.append(last);
00478     }
00479 }
00480 
00481 void Referee::fillMapName()
00482 {
00483     QStrList list = mapName;
00484 
00485     if (!mapName.isEmpty())
00486                                 mapName.clear();
00487 
00488     QString map;
00489 
00490     QFileInfo fileInfo;
00491 
00492     for (uint i = 0; i < list.count(); i++) {
00493         map = list.at(i);
00494 
00495         if (map.left(1) != "/" && map.left(1) != "~")
00496                   map = FIND_APP_DATA( mapDirectory+map );
00497 
00498         fileInfo.setFile(map);
00499         if (!fileInfo.isReadable())
00500             map = "";
00501         
00502         mapName.append(map);
00503     }
00504 }
00505 
00506 void Referee::confLevels(bool defGroup)
00507 {
00508     APP_CONFIG_BEGIN( cfg );
00509     if (defGroup || cfg->hasKey("Levels"))
00510         maxLevel = cfg->readNumEntry("Levels", 13);
00511     APP_CONFIG_END( cfg );
00512 }
00513 
00514 void Referee::confMisc(bool defGroup)
00515 {
00516     APP_CONFIG_BEGIN( cfg );
00517     if (defGroup || cfg->hasKey("PixmapDirectory")) {
00518         pixmapDirectory = cfg->readEntry("PixmapDirectory");
00519 
00520         if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
00521                   pixmapDirectory.insert(0, "pics/");
00522         if (pixmapDirectory.right(1) != "/")
00523                   pixmapDirectory.append("/");
00524     }
00525 
00526     if (defGroup || cfg->hasKey("MapDirectory")) {
00527         mapDirectory = cfg->readEntry("MapDirectory");
00528 
00529         if (mapDirectory.left(1) != "/" && mapDirectory.left(1) != "~")
00530             mapDirectory.insert(0, "maps/");
00531         if (mapDirectory.right(1) != "/")
00532             mapDirectory.append("/");
00533     }
00534 
00535     if (defGroup || cfg->hasKey("MapName"))
00536         fillStrList(mapName, cfg->readEntry("MapName", "map"), maxLevel+1);
00537 
00538     if (defGroup || cfg->hasKey("MonsterIQ"))
00539         fillArray(monsterIQ, cfg->readEntry("MonsterIQ", "0,170,180,170,180,170,180"), maxLevel+1);
00540     if (defGroup || cfg->hasKey("FruitIQ"))
00541         fillArray(fruitIQ, cfg->readEntry("FruitIQ", "0,170,180,170,180,170,180"), maxLevel+1);
00542     if (defGroup || cfg->hasKey("FruitIndex"))
00543         fillArray(fruitIndex, cfg->readEntry("FruitIndex", "0"), maxLevel+1);
00544     APP_CONFIG_END( cfg );
00545 }
00546 
00547 void Referee::confTiming(bool defGroup)
00548 {
00549     APP_CONFIG_BEGIN( cfg );
00550     if (defGroup || cfg->hasKey("SpeedMS"))
00551         fillArray(speed, cfg->readEntry("SpeedMS", "20"), maxLevel+1);
00552     if (defGroup || cfg->hasKey("PacmanTicks"))
00553         fillArray(pacmanTicks,cfg->readEntry("PacmanTicks", "3"), maxLevel+1);
00554     if (defGroup || cfg->hasKey("RemTicks"))
00555         fillArray(remTicks, cfg->readEntry("RemTicks", "1"), maxLevel+1);
00556     if (defGroup || cfg->hasKey("DangerousTicks"))
00557         fillArray(dangerousTicks, cfg->readEntry("DangerousTicks", "3"), maxLevel+1);
00558     if (defGroup || cfg->hasKey("HarmlessTicks"))
00559         fillArray(harmlessTicks, cfg->readEntry("HarmlessTicks", "7,6,,5,,4"), maxLevel+1);
00560     if (defGroup || cfg->hasKey("HarmlessDurationTicks"))
00561         fillArray(harmlessDurTicks, cfg->readEntry("HarmlessDurationTicks", "375,,,300,,250,200,150"), maxLevel+1);
00562     if (defGroup || cfg->hasKey("HarmlessWarningTicks"))
00563         fillArray(harmlessWarnTicks, cfg->readEntry("HarmlessWarningTicks", "135"), maxLevel+1);
00564     if (defGroup || cfg->hasKey("ArrestTicks"))
00565         fillArray(arrestTicks, cfg->readEntry("ArrestTicks", "6"), maxLevel+1);
00566     if (defGroup || cfg->hasKey("ArrestDurationTicks"))
00567         fillArray(arrestDurTicks, cfg->readEntry("ArrestDurationTicks", "200,,,150"), maxLevel+1);
00568     if (defGroup || cfg->hasKey("FruitTicks"))
00569         fillArray(fruitTicks, cfg->readEntry("FruitTicks", "7,6,,5,,4"), maxLevel+1);
00570     if (defGroup || cfg->hasKey("FruitAppearsTicks"))
00571         fillArray(fruitAppearsTicks, cfg->readEntry("FruitAppearsTicks", "1000,,1500,2000,2500,3000,3500,4000"), maxLevel+1);
00572     if (defGroup || cfg->hasKey("FruitDurationTicks"))
00573         fillArray(fruitDurTicks, cfg->readEntry("FruitDurationTicks", "500,,,400,350,300,,250,200,150"), maxLevel+1);
00574     if (defGroup || cfg->hasKey("FruitScoreDurationTicks"))
00575         fillArray(fruitScoreDurTicks, cfg->readEntry("FruitScoreDurationTicks", "150"), maxLevel+1);
00576 
00577     if (defGroup || cfg->hasKey("MonsterScoreDurationMS"))
00578         monsterScoreDurMS = cfg->readNumEntry("MonsterScoreDurationMS", 1000);
00579     if (defGroup || cfg->hasKey("PlayerDurationMS"))
00580         playerDurMS = cfg->readNumEntry("PlayerDurationMS", 3000);
00581     if (defGroup || cfg->hasKey("ReadyDurationMS"))
00582         readyDurMS = cfg->readNumEntry("ReadyDurationMS", 2000);
00583     if (defGroup || cfg->hasKey("GameOverDurationMS"))
00584         gameOverDurMS = cfg->readNumEntry("GameOverDurationMS", 3000);
00585     if (defGroup || cfg->hasKey("AfterPauseMS"))
00586         afterPauseMS = cfg->readNumEntry("AfterPauseMS", 1000);
00587     if (defGroup || cfg->hasKey("DyingPreAnimationMS"))
00588         dyingPreAnimationMS = cfg->readNumEntry("DyingPreAnimationMS", 1000);
00589     if (defGroup || cfg->hasKey("DyingAnimationMS"))
00590         dyingAnimationMS = cfg->readNumEntry("DyingAnimationMS", 100);
00591     if (defGroup || cfg->hasKey("DyingPostAnimationMS"))
00592         dyingPostAnimationMS = cfg->readNumEntry("DyingPostAnimationMS", 500);
00593     if (defGroup || cfg->hasKey("IntroAnimationMS"))
00594         introAnimationMS = cfg->readNumEntry("IntroAnimationMS", 800);
00595     if (defGroup || cfg->hasKey("IntroPostAnimationMS"))
00596         introPostAnimationMS = cfg->readNumEntry("IntroPostAnimationMS", 1000);
00597     if (defGroup || cfg->hasKey("LevelUpPreAnimationMS"))
00598         levelUpPreAnimationMS = cfg->readNumEntry("LevelUpPreAnimationMS", 2000);
00599     if (defGroup || cfg->hasKey("LevelUpAnimationMS"))
00600         levelUpAnimationMS = cfg->readNumEntry("LevelUpAnimationMS", 2000);
00601     if (defGroup || cfg->hasKey("EnergizerAnimationMS"))
00602         energizerAnimationMS = cfg->readNumEntry("EnergizerAnimationMS", 200);
00603     APP_CONFIG_END( cfg );
00604 }
00605 
00606 void Referee::confScoring(bool defGroup)
00607 {
00608     APP_CONFIG_BEGIN( cfg );
00609     if (defGroup || cfg->hasKey("PointScore"))
00610         pointScore = cfg->readNumEntry("PointScore", 10);
00611     if (defGroup || cfg->hasKey("EnergizerScore"))
00612         energizerScore = cfg->readNumEntry("EnergizerScore", 50);
00613     if (defGroup || cfg->hasKey("FruitScore"))
00614         fillArray(fruitScore, cfg->readEntry("FruitScore", "100,300,500,,700,,1000,,2000,,3000,,5000"), maxLevel+1);
00615     if (defGroup || cfg->hasKey("MonsterScore"))
00616         fillArray(monsterScore, cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
00617     if (defGroup || cfg->hasKey("ExtraLifeScore"))
00618         fillArray(extraLifeScore, cfg->readEntry("ExtraLifeScore", "10000"), -1);
00619     APP_CONFIG_END( cfg );
00620 }
00621 
00622 void Referee::confScheme()
00623 {
00624     APP_CONFIG_BEGIN( cfg );
00625     SAVE_CONFIG_GROUP( cfg, oldgroup );
00626     QString newgroup;
00627 
00628     // if not set, read mode and scheme from the configfile
00629     if (mode == -1 && scheme == -1) {
00630         scheme = cfg->readNumEntry("Scheme", -1);
00631         mode = cfg->readNumEntry("Mode", -1);
00632 
00633         // if mode is not set in the defGroup-group, lookup the scheme group
00634         if (scheme != -1 || mode == -1) {
00635             newgroup.sprintf("Scheme %d", scheme);
00636             cfg->setGroup(newgroup);
00637 
00638             mode = cfg->readNumEntry("Mode", -1);
00639             RESTORE_CONFIG_GROUP( cfg, oldgroup );
00640         }
00641     }
00642 
00643     confLevels();
00644 
00645     if (mode != -1) {
00646         newgroup.sprintf("Mode %d", mode);
00647         cfg->setGroup(newgroup);
00648 
00649         confLevels(FALSE);
00650     }
00651 
00652     if (scheme != -1) {
00653         newgroup.sprintf("Scheme %d", scheme);
00654         cfg->setGroup(newgroup);
00655 
00656         confLevels(FALSE);
00657     }
00658 
00659     RESTORE_CONFIG_GROUP( cfg, oldgroup );
00660 
00661     confMisc();
00662     confTiming();
00663     confScoring();
00664 
00665     if (mode != -1) {
00666         newgroup.sprintf("Mode %d", mode);
00667         cfg->setGroup(newgroup);
00668 
00669         confMisc(FALSE);
00670         confTiming(FALSE);
00671         confScoring(FALSE);
00672     }
00673 
00674     if (scheme != -1) {
00675         newgroup.sprintf("Scheme %d", scheme);
00676         cfg->setGroup(newgroup);
00677 
00678         confMisc(FALSE);
00679         confTiming(FALSE);
00680         confScoring(FALSE);
00681     }
00682 
00683     fillMapName();
00684 
00685     RESTORE_CONFIG_GROUP( cfg, oldgroup );
00686     APP_CONFIG_END( cfg );
00687 }
00688 
00689 void Referee::setScheme(int Scheme, int Mode, Bitfont *font)
00690 {
00691     mode = Mode;
00692     scheme = Scheme;
00693 
00694     confScheme();
00695 
00696     pix->setScheme(scheme, mode, font);
00697 
00698     pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
00699     fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
00700 
00701     for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00702         if (m)
00703             m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
00704 
00705     for (Energizer *e = energizers->first(); e != 0; e = energizers->next())
00706         if (e)
00707             e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
00708 
00709     if (gameState.testBit(Introducing))
00710         for (int i = 0; i < (gameState.testBit(Init) ? timerCount : 15); i++)
00711             introPaint(i);
00712 
00713     setFixedSize(pix->levelPix().size());
00714     repaint();
00715 }
00716 
00717 void Referee::keyPressEvent( QKeyEvent *k )
00718 {
00719     uint key = k->key();
00720 
00721     if ( !gameState.testBit(Playing) && ( key == Key_Up || key == Key_Down || key == Key_Left || key == Key_Right ) )
00722         play();
00723 
00724     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame) ||
00725         gameState.testBit(Demonstration) || gameState.testBit(Dying) ||
00726         gameState.testBit(Ready) || gameState.testBit(LevelDone) ||
00727         !gameState.testBit(Playing))
00728         return;
00729 
00730     if (key == UpKey)
00731         pacman->setDirection(N);
00732     else if (key == DownKey)
00733         pacman->setDirection(S);
00734     else if (key == RightKey)
00735         pacman->setDirection(E);
00736     else if (key == LeftKey)
00737         pacman->setDirection(W);
00738 
00739 #ifdef CHEATS
00740     else if (key == Key_L) { printf("levelUp()\n"); levelUp(); }
00741     else if (key == Key_F) { printf("fruit->move(TRUE)\n"); fruit->move(TRUE); repaint(FALSE); }
00742     else if (key == Key_E) { printf("setLifes(++lifes)\n"); emit setLifes(++lifes); }
00743 #endif
00744 
00745     else {
00746         k->ignore();
00747         return;
00748     }
00749     k->accept();
00750 }
00751 
00752 void Referee::score(int p)
00753 {
00754     if (!gameState.testBit(Playing))
00755         return;
00756 
00757     if ((points += p) < 0)
00758         points = 0;
00759 
00760     emit setPoints(points);
00761 
00762     if (points >= nextExtraLifeScore) {
00763         emit setLifes(++lifes);
00764         if (extraLifeScoreIndex < (int) extraLifeScore.size()-1)
00765             extraLifeScoreIndex++;
00766         if (extraLifeScore[extraLifeScoreIndex] < 0)
00767             nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex] * -1;
00768         else
00769             nextExtraLifeScore += extraLifeScore[extraLifeScoreIndex];
00770     }
00771 }
00772 
00773 void Referee::eaten()
00774 {
00775     if (gameState.testBit(Ready))
00776         return;
00777 
00778     stop();
00779 
00780     if (monstersEaten < 4)
00781         monstersEaten++;
00782 
00783     gameState.setBit(Scoring);
00784     score(monsterScore[monstersEaten-1]);
00785 
00786     repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
00787                       pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
00788 
00789     if (--timerCount > 0)
00790         QTimer::singleShot( monsterScoreDurMS, this, SLOT(eaten()));
00791     else {
00792         for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00793             if (m && m->direction() == X && !gameState.testBit(Introducing))
00794                 m->setDirection(N);
00795         if (monstersEaten != 4 || !gameState.testBit(Introducing))
00796             QTimer::singleShot( monsterScoreDurMS, this, SLOT(start()));
00797     }
00798 }
00799 
00800 void Referee::toggleHallOfFame()
00801 {
00802     gameState.toggleBit(HallOfFame);
00803 }
00804 
00805 void Referee::hallOfFame()
00806 {
00807     if (gameState.testBit(HallOfFame))  // If the HallOfFame is switched on manually, toggle the
00808         toggleHallOfFame();             // bit twice.
00809 
00810     emit setLevel(0);                   // Clear status display for hall of fame
00811     emit setScore(level, 0);
00812     emit forcedHallOfFame(TRUE);
00813 }
00814 
00815 void Referee::pause()
00816 {
00817     static int pausedTimer = 0;
00818 
00819     if (!gameState.testBit(Paused)) {
00820         pausedTimer = gameTimer;
00821         stop();
00822         stopEnergizer();
00823         gameState.setBit(Paused);
00824         repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, tr("PAUSED")), FALSE);
00825     } else {
00826         gameState.clearBit(Paused);
00827         repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, tr("PAUSED")), FALSE);
00828         if (pausedTimer) {
00829             pausedTimer = 0;
00830             start();
00831         }
00832     }
00833     emit togglePaused();
00834 }
00835 
00836 void Referee::intro()
00837 {
00838     stop();
00839     stopEnergizer();
00840     bool paused = gameState.testBit(Paused);
00841 
00842     gameState.fill(FALSE);
00843     gameState.setBit(Introducing);
00844     gameState.setBit(Init);
00845 
00846     if (paused)
00847         gameState.setBit(Paused);
00848 
00849     level = 0;
00850     emit setLevel(level);
00851 
00852     board->init(Intro);
00853     pix->setLevel(level);
00854 
00855     initPacman();
00856     initFruit();
00857     initMonsters();
00858     initEnergizers();
00859 
00860     repaint();
00861 
00862     monstersEaten = 0;
00863     timerCount = 0;
00864     introPlay();
00865 }
00866 
00867 void Referee::introMonster(int id)
00868 {
00869     Monster *m = new Monster(board, id);
00870 
00871     m->setPosition((10+id*6)*BoardWidth+10);
00872     m->setDirection(E);
00873     m->setDangerous(dangerousTicks[level], monsterIQ[level]);
00874     m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
00875 
00876     if (m->body() != -1)
00877         pix->draw(m->position(), RoomPix, MonsterPix, m->body());
00878     if (m->eyes() != -1)
00879         pix->draw(m->position(), RoomPix, EyesPix, m->eyes());
00880 
00881     repaint(pix->rect(m->position(), MonsterPix), FALSE);
00882     m->setPosition(OUT);
00883 }
00884 
00885 void Referee::introPaint(int t)
00886 {
00887     QString pts;
00888 
00889     switch (t) {
00890         case  0 : repaint(pix->draw(16, 6, RoomPix, tr("CHARACTER"), WHITE, QColor(), AlignLeft), FALSE);
00891                   repaint(pix->draw(36, 6, RoomPix, tr("/"), WHITE, QColor(), AlignLeft), FALSE);
00892                   repaint(pix->draw(40, 6, RoomPix, tr("NICKNAME"), WHITE, QColor(), AlignLeft), FALSE);
00893                   break;
00894         case  1 : introMonster(0);
00895                   break;
00896         case  2 : repaint(pix->draw(16, 10, RoomPix, tr("-SHADOW"), RED, QColor(), AlignLeft), FALSE);
00897                   break;
00898         case  3 : repaint(pix->draw(38, 10, RoomPix, tr("\"BLINKY\""), RED, QColor(), AlignLeft), FALSE);
00899                   break;
00900         case  4 : introMonster(1);
00901                   break;
00902         case  5 : repaint(pix->draw(16, 16, RoomPix, tr("-SPEEDY"), PINK, QColor(), AlignLeft), FALSE);
00903                   break;
00904         case  6 : repaint(pix->draw(38, 16, RoomPix, tr("\"PINKY\""), PINK, QColor(), AlignLeft), FALSE);
00905                   break;
00906         case  7 : introMonster(2);
00907                   break;
00908         case  8 : repaint(pix->draw(16, 22, RoomPix, tr("-BASHFUL"), CYAN, QColor(), AlignLeft), FALSE);
00909                   break;
00910         case  9 : repaint(pix->draw(38, 22, RoomPix, tr("\"INKY\""), CYAN, QColor(), AlignLeft), FALSE);
00911                   break;
00912         case 10 : introMonster(3);
00913                   break;
00914         case 11 : repaint(pix->draw(16, 28, RoomPix, tr("-POKEY"), ORANGE, QColor(), AlignLeft), FALSE);
00915                   break;
00916         case 12 : repaint(pix->draw(38, 28, RoomPix, tr("\"CLYDE\""), ORANGE, QColor(), AlignLeft), FALSE);
00917                   break;
00918         case 13 : pts.sprintf("%d", pointScore);
00919                   repaint(pix->draw(28, 44, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
00920                   repaint(pix->draw(31, 44, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
00921                   pts.sprintf("%d", energizerScore);
00922                   repaint(pix->draw(28, 48, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
00923                   repaint(pix->draw(31, 48, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
00924                   break;
00925         case 14 : // "@ 1980 MIDWAY MFG.CO."
00926 #if defined( KDE2_PORT )
00927                   repaint(pix->draw(30, 58, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
00928 #elif defined( QPE_PORT )
00929                   repaint(pix->draw(30, 55, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
00930                   repaint(pix->draw(29, 58, RoomPix, tr("QTOPIA PORT: CATALIN CLIMOV"), GREEN), FALSE);
00931                   repaint(pix->draw(29, 61, RoomPix, tr("PRESS CURSOR TO START"), GREEN), FALSE);
00932 #endif
00933                   break;
00934     }
00935 }
00936 
00937 void Referee::introPlay()
00938 {
00939     if (!gameState.testBit(Introducing) || gameState.testBit(Ready))
00940         return;
00941     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
00942         QTimer::singleShot(afterPauseMS, this, SLOT(introPlay()));
00943         return;
00944     }
00945 
00946     if (!gameState.testBit(Init)) {
00947         if (monstersEaten == 4) {
00948             stop();
00949             QTimer::singleShot(introPostAnimationMS, this, SLOT(demo()));
00950         }
00951         if (pacman->direction() == W) {
00952             int id = -1;
00953             if (pacman->position() == 37*BoardWidth-6)
00954                 id = 0;
00955             else
00956                 if (board->isMonster(37*BoardWidth-6))
00957                     for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00958                         if (m && m->position() == 37*BoardWidth-6) {
00959                             id = m->id();
00960                             id++;
00961                             break;
00962                         }
00963                 
00964             if (id >= 0 && id <= 4)
00965                 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
00966                     if (m && m->id() == id && m->position() == OUT) {
00967                         m->setPosition(37*BoardWidth-1);
00968                         m->setDirection(W);
00969                         m->setDangerous(dangerousTicks[level], monsterIQ[level]);
00970                         board->set(37*BoardWidth-1, monsterhome, id);
00971                         repaint(pix->rect(m->position(), MonsterPix));
00972                         break;
00973                     }
00974         }
00975         return;
00976     }
00977 
00978     if (timerCount < 15)
00979         introPaint(timerCount);
00980 
00981     switch (timerCount) {
00982         case 13 : board->set(44*BoardWidth+22, Point);
00983                   pix->drawPoint(44*BoardWidth+22);
00984                   repaint(pix->rect(44*BoardWidth+22, PointPix), FALSE);
00985                   energizers->at(0)->setPosition(48*BoardWidth+22);
00986                   energizers->at(0)->setOn();
00987                   repaint(pix->rect(48*BoardWidth+22, EnergizerPix), FALSE);
00988                   break;
00989         case 14 : energizers->at(1)->setPosition(36*BoardWidth+10);
00990                   energizers->at(1)->setOn();
00991                   repaint(pix->rect(36*BoardWidth+10, EnergizerPix), FALSE);
00992                   for (int pos = 8; pos < BoardWidth; pos++) {
00993                       board->set(34*BoardWidth+pos, out);
00994                       board->set(38*BoardWidth+pos, out);
00995                   }
00996                   board->set(36*BoardWidth+8, out);
00997                   break;
00998         case 15 : gameState.clearBit(Init);
00999                   initPacman();
01000                   pacman->setDemo(TRUE);
01001                   pacman->setPosition(37*BoardWidth-1);
01002                   repaintFigures();
01003                   start();
01004                   return;               
01005     }
01006 
01007     if (timerCount++ < 15)
01008         QTimer::singleShot(introAnimationMS, this, SLOT(introPlay()));
01009 }
01010 
01011 void Referee::demo()
01012 {
01013     if (gameState.testBit(Ready))
01014         return;
01015 
01016     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {   
01017         QTimer::singleShot(afterPauseMS, this, SLOT(demo()));
01018         return;
01019     }
01020 
01021     stop();
01022     stopEnergizer();
01023 
01024     gameState.fill(FALSE);
01025     gameState.setBit(Init);
01026     gameState.setBit(Demonstration);
01027 
01028     level = 0;
01029     emit setLevel(level);
01030 
01031     board->init(Demo, mapName.at(0));
01032     pix->setLevel(level);
01033 
01034     initPacman();
01035     initFruit();
01036     initMonsters();
01037     initEnergizers();
01038 
01039     gameState.clearBit(Init);
01040 
01041     repaint();
01042 
01043     timerCount = 0;
01044     QTimer::singleShot(playerDurMS, this, SLOT(start()));
01045 }
01046 
01047 void Referee::play()
01048 {
01049     stop();
01050     stopEnergizer();
01051 
01052     gameState.fill(FALSE);
01053     gameState.setBit(Init);
01054     gameState.setBit(Playing);
01055     gameState.setBit(Player);
01056     gameState.setBit(Ready);
01057 
01058     lifes = 3;
01059     level = 1;
01060     points = 0;
01061 
01062     extraLifeScoreIndex = 0;
01063     nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex];
01064     if (nextExtraLifeScore < 0)
01065         nextExtraLifeScore *= -1;
01066 
01067     board->init(Level, mapName.at(level));
01068     pix->setLevel(level);
01069 
01070     initPacman();
01071     initFruit();
01072     initMonsters();
01073     initEnergizers();
01074 
01075     repaint();
01076     emit toggleNew();
01077     emit setLifes(lifes);
01078     emit setLevel(level);
01079     emit setPoints(points);
01080 
01081     repaint(pix->rect(board->position(monsterhome, 0), tr("PLAYER ONE")), FALSE);
01082     repaint(pix->rect(board->position(fruithome), tr("READY!")), FALSE);
01083 
01084     timerCount = 0;
01085     QTimer::singleShot(playerDurMS, this, SLOT(ready()));
01086 }
01087 
01088 void Referee::ready()
01089 {
01090     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
01091         QTimer::singleShot(afterPauseMS, this, SLOT(ready()));
01092         return;
01093     }
01094 
01095     if (gameState.testBit(Player)) {
01096         emit setLifes(--lifes);
01097         gameState.clearBit(Player);
01098         gameState.clearBit(Init);
01099         repaint(pix->rect(board->position(monsterhome, 0), tr("PLAYER ONE")), FALSE);
01100         repaintFigures();
01101         QTimer::singleShot(playerDurMS, this, SLOT(ready()));
01102         return;
01103     }
01104 
01105     if (gameState.testBit(Ready)) {
01106         gameState.clearBit(Ready);
01107         repaint(pix->rect(board->position(fruithome), tr("READY!")), FALSE);
01108         start();
01109     } else {
01110         gameState.setBit(Ready);
01111         gameState.clearBit(Init);
01112         repaint(pix->rect(board->position(fruithome), tr("READY!")), FALSE);
01113         QTimer::singleShot(readyDurMS, this, SLOT(ready()));
01114     }
01115 }
01116 
01117 
01118 void Referee::levelUp()
01119 {
01120     stop();
01121     stopEnergizer();
01122 
01123     gameState.setBit(LevelDone);
01124     pacman->setPosition(pacman->position());    // set mouthPosition to "0"
01125     repaint(pix->rect(pacman->position(), PacmanPix));
01126 
01127     timerCount = 0;
01128     QTimer::singleShot(levelUpPreAnimationMS, this, SLOT(levelUpPlay()));
01129 }
01130 
01131 void Referee::levelUpPlay()
01132 {
01133     if (gameState.testBit(Ready))
01134         return;
01135 
01136     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
01137         QTimer::singleShot(afterPauseMS, this, SLOT(levelUpPlay()));
01138         return;
01139     }
01140 
01141     switch (timerCount) {
01142         case 0 : gameState.setBit(Init);
01143                  setOnEnergizers();
01144                  repaintFigures();
01145                  break;
01146         case 1 : gameState.clearBit(LevelDone);
01147                  repaint(pix->rect(pacman->position(), PacmanPix));
01148                  break;
01149     }
01150 
01151     if (timerCount++ < 2) {
01152         QTimer::singleShot(levelUpAnimationMS, this, SLOT(levelUpPlay()));
01153         return;
01154     }
01155 
01156     gameState.clearBit(Init);
01157 
01158     if (gameState.testBit(Demonstration)) {
01159         hallOfFame();
01160         return;
01161     }
01162 
01163     if (level < maxLevel)
01164         level++;
01165 
01166     board->init(Level, mapName.at(level));
01167     pix->setLevel(level);
01168 
01169     initPacman();
01170     initFruit();
01171     initMonsters();
01172     initEnergizers();
01173 
01174     repaint();
01175     emit setLevel(level);
01176 
01177     ready();
01178 }
01179 
01180 void Referee::start()
01181 {
01182     if (gameState.testBit(Ready))
01183         return;
01184 
01185     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
01186         QTimer::singleShot(afterPauseMS, this, SLOT(start()));
01187         return;
01188     }
01189 
01190     if (gameState.testBit(Scoring)) {
01191         gameState.clearBit(Scoring);
01192         repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
01193                           pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
01194     }
01195         
01196     if (!gameTimer)
01197         gameTimer = startTimer( speed [level] );
01198 
01199     if (!energizerTimer)
01200         energizerTimer = startTimer( energizerAnimationMS );
01201 }
01202 
01203 void Referee::start(int t)
01204 {
01205     gameTimer = startTimer(t);
01206 }
01207 
01208 void Referee::stop()
01209 {
01210     if (gameTimer) {
01211         killTimer (gameTimer);
01212         gameTimer = 0;
01213     }
01214 }
01215 
01216 void Referee::stopEnergizer()
01217 {
01218     if (energizerTimer) {
01219         killTimer (energizerTimer);
01220         energizerTimer = 0;
01221     }
01222 }
01223 
01224 void Referee::killed()
01225 {
01226     if (gameState.testBit(Ready))
01227         return;
01228 
01229     if (!gameState.testBit(Dying)) {
01230         gameState.setBit(Dying);
01231 
01232         pacman->setDirection(X, TRUE);
01233         for (Monster *m = monsters->first(); m != 0; m = monsters->next())
01234             if (m)
01235                 m->setDirection(X);
01236         QTimer::singleShot(dyingPreAnimationMS, this, SLOT(killed()));
01237     } else {
01238         stop();
01239         if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
01240             QTimer::singleShot(afterPauseMS, this, SLOT(killed()));
01241             return;
01242         }
01243 
01244         gameState.setBit(Init);
01245 
01246         repaintFigures();
01247 
01248         timerCount = 0;
01249         killedPlay();
01250     }
01251 }
01252 
01253 void Referee::killedPlay()
01254 {
01255     if (!gameState.testBit(Dying) || gameState.testBit(Ready))
01256         return;
01257     if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
01258         QTimer::singleShot(afterPauseMS, this, SLOT(killedPlay()));
01259         return;
01260     }
01261 
01262     if (timerCount <= pix->maxPixmaps(DyingPix)) {
01263         repaint(pix->rect(pacman->position(), PacmanPix), FALSE);
01264         if (timerCount >= pix->maxPixmaps(DyingPix)-1 || timerCount == 0)
01265             QTimer::singleShot(dyingPostAnimationMS, this, SLOT(killedPlay()));
01266         else
01267             QTimer::singleShot(dyingAnimationMS, this, SLOT(killedPlay()));
01268         timerCount++;
01269     } else {
01270         gameState.clearBit(Dying);
01271         stopEnergizer();
01272         if (lifes == 0) {
01273             gameState.setBit(GameOver);
01274             gameState.clearBit(Playing);
01275             for (int e = 0; e < board->energizers(); e++) {
01276                 energizers->at(e)->setOff();
01277                 repaint(pix->rect(board->position(energizer, e), EnergizerPix), FALSE);
01278             }
01279             repaint(pix->rect(board->position(fruithome), tr("GAME  OVER")), FALSE);
01280             QTimer::singleShot(gameOverDurMS, this, SLOT(hallOfFame()));
01281         } else {
01282             gameState.clearBit(Init);
01283             initPacman();
01284             initFruit();
01285             initMonsters();
01286             initEnergizers();
01287             emit setLifes(--lifes);
01288             repaintFigures();
01289             ready();
01290         }
01291     }
01292 }
01293 
01294 void Referee::initPacman()
01295 {
01296     pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
01297     pacman->setDemo(gameState.testBit(Demonstration));
01298     pacman->setPosition(board->position(pacmanhome));
01299     pacman->setDirection(W, TRUE);
01300     pacman->setAlive(pacmanTicks[level]);
01301 }
01302 
01303 void Referee::initFruit(bool fullInitialization)
01304 {
01305     if (fullInitialization) {
01306         fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
01307         if (fruitIndex[level] == 0)
01308             fruit->setLevel(level, fruitAppearsTicks[level],
01309                             fruitDurTicks[level], fruitTicks[level]);
01310         else if (fruitIndex[level] < 0)
01311             fruit->setLevel(pix->maxPixmaps(FruitPix)+1,
01312                             fruitAppearsTicks[level],
01313                             fruitDurTicks[level], fruitTicks[level]);
01314         else
01315             fruit->setLevel(fruitIndex[level], fruitAppearsTicks[level],
01316                             fruitDurTicks[level], fruitTicks[level]);
01317     }
01318 
01319     if (board->tunnels() > 0)
01320         fruit->setMovement(board->position(tunnel, rand() % board->tunnels()),
01321                            board->position(tunnel, rand() % board->tunnels()),
01322                            fruitIQ[level]);
01323 }
01324 
01325 void Referee::initMonsters()
01326 {
01327     if( !monsters->isEmpty())
01328         monsters->clear();
01329     if( !monsterRect->isEmpty())
01330         monsterRect->clear();
01331 
01332     for (int id = 0; id < (gameState.testBit(Introducing) ? 4 : board->monsters()); id++) {
01333         Monster *m = new Monster(board, id);
01334         monsters->append(m);
01335         QRect *r = new QRect();
01336         monsterRect->append(r);
01337         if (!gameState.testBit(Introducing)) {
01338             m->setFreedom(board->position(prisonexit));
01339             m->setDangerous(dangerousTicks[level], monsterIQ[level]);
01340             if (id == 0)
01341                 m->setPrison(board->position(prisonentry));
01342             else {
01343                 m->setPrison(board->position(monsterhome, id));
01344                 m->setArrested(arrestTicks[level], arrestDurTicks[level]*id);
01345             }
01346             m->setPosition(board->position(monsterhome, id));
01347             switch(id) {
01348                 case 0  : m->setDirection(W); break;
01349                 case 1  : m->setDirection(N); break;
01350                 default : m->setDirection(S);
01351             }
01352         }
01353         m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
01354     }
01355 }
01356 
01357 void Referee::initEnergizers()
01358 {
01359     if( !energizers->isEmpty())
01360         energizers->clear();
01361     if( !energizerRect->isEmpty())
01362         energizerRect->clear();
01363 
01364     for (int id = 0; id < (gameState.testBit(Introducing) ? 2 : board->energizers()); id++) {
01365         Energizer *e = new Energizer(board);
01366         energizers->append(e);
01367         QRect *r = new QRect();
01368         energizerRect->append(r);
01369         if (!gameState.testBit(Introducing)) {
01370             e->setPosition(board->position(energizer, id));
01371             e->setOn();
01372         }
01373         e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
01374     }
01375 }
01376 
01377 void Referee::setOnEnergizers()
01378 {
01379     for (int e = 0; e < board->energizers(); e++) {
01380         energizers->at(e)->setOn();
01381     }
01382 }
01383 
01384 void Referee::setFocusOutPause(bool FocusOutPause)
01385 {
01386     focusOutPause = FocusOutPause;
01387 }
01388 
01389 void Referee::setFocusInContinue(bool FocusInContinue)
01390 {
01391     focusInContinue = FocusInContinue;
01392 }
01393 
01394 void Referee::focusInEvent(QFocusEvent *)
01395 {
01396     if (focusInContinue && focusedPause &&
01397         gameState.testBit(Paused) && gameState.testBit(Playing)) {
01398         pause();
01399     }
01400 }
01401 
01402 void Referee::focusOutEvent(QFocusEvent *)
01403 {
01404     if (focusOutPause && !gameState.testBit(Paused) && gameState.testBit(Playing)) {
01405         focusedPause = TRUE;
01406         pause();
01407     }
01408 }

Generated on Sat Nov 5 16:17:22 2005 for OPIE by  doxygen 1.4.2