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()) {
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);
00205 else
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);
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
00629 if (mode == -1 && scheme == -1) {
00630 scheme = cfg->readNumEntry("Scheme", -1);
00631 mode = cfg->readNumEntry("Mode", -1);
00632
00633
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))
00808 toggleHallOfFame();
00809
00810 emit setLevel(0);
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 :
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());
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 }