#include #include "PacMan.h" #include "Gameplay.h" #include "constant.h" extern bool joystickInstalled; extern int joystickId; extern int joystickStickId; extern int joystickMedium; extern float joystickThreshold; extern int enableJoystick; extern BITMAP *tileImage; extern bool forgotScreen; extern volatile bool heartBeat; extern void drawSpritesForBlitting(); extern void showFrame(); extern void generalDrawPacMan(direction headed, fixed jawBinaryAngle); extern void drawFrame(); extern void go(int *x, int *y, int step, int xMax, int yMax, direction way); extern void loopingLine(BITMAP *canvas, int x1, int y1, int x2, int y2, int color); extern float joyDistFromCenter(); extern void setHeartBeat(); PacMan::PacMan(Gameplay *desiredGame) : game(desiredGame), x(desiredGame->getLevelPointer()->getPacManStartX() * tileSize), y(desiredGame->getLevelPointer()->getPacManStartY() * tileSize), headed(right), jawBinaryAngle(itofix(32)), openingMouth(false) {} int PacMan::getX() { return x; } int PacMan::getY() { return y; } void PacMan::move() { if (key[KEY_8_PAD] || key[KEY_UP]) headed = up; else if (key[KEY_4_PAD] || key[KEY_LEFT]) headed = left; else if (key[KEY_6_PAD] || key[KEY_RIGHT]) headed = right; else if (key[KEY_2_PAD] || key[KEY_DOWN]) headed = down; if (joystickInstalled && enableJoystick) switch (joystickMedium) { case 0: if (joyDistFromCenter() >= joystickThreshold) { const int xDiff = joy[joystickId].stick[joystickStickId].axis[0].pos; const int yDiff = joy[joystickId].stick[joystickStickId].axis[1].pos; if ((xDiff < 0 ? -xDiff : xDiff) > (yDiff < 0 ? -yDiff : yDiff)) { if (xDiff < 0) headed = left; else if (xDiff > 0) headed = right; } else if (yDiff < 0) headed = up; else if (yDiff > 0) headed = down; } break; case 1: if (joy[joystickId].stick[joystickStickId].axis[1].d1) headed = up; else if (joy[joystickId].stick[joystickStickId].axis[0].d1) headed = left; else if (joy[joystickId].stick[joystickStickId].axis[0].d2) headed = right; else if (joy[joystickId].stick[joystickStickId].axis[1].d2) headed = down; } direction way; if ((headed == up || headed == down) && x % tileSize != 0) way = (x + halfTileSize) % tileSize < tileSize / 2 ? right : left; else if ((headed == left || headed == right) && y % tileSize != 0) way = (y + halfTileSize) % tileSize < tileSize / 2 ? down : up; else way = headed; if (openingMouth) { jawBinaryAngle += jawStep; openingMouth = jawBinaryAngle < itofix(32); } else { jawBinaryAngle -= jawStep; openingMouth = jawBinaryAngle <= itofix(0); } const tile above = game->getLevelPointer()->getTile(x / tileSize, y / tileSize + boardH - 1); const tile toTheLeft = game->getLevelPointer()->getTile(x / tileSize + boardW - 1, y / tileSize); const tile toTheRight = game->getLevelPointer()->getTile(x / tileSize + 1, y / tileSize); const tile below = game->getLevelPointer()->getTile(x / tileSize, y / tileSize + 1); if (x % tileSize != 0 || y % tileSize != 0 || way == up && above != wallTile && above != gateTile && above != gateEnergyTile || way == left && toTheLeft != wallTile && toTheLeft != gateTile && toTheLeft != gateEnergyTile || way == right && toTheRight != wallTile && toTheRight != gateTile && toTheRight != gateEnergyTile || way == down && below != wallTile && below != gateTile && below != gateEnergyTile) go(&x, &y, pacManStep, boardW * tileSize, boardH * tileSize, way); } void PacMan::draw(BITMAP *canvas) { generalDrawPacMan(headed, jawBinaryAngle); draw_sprite(canvas, tileImage, x, y); if (x > boardW * tileSize - tileSize) draw_sprite(canvas, tileImage, x - boardW * tileSize, y); if (y > boardH * tileSize - tileSize) { draw_sprite(canvas, tileImage, x, y - boardH * tileSize); if (x > boardW * tileSize - tileSize) draw_sprite(canvas, tileImage, x - boardW * tileSize, y - boardH * tileSize); } } void PacMan::playDeathAnimation(BITMAP *canvas) { const int centerX = x + halfTileSize; const int centerY = y + halfTileSize; heartBeat = false; install_int(setHeartBeat, deathAnimationDelay); while (jawBinaryAngle < itofix(125)) { const fixed lipBinaryAngle1 = throatBinaryAngle[headed] + jawBinaryAngle; const fixed lipBinaryAngle2 = throatBinaryAngle[headed] + itofix(256) - jawBinaryAngle; game->drawActors(); loopingLine(canvas, centerX, centerY, centerX + fixtoi(deathWiperLength * fixcos(lipBinaryAngle1)), centerY - fixtoi(deathWiperLength * fixsin(lipBinaryAngle1)), 15); loopingLine(canvas, centerX, centerY, centerX + fixtoi(deathWiperLength * fixcos(lipBinaryAngle2)), centerY - fixtoi(deathWiperLength * fixsin(lipBinaryAngle2)), 15); drawFrame(); showFrame(); while (!heartBeat) if (forgotScreen) { drawSpritesForBlitting(); game->drawGame(); loopingLine(canvas, centerX, centerY, centerX + fixtoi(deathWiperLength * fixcos(lipBinaryAngle1)), centerY - fixtoi(deathWiperLength * fixsin(lipBinaryAngle1)), 15); loopingLine(canvas, centerX, centerY, centerX + fixtoi(deathWiperLength * fixcos(lipBinaryAngle2)), centerY - fixtoi(deathWiperLength * fixsin(lipBinaryAngle2)), 15); drawFrame(); showFrame(); } heartBeat = false; jawBinaryAngle += itofix(3); } jawBinaryAngle = itofix(128); remove_int(setHeartBeat); game->drawActors(); for (fixed i = itofix(0); i < itofix(256); i += itofix(32)) loopingLine(canvas, centerX + fixtoi(4 * fixcos(i)), centerY - fixtoi(4 * fixsin(i)), centerX + fixtoi(halfTileSize * fixcos(i)), centerY - fixtoi(halfTileSize * fixsin(i)), 15); drawFrame(); showFrame(); }