Commit 8ac4f471 authored by Ian Wadham's avatar Ian Wadham

Fix dig timing. Fix a crash when digging bricks and then changing themes....

Fix dig timing. Fix a crash when digging bricks and then changing themes. Re-implement some debug aids. Improve the animation of dug bricks. Show the hero and enemies in front of dug bricks. Improve the animations for standing and falling runners. Factor out some common code in the hero and enemy run() methods. Clean up some obsolete or redundant graphics code.

svn path=/trunk/KDE/kdegames/kgoldrunner/; revision=975751
parent 1eb90e48
......@@ -29,6 +29,11 @@
#include <cmath>
const StartFrame animationStartFrames [nAnimationTypes] = {
RIGHTWALK1, LEFTWALK1, RIGHTCLIMB1, LEFTCLIMB1,
CLIMB1, CLIMB1, FALL1, FALL2,
(StartFrame) 0, // Calculate OPEN_BRICK frame later.
(StartFrame) 0}; // Calculate CLOSE_BRICK frame later.
// Helper function: find how many tiles are needed to cover at least w pixels
static int numSections(int w, int sectionWidth)
......@@ -57,7 +62,8 @@ KGrCanvas::KGrCanvas (QWidget * parent, const double scale,
m_livesDisplay(0),
m_fadingTimeLine (1000, this),
emptySprites (0),
theme (systemDataDir)
theme (systemDataDir),
heroId (0)
{
resizeCount = 0; // IDW
......@@ -532,23 +538,26 @@ int KGrCanvas::makeSprite (const char type, int i, int j)
emptySprites = 0;
}
int z = 0;
int frame1 = FALL1;
double scale = (double) imgW / (double) bgw;
switch (type) {
case HERO:
heroId = spriteId;
sprite->addFrames (heroFrames, topLeft, scale);
z = 1;
sprite->setZ (1);
break;
case ENEMY:
sprite->addFrames (enemyFrames, topLeft, scale);
z = 2;
sprite->setZ (2);
break;
case BRICK:
sprite->addFrames (tileset, topLeft, scale);
frame1 = KGrTheme::BrickTile;
z = 1;
frame1 = KGrTheme::BrickAnimation1Tile;
// The hero and enemies must be painted in front of dug bricks.
sprite->stackUnder (sprites->at (heroId));
// Erase the brick-image so that animations are visible in all themes.
paintCell (i, j, FREE, 0);
break;
......@@ -558,7 +567,6 @@ int KGrCanvas::makeSprite (const char type, int i, int j)
// In KGoldrunner, the top-left visible cell is [1,1]: in KGrSprite [0,0].
sprite->move ((i - 1) * bgw, (j - 1) * bgh, frame1);
sprite->setZ (z);
sprite->show();
// kDebug() << "Sprite ID" << spriteId << "sprite type" << type
......@@ -570,11 +578,8 @@ void KGrCanvas::startAnimation (const int id, const bool repeating,
const int i, const int j, const int time,
const Direction dirn, const AnimationType type)
{
// TODO - Save last direction somehow, to use in facing and centering code.
// TODO - Put most of this in helper code, based on theme parameters.
// TODO - Use a QList of animation parameters: one entry per id.
// TODO - Need to select plain or gold-carrying enemy frames somehow.
int frame = 0;
int frame = animationStartFrames [type];
int nFrames = 8;
int nFrameChanges = 4;
int dx = 0;
......@@ -583,28 +588,22 @@ void KGrCanvas::startAnimation (const int id, const bool repeating,
switch (dirn) {
case RIGHT:
dx = +1;
frame = (type == RUN_R) ? RIGHTWALK1 : RIGHTCLIMB1;
break;
case LEFT:
dx = -1;
frame = (type == RUN_L) ? LEFTWALK1 : LEFTCLIMB1;
break;
case DOWN:
dy = +1;
if ((type == FALL_R) || (type == FALL_L)) {
nFrames = 1;
// TODO - Work out which way to face the runner.
frame = (type == FALL_R) ? FALL2 : FALL1;
}
else {
nFrames = 2;
frame = CLIMB1;
}
break;
case UP:
dy = -1;
nFrames = 2;
frame = CLIMB1;
break;
case STAND:
switch (type) {
......@@ -617,27 +616,25 @@ void KGrCanvas::startAnimation (const int id, const bool repeating,
frame = tileNumber (KGrTheme::BrickAnimation6Tile, i, j);
break;
default:
// Show a standing hero or enemy.
// Show a standing hero or enemy, using the previous StartFrame.
nFrames = 0;
// TODO - Work out which way to face the runner.
frame = FALL1; // (type == RUN) ? RIGHTWALK1 : RIGHTCLIMB1;
break;
}
break;
default:
break;
}
// kDebug() << "id" << id << "data" << i << j << dx * bgw << dy * bgw << frame << time;
// TODO - Generalise nFrameChanges = 4, also the tick time = 20 new sprite.
sprites->at(id)->setAnimation (repeating, (i - 1) * bgw, (j - 1) * bgh,
frame, nFrames, dx * bgw, dy * bgh, time, nFrameChanges);
}
void KGrCanvas::resynchAnimation (const int id, const int i, const int j,
const bool stop)
{
// TODO - Write this code.
}
// void KGrCanvas::resynchAnimation (const int id, const int i, const int j,
// const bool stop)
// {
// TODO - Write this code, if it is really needed.
// }
void KGrCanvas::gotGold (const int spriteId, const int i, const int j,
const bool spriteHasGold, const bool lost)
......@@ -691,17 +688,6 @@ void KGrCanvas::deleteAllSprites()
emptySprites = 0;
}
void KGrCanvas::moveEnemy (int id, int x, int y, int frame, int nuggets)
{
if (nuggets != 0) { // If enemy is carrying gold,
frame = frame + goldEnemy; // show him with gold outline.
}
// In KGoldrunner, the top-left visible cell is [1,1]: in KGrSprite [0,0].
// kDebug() << "accessing enemySprite" << id;
// OBSOLESCENT - 28/1/09 enemySprites->at (id)->move (x - bgw, y - bgh, frame);
}
QPixmap KGrCanvas::getPixmap (char type)
{
return tileset->at (theme.firstTile(tileForType(type)));
......
......@@ -35,6 +35,16 @@
#include "kgrtheme.h"
enum StartFrame {RIGHTWALK1, RIGHTWALK2, RIGHTWALK3, RIGHTWALK4,
RIGHTWALK5, RIGHTWALK6, RIGHTWALK7, RIGHTWALK8,
LEFTWALK1, LEFTWALK2, LEFTWALK3, LEFTWALK4,
LEFTWALK5, LEFTWALK6, LEFTWALK7, LEFTWALK8,
RIGHTCLIMB1, RIGHTCLIMB2, RIGHTCLIMB3, RIGHTCLIMB4,
RIGHTCLIMB5, RIGHTCLIMB6, RIGHTCLIMB7, RIGHTCLIMB8,
LEFTCLIMB1, LEFTCLIMB2, LEFTCLIMB3, LEFTCLIMB4,
LEFTCLIMB5, LEFTCLIMB6, LEFTCLIMB7, LEFTCLIMB8,
CLIMB1, CLIMB2,
FALL1, FALL2};
class KGrCanvas : public KGameCanvasWidget
{
......@@ -48,8 +58,6 @@ public:
void setTitle (const QString&);
void moveEnemy (int, int, int, int, int);
void goToBlack();
void fadeIn();
void fadeOut();
......@@ -78,8 +86,9 @@ public slots:
void startAnimation (const int id, const bool repeating,
const int i, const int j, const int time,
const Direction dirn, const AnimationType type);
void resynchAnimation (const int id, const int i, const int j,
const bool stop);
// TODO - Implement this method, if it is really needed.
// void resynchAnimation (const int id, const int i, const int j,
// const bool stop);
void gotGold (const int spriteId, const int i, const int j,
const bool spriteHasGold, const bool lost = false);
void showHiddenLadders (const QList<int> & ladders, const int width);
......@@ -178,6 +187,7 @@ private:
int score;
bool enemiesShowGold; // Show or conceal if enemies have gold.
int heroId; // The hero's sprite ID.
};
#endif // KGRCANVAS_H
// vi: set sw=4 :
......@@ -66,20 +66,6 @@ const int graphicsCycle = 8; // Animation frames per running cycle.
const double DROPNUGGETDELAY = 70.0; // Enemy holds gold for avg. 12.5 cells.
enum Position {RIGHTWALK1, RIGHTWALK2, RIGHTWALK3, RIGHTWALK4,
RIGHTWALK5, RIGHTWALK6, RIGHTWALK7, RIGHTWALK8,
LEFTWALK1, LEFTWALK2, LEFTWALK3, LEFTWALK4,
LEFTWALK5, LEFTWALK6, LEFTWALK7, LEFTWALK8,
RIGHTCLIMB1, RIGHTCLIMB2, RIGHTCLIMB3, RIGHTCLIMB4,
RIGHTCLIMB5, RIGHTCLIMB6, RIGHTCLIMB7, RIGHTCLIMB8,
LEFTCLIMB1, LEFTCLIMB2, LEFTCLIMB3, LEFTCLIMB4,
LEFTCLIMB5, LEFTCLIMB6, LEFTCLIMB7, LEFTCLIMB8,
CLIMB1, CLIMB2,
FALL1, FALL2};
// TODO - Is this enum still needed?
enum Status {STANDING, FALLING, WALKING, CLIMBING, CAPTIVE};
// Keyboard action codes
enum KBAction {KB_UP, KB_DOWN, KB_LEFT, KB_RIGHT,
KB_DIGLEFT, KB_DIGRIGHT, KB_STOP};
......@@ -180,6 +166,7 @@ enum Setting {PLAY_SOUNDS, // Sound effects on/off.
const int ConcreteWall = 1;
// TODO - Should these be uchar?
typedef char DirectionFlag;
typedef char AccessFlag;
typedef char Flags;
......@@ -210,7 +197,7 @@ enum AnimationType {
CLIMB_R, CLIMB_L,
CLIMB_U, CLIMB_D,
FALL_R, FALL_L,
OPEN_BRICK, CLOSE_BRICK};
OPEN_BRICK, CLOSE_BRICK, nAnimationTypes};
const AnimationType aType [nDirections] = {
FALL_L, RUN_R, RUN_L, CLIMB_U, CLIMB_D};
......
......@@ -58,7 +58,7 @@ KGrLevelPlayer::KGrLevelPlayer (QObject * parent, KRandomSequence * pRandomGen)
{
t.start(); // IDW
dbgLevel = 0;
dbgLevel = 2;
}
int KGrLevelPlayer::playerCount = 0;
......@@ -656,7 +656,9 @@ bool KGrLevelPlayer::heroCaught (const int heroX, const int heroY)
pointsPerCell_1 = enemy->whereAreYou (enemyX, enemyY) - 1;
if (((heroX < enemyX) ? ((heroX + pointsPerCell_1) >= enemyX) :
(heroX <= (enemyX + pointsPerCell_1))) &&
((heroY < enemyY) ? ((heroY + pointsPerCell_1) >= enemyY) :
// TODO - Remove? ((heroY < enemyY) ?
// ((heroY + pointsPerCell_1) >= enemyY) :
((heroY < enemyY) ? ((heroY + pointsPerCell_1) > enemyY) :
(heroY <= (enemyY + pointsPerCell_1)))) {
return true;
}
......@@ -1154,7 +1156,7 @@ void KGrLevelPlayer::dbgControl (int code)
showFigurePositions(); // Show everybody's co-ordinates.
break;
case S_HERO:
hero->showState ('s'); // Show hero's co-ordinates and state.
hero->showState(); // Show hero's co-ordinates and state.
break;
case S_OBJ:
showObjectState(); // Show an object's state.
......@@ -1183,9 +1185,9 @@ void KGrLevelPlayer::startLogging()
void KGrLevelPlayer::showFigurePositions()
{
hero->showState ('p');
hero->showState();
foreach (KGrEnemy * enemy, enemies) {
enemy->showState ('p');
enemy->showState();
}
}
......@@ -1225,7 +1227,7 @@ void KGrLevelPlayer::showObjectState()
void KGrLevelPlayer::showEnemyState (int enemyId)
{
if (enemyId < enemies.count()) {
enemies.at(enemyId)->showState ('s');
enemies.at(enemyId)->showState();
}
}
......
......@@ -41,12 +41,12 @@ void KGrRuleBook::setTiming (const int enemyCount)
{
int choice;
Timing varTiming[6] = {
{40, 58, 78, 88, 170, 23}, // No enemies.
{50, 68, 78, 88, 170, 32}, // 1 enemy.
{57, 67, 114, 128, 270, 37}, // 2 enemies.
{60, 70, 134, 136, 330, 40}, // 3 enemies.
{63, 76, 165, 150, 400, 46}, // 4 enemies.
{70, 80, 189, 165, 460, 51} // >4 enemies.
{40, 58, 78, 88, 340, 23}, // No enemies.
{50, 68, 78, 88, 340, 32}, // 1 enemy.
{57, 67, 114, 128, 540, 37}, // 2 enemies.
{60, 70, 134, 136, 660, 40}, // 3 enemies.
{63, 76, 165, 150, 800, 46}, // 4 enemies.
{70, 80, 189, 165, 920, 51} // >4 enemies.
};
if (mVariableTiming) {
choice = (enemyCount < 0) ? 0 : enemyCount;
......@@ -73,7 +73,7 @@ KGrTraditionalRules::KGrTraditionalRules (QObject * parent)
mTurnAnywhere = false; ///< Change direction only at next cell.
mEnemiesShowGold = true; ///< Show enemies carrying gold.
Timing t = {40, 58, 78, 88, 170, 23};
Timing t = {40, 58, 78, 88, 340, 23};
times = t;
}
......@@ -495,7 +495,7 @@ KGrKGoldrunnerRules::KGrKGoldrunnerRules (QObject * parent)
mTurnAnywhere = false; ///< Change direction only at next cell.
mEnemiesShowGold = true; ///< Show enemies carrying gold.
Timing t = {45, 50, 55, 100, 500, 40};
Timing t = {45, 50, 55, 100, 1000, 40};
times = t;
}
......@@ -688,7 +688,7 @@ KGrScavengerRules::KGrScavengerRules (QObject * parent)
mTurnAnywhere = true; ///< Change direction anywhere in cell.
mEnemiesShowGold = false; ///< Conceal enemies carrying gold.
Timing t = {45, 50, 55, 100, 500, 40};
Timing t = {45, 50, 55, 100, 1000, 40};
times = t;
}
......
......@@ -47,12 +47,14 @@ public:
void setTiming (const int enemyCount = 0);
inline void getHeroTimes (int & runTime, int & fallTime) {
runTime = times.hwalk; fallTime = times.hfall; }
inline void getHeroTimes (int & runTime, int & fallTime,
int & enemyFallTime, int & trapTime) {
runTime = times.hwalk; fallTime = times.hfall;
enemyFallTime = times.efall; trapTime = times.ecaptive; }
inline char getEnemyTimes (int & runTime, int & fallTime, int & trapTime) {
runTime = times.ewalk; fallTime = times.efall;
trapTime = times.ecaptive;
runTime = times.ewalk; fallTime = times.efall;
trapTime = times.ecaptive;
return mRules; }
inline void getDigTimes (int & digTime, int & digCounter) {
......
......@@ -38,6 +38,7 @@ KGrRunner::KGrRunner (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
deltaX (0),
deltaY (0),
pointCtr (0),
falling (false),
currDirection (STAND),
currAnimation (FALL_L),
......@@ -110,6 +111,92 @@ Situation KGrRunner::situation (const int scaledTime)
return EndCell;
}
char KGrRunner::nextCell()
{
pointCtr = 0;
gridI = gridX / pointsPerCell;
gridJ = gridY / pointsPerCell;
return grid->cellType (gridI, gridJ);
}
bool KGrRunner::setNextMovement (const char spriteType, const char cellType,
Direction & dir,
AnimationType & anim, int & interval)
{
bool fallingState = false;
Flags OK = 0;
if (spriteType == HERO) {
dir = levelPlayer->getDirection (gridI, gridJ);
OK = grid->heroMoves (gridI, gridJ);
}
else {
dir = levelPlayer->getEnemyDirection (gridI, gridJ, leftRightSearch);
OK = grid->enemyMoves (gridI, gridJ);
}
if ((dir >= nDirections) || (dir < 0)) {
dir = STAND; // Make sure indices stay within range.
}
if (dir == STAND) {
anim = currAnimation;
}
else {
anim = aType [dir];
}
if (((anim == RUN_R) || (anim == RUN_L)) && (cellType == BAR)) {
anim = (dir == RIGHT) ? CLIMB_R : CLIMB_L;
}
interval = runTime;
bool onEnemy = levelPlayer->standOnEnemy (spriteId, gridX, gridY);
if (onEnemy) dbk3 << spriteId << "STANDING ON ENEMY - dirn"
<< dir;
// TODO - Do a better, smoother job of falling while standing on enemy.
// TODO - Especially, do not do a climb-down action.
bool canStand = (OK & dFlag [STAND]) || (OK == 0) || onEnemy;
if ((dir == DOWN) && (cellType == BAR)) {
canStand = false;
}
// TODO - Check that the trap time is the same as in KGr 3.0.
// TODO - We seem to be early getting into/out of the hole, but
// the captive time is now OK. Total t down by ~100 in 4400.
if ((spriteType == ENEMY) && (cellType == USEDHOLE)) {
// The enemy is in a hole.
if (currDirection == DOWN) {
// The enemy is at the bottom of the hole: start the captive-timer.
dir = STAND;
anim = currAnimation;
interval = trapTime;
dbe1 "T %05d id %02d Captive at [%02d,%02d]\n",
t.elapsed(), spriteId, gridI, gridJ);
}
else {
// The enemy can start climbing out after a cycle of captive-times.
dir = UP;
anim = CLIMB_U;
dbe1 "T %05d id %02d Start climb out at [%02d,%02d]\n",
t.elapsed(), spriteId, gridI, gridJ);
}
}
else if (! canStand) {
fallingState = true;
dir = DOWN;
anim = (falling) ? currAnimation :
((currDirection == RIGHT) ? FALL_R : FALL_L);
interval = fallTime;
}
else if (! (OK & dFlag [dir])) {
// Sprite cannot move, but the animation shows the desired direction.
dir = STAND;
}
return fallingState;
}
KGrHero::KGrHero (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
int i, int j, int pSpriteId, KGrRuleBook * pRules)
......@@ -118,7 +205,7 @@ KGrHero::KGrHero (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
nuggets (0) // KGrLevelPlayer object will call hero->setNuggets().
{
kDebug() << "THE HERO IS BORN at" << i << j << "sprite ID" << pSpriteId;
rules->getHeroTimes (runTime, fallTime);
rules->getHeroTimes (runTime, fallTime, enemyFallTime, trapTime);
kDebug() << "Hero run time" << runTime << "fall time" << fallTime;
interval = runTime;
}
......@@ -127,10 +214,6 @@ KGrHero::~KGrHero()
{
}
// These statics will be set to their proper values in the constructor.
int KGrHero::runTime = 0;
int KGrHero::fallTime = 0;
HeroStatus KGrHero::run (const int scaledTime)
{
Situation s = situation (scaledTime);
......@@ -144,68 +227,40 @@ HeroStatus KGrHero::run (const int scaledTime)
}
// TODO - If on top row and all nuggets gone, plus Scav cond, go up a level.
// TODO - Must be standing, NOT about to fall. Maybe can go AFTER setNextM.
if ((gridJ == 1) && (nuggets <= 0)) {
return WON_LEVEL;
}
// TODO - Do we need to do this on every grid-point?
bool standingOnEnemy = levelPlayer->standOnEnemy (spriteId, gridX, gridY);
if ((! standingOnEnemy) && levelPlayer->heroCaught (gridX, gridY)) {
if (levelPlayer->heroCaught (gridX, gridY)) {
return DEAD;
}
if (s == MidCell) {
return NORMAL;
}
pointCtr = 0;
gridI = gridX / pointsPerCell;
gridJ = gridY / pointsPerCell;
// Continue to the next cell.
char cellType = nextCell();
char cell = grid->cellType (gridI, gridJ);
if (cell == NUGGET) {
if (cellType == NUGGET) {
nuggets = levelPlayer->runnerGotGold (spriteId, gridI, gridJ, true);
emit incScore (250); // Add to the human player's score.
}
Direction nextDirection = levelPlayer->getDirection (gridI, gridJ);
if ((nextDirection >= nDirections) || (nextDirection < 0)) {
nextDirection = STAND; // Make sure indices stay within range.
Direction nextDirection;
AnimationType nextAnimation;
bool newFallingState = setNextMovement (HERO, cellType, nextDirection,
nextAnimation, interval);
if (newFallingState != falling) {
// emit soundSignal (FALLING, newFallingState); // Start/stop falling.
falling = newFallingState;
}
interval = runTime;
Flags OK = grid->heroMoves (gridI, gridJ);
bool onEnemy = levelPlayer->standOnEnemy (spriteId, gridX, gridY);
bool canStand = (OK & dFlag [STAND]) || (OK == 0) || onEnemy;
// TODO - Do a better, smoother job of falling while standing on enemy.
// TODO - Interface fall start and end with sound.
AnimationType nextAnimation = aType [nextDirection];
if (! canStand) {
nextDirection = DOWN;
nextAnimation = (currDirection == RIGHT) ? FALL_R : FALL_L;
interval = fallTime;
}
else if (! (OK & dFlag [nextDirection])) {
nextDirection = STAND;
}
if (nextDirection == STAND) {
nextAnimation = currAnimation;
}
timeLeft += interval;
dbe2 "%d sprite %02d [%02d,%02d] timeLeft %03d currDir %d nextDir %d\n",
pointCtr, spriteId, gridI, gridJ, timeLeft, currDirection, nextDirection);
if ((! onEnemy) && levelPlayer->heroCaught (gridX, gridY)) {
return DEAD;
}
if (((nextAnimation == RUN_R) || (nextAnimation == RUN_L)) &&
(cell == BAR)) {
nextAnimation = (nextDirection == RIGHT) ? CLIMB_R : CLIMB_L;
}
dbe2 "%d sprite %02d [%02d,%02d] timeLeft %03d currDir %d nextDir %d "
"currAnim %d nextAnim %d\n",
pointCtr, spriteId, gridI, gridJ, timeLeft, currDirection, nextDirection,
currAnimation, nextAnimation);
if ((nextDirection == currDirection) && (nextAnimation == currAnimation)) {
// TODO - If dirn == STAND, no animation, else emit resynchAnimation().
......@@ -261,25 +316,13 @@ bool KGrHero::dig (const Direction diggingDirection, int & i, int & j)
return result; // Tell the levelPlayer whether & where to open a hole.
}
void KGrHero::showState (char option)
void KGrHero::showState()
{
fprintf (stderr, "(%02d,%02d) - Hero ", gridI, gridJ);
switch (option) {
case 'p': fprintf (stderr, "\n"); break;
case 's': fprintf (stderr, " STATE\n");
// TODO - Print the hero's state.
// fprintf (stderr, " nuggets %02d status %d walk-ctr %d ",
// nuggets, status, walkCounter);
// fprintf (stderr, "dirn %d next dirn %d\n", direction, nextDir);
// fprintf (stderr, " rel (%02d,%02d) abs (%03d,%03d)",
// relx, rely, absx, absy);
// fprintf (stderr, " pix %02d", actualPixmap);
// fprintf (stderr, " mem %d %d %d %d", mem_x, mem_y, mem_relx, mem_rely);
// if (walkFrozen) fprintf (stderr, " wBlock");
// if (fallFrozen) fprintf (stderr, " fBlock");
// fprintf (stderr, "\n");
break;
}
fprintf (stderr, "(%02d,%02d) - Hero [%02d]", gridI, gridJ, spriteId);
fprintf (stderr, " gold %02d dirn %d ctr %d",
nuggets, currDirection, pointCtr);
fprintf (stderr, " gridX %3d gridY %3d anim %d\n",
gridX, gridY, currAnimation);
}
......@@ -292,24 +335,21 @@ KGrEnemy::KGrEnemy (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
birthJ (j),
prevInCell (-1)
{
rulesType = rules->getEnemyTimes (runTime, fallTime, trapTime);
interval = runTime;
rulesType = rules->getEnemyTimes (runTime, fallTime, trapTime);
enemyFallTime = fallTime;
interval = runTime;
kDebug() << "ENEMY" << pSpriteId << "IS BORN at" << i << j;
if (pSpriteId < 2) {
kDebug() << "Enemy run time " << runTime << "fall time" << fallTime;
kDebug() << "Enemy trap time" << trapTime << "Rules type" << rulesType;
}
t.start(); // IDW
}
KGrEnemy::~KGrEnemy()
{
}
// These statics will be set to their proper values in the constructor.
int KGrEnemy::runTime = 0;
int KGrEnemy::fallTime = 0;
int KGrEnemy::trapTime = 0;
void KGrEnemy::run (const int scaledTime)
{
Situation s = situation (scaledTime);
......@@ -324,7 +364,9 @@ void KGrEnemy::run (const int scaledTime)
// TODO - What if >1 enemy has occupied a cell somehow?
// TODO - Effect on CPU time of more frequent BRICK checks ...
releaseCell (gridI + deltaX, gridJ + deltaY);
emit incScore (75); // Add to the human player's score.
emit incScore (75); // Killed: add to the player's score.
dbe1 "T %05d id %02d Died in brick at [%02d,%02d]\n",
t.elapsed(), spriteId, gridI, gridJ);
dieAndReappear(); // Move to a new (gridI, gridJ).
reserveCell (gridI, gridJ);
// No return: treat situation as EndCell.
......@@ -333,35 +375,37 @@ void KGrEnemy::run (const int scaledTime)
else if ((pointCtr == 1) && (currDirection == DOWN) &&
(grid->cellType (gridI, gridJ + 1) == HOLE)) {
// Enemy is starting to fall into a hole.
dbk3 << spriteId
<< "Falling into hole at:" << gridI << (gridJ + 1);
dbe1 "T %05d id %02d Mark hole [%02d,%02d] as used\n",
t.elapsed(), spriteId, gridI, gridJ+1);
grid->changeCellAt (gridI, gridJ + 1, USEDHOLE);
dropGold();
emit incScore (75); // Add to the human player's score.
emit incScore (75); // Trapped: add to the player's score.
return;
}
// Wait till end of cell.
else if (s == MidCell) {
if (grid->cellType (gridI, gridJ) == USEDHOLE) {