/* Hard drop */ static void dropTetromino(StcGame *game) { #ifdef STC_SHOW_GHOST_PIECE /* Shadow has already calculated the landing position. */ game->fallingBlock.y += game->shadowGap; /* Force lock. */ moveTetromino(game, 0, 1); /* Update score */ if (game->showShadow) { game->stats.score += (long)(SCORE_2_FILLED_ROW * (game->stats.level + 1) / SCORE_DROP_WITH_SHADOW_DIVISOR); } else { game->stats.score += (long)(SCORE_2_FILLED_ROW * (game->stats.level + 1) / SCORE_DROP_DIVISOR); } #else int y = 0; /* Calculate number of cells to drop */ while (!checkCollision(game, 0, ++y)); moveTetromino(game, 0, y - 1); moveTetromino(game, 0, 1); /* Force lock */ /* Update score */ game->stats.score += (long)(SCORE_2_FILLED_ROW * (game->stats.level + 1) / SCORE_DROP_DIVISOR); #endif }
// Hard drop void Game::dropTetromino() { #ifdef STC_SHOW_GHOST_PIECE // Shadow has already calculated the landing position. mFallingBlock.y += mShadowGap; // Force lock. moveTetromino(0, 1); // Update score if (mShowShadow) { addScore((long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_DROP_WITH_SHADOW_DIVISOR)); } else { addScore(mStats.score += (long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_DROP_DIVISOR)); } #else int y = 0; // Calculate number of cells to drop while (!checkCollision(0, ++y)); moveTetromino(0, y - 1); moveTetromino(0, 1); // Force lock // Update score addScore((long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_DROP_DIVISOR)); #endif mPlatform->onPieceDrop(); }
// 完成一次hard drop,有一定的分数奖励 // A Hard Drop is the event in which a Tetromino drops // instantly to where the Ghost Piece is. It can't be // moved or rotated afterwards. It causes the Score to go up. void Game::dropTetromino() { //计算block的位置? mFallingBlock.y += mShadowGap; //Force lock? moveTetromino(0, 1); //更新分数,使用了shadow的分数减少 if (mShowShadow) { mStats.score += (long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_DROP_WITH_SHADOW_DIVISOR); } else { mStats.score += (long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_DROP_DIVISOR); } //计算方块最多能下落到哪里 int y = 1; while (!checkCollision(0, ++y)); moveTetromino(0, y - 1); //Force lock? moveTetromino(0, 1); mStats.score += (long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_DROP_DIVISOR); mPlatform->onPieceDrop(); }
// Main function. int main(int argc, char** argv) { rowIndexNew = 10; colIndexNew = 55; initTerminal(); while (true) { drawField(); int key = getch(); moveTetromino(key); showTetromino(); usleep(1000); count++; // Arrow up will exit the program if (key == 65) {break;} } endwin(); }
/* * Main function game called every frame */ void gameUpdate(StcGame *game) { long currentTime; int timeDelta; /* Read user input */ platformProcessEvents(game); /* Update game state */ if (game->data->isOver != 0) { if ((game->data->events & EVENT_RESTART) != 0) { game->data->isOver = 0; startGame(game); } } else { currentTime = platformGetSystemTime(); /* Process delayed autoshift */ timeDelta = (int)(currentTime - game->data->systemTime); if (game->data->delayDown > 0) { game->data->delayDown -= timeDelta; if (game->data->delayDown <= 0) { game->data->delayDown = DAS_MOVE_TIMER; game->data->events |= EVENT_MOVE_DOWN; } } if (game->data->delayLeft > 0) { game->data->delayLeft -= timeDelta; if (game->data->delayLeft <= 0) { game->data->delayLeft = DAS_MOVE_TIMER; game->data->events |= EVENT_MOVE_LEFT; } } else if (game->data->delayRight > 0) { game->data->delayRight -= timeDelta; if (game->data->delayRight <= 0) { game->data->delayRight = DAS_MOVE_TIMER; game->data->events |= EVENT_MOVE_RIGHT; } } #ifdef STC_AUTO_ROTATION if (game->data->delayRotation > 0) { game->data->delayRotation -= timeDelta; if (game->data->delayRotation <= 0) { game->data->delayRotation = ROTATION_AUTOREPEAT_TIMER; game->data->events |= EVENT_ROTATE_CW; } } #endif /* STC_AUTO_ROTATION */ /* Always handle pause event */ if ((game->data->events & EVENT_PAUSE) != 0) { game->isPaused = !game->isPaused; game->data->events = EVENT_NONE; } /* Check if the game is paused */ if (game->isPaused != 0) { /* We achieve the effect of pausing the game * adding the last frame duration to lastFallTime */ game->data->lastFallTime += (currentTime - game->data->systemTime); } else { if ((game->data->events != EVENT_NONE) != 0) { if (game->data->events & EVENT_SHOW_NEXT) { game->showPreview = !game->showPreview; game->stateChanged = 1; } #ifdef STC_SHOW_GHOST_PIECE if ((game->data->events & EVENT_SHOW_SHADOW) != 0) { game->showShadow = !game->showShadow; game->stateChanged = 1; } #endif if ((game->data->events & EVENT_DROP) != 0) { dropTetromino(game); } if ((game->data->events & EVENT_ROTATE_CW) != 0) { rotateTetromino(game, 1); } if ((game->data->events & EVENT_MOVE_RIGHT) != 0) { moveTetromino(game, 1, 0); } else if ((game->data->events & EVENT_MOVE_LEFT) != 0) { moveTetromino(game, -1, 0); } if ((game->data->events & EVENT_MOVE_DOWN) != 0) { /* Update score if the user accelerates downfall */ game->stats.score += (long)(SCORE_2_FILLED_ROW * (game->stats.level + 1) / SCORE_MOVE_DOWN_DIVISOR); moveTetromino(game, 0, 1); } game->data->events = EVENT_NONE; } /* Check if it's time to move downwards the falling tetromino */ if (currentTime - game->data->lastFallTime >= game->data->fallingDelay) { moveTetromino(game, 0, 1); game->data->lastFallTime = currentTime; } } /* Save current time for next game update */ game->data->systemTime = currentTime; } /* Draw game state */ platformRenderGame(game); }
// Main function game called every frame void Game::update() { // Read player input mPlatform->processEvents(); // Update game state if (mIsOver) { if ((mEvents & EVENT_RESTART) != 0) { mIsOver = false; start(); } } else { // Always handle restart event if ((mEvents & EVENT_RESTART) != 0) { start(); return; } long currentTime = mPlatform->getSystemTime(); // Process delayed autoshift int timeDelta = (int)(currentTime - mSystemTime); if (mDelayDown > 0) { mDelayDown -= timeDelta; if (mDelayDown <= 0) { mDelayDown = DAS_MOVE_TIMER; mEvents |= EVENT_MOVE_DOWN; } } if (mDelayLeft > 0) { mDelayLeft -= timeDelta; if (mDelayLeft <= 0) { mDelayLeft = DAS_MOVE_TIMER; mEvents |= EVENT_MOVE_LEFT; } } else if (mDelayRight > 0) { mDelayRight -= timeDelta; if (mDelayRight <= 0) { mDelayRight = DAS_MOVE_TIMER; mEvents |= EVENT_MOVE_RIGHT; } } #ifdef STC_AUTO_ROTATION if (mDelayRotation > 0) { mDelayRotation -= timeDelta; if (mDelayRotation <= 0) { mDelayRotation = ROTATION_AUTOREPEAT_TIMER; mEvents |= EVENT_ROTATE_CW; } } #endif // STC_AUTO_ROTATION // Always handle pause event if ((mEvents & EVENT_PAUSE) != 0) { mIsPaused = !mIsPaused; mEvents = EVENT_NONE; } // Check if the game is paused if (mIsPaused) { // We achieve the effect of pausing the game // adding the last frame duration to lastFallTime mLastFallTime += (currentTime - mSystemTime); } else { if (mEvents != EVENT_NONE) { if ((mEvents & EVENT_SHOW_NEXT) != 0) { mShowPreview = !mShowPreview; mStateChanged = true; } #ifdef STC_SHOW_GHOST_PIECE if ((mEvents & EVENT_SHOW_SHADOW) != 0) { mShowShadow = !mShowShadow; mStateChanged = true; } #endif if ((mEvents & EVENT_DROP) != 0) { dropTetromino(); } if ((mEvents & EVENT_ROTATE_CW) != 0) { rotateTetromino(true); } if ((mEvents & EVENT_ROTATE_CCW) != 0) { rotateTetromino(false); } if ((mEvents & EVENT_MOVE_RIGHT) != 0) { moveTetromino(1, 0); } else if ((mEvents & EVENT_MOVE_LEFT) != 0) { moveTetromino(-1, 0); } if ((mEvents & EVENT_MOVE_DOWN) != 0) { // Update score if the player accelerates downfall addScore((long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_MOVE_DOWN_DIVISOR)); moveTetromino(0, 1); } mEvents = EVENT_NONE; } // Check if it's time to move downwards the falling tetromino if (currentTime - mLastFallTime >= mFallingDelay) { moveTetromino(0, 1); mLastFallTime = currentTime; } } // Save current time for next game update mSystemTime = currentTime; } // Draw game state mPlatform->renderGame(); }
//每帧更新都要调用的方法 void Game::update() { //这个方法是空的 mPlatform->processEvents(); if (mIsOver) { if ((mEvents & EVENT_RESTART) != 0) { mIsOver = false; start(); } } else { if ((mEvents & EVENT_RESTART) != 0) { start(); return; } long currentTime = mPlatform->getSystemTime(); //上次调用update的时间为mSystemTime //timeDelta就是距离上次刷新过去的millseconds int timeDelta = (int)(currentTime - mSystemTime); if (mDelayDown > 0) { mDelayDown -= timeDelta; if (mDelayDown <= 0) { //到了下降的时间了,重置mDelayDown mDelayDown = DAS_MOVE_TIMER; //设置下降事件 mEvents |= EVENT_MOVE_DOWN; } } if (mDelayLeft > 0) { mDelayLeft -= timeDelta; if (mDelayLeft <= 0) { mDelayLeft = DAS_MOVE_TIMER; mEvents |= EVENT_MOVE_LEFT; } } else if (mDelayRight > 0) { mDelayRight -= timeDelta; if (mDelayRight <= 0) { mDelayRight = DAS_MOVE_TIMER; mEvents |= EVENT_MOVE_RIGHT; } } if (mDelayRotation > 0) { mDelayRotation -= timeDelta; if (mDelayRotation > 0) { mDelayRotation = ROTATION_AUTOREPEAT_TIMER; mEvents |= EVENT_ROTATE_CW; } } //处理暂停 if ((mEvents & EVENT_PAUSE) != 0) { //如果检测到暂停,清空所有当前事件,等待暂停结束 mIsPaused = !mIsPaused; mEvents = EVENT_NONE; } if (mIsPaused) { //暂停了,就要更新距离上次方块落地过去的时间 //这个变量好像没什么用 mLastFallTime += (currentTime - mSystemTime); } else { if (mEvents != EVENT_NONE) { if ((mEvents & EVENT_SHOW_NEXT) != 0) { mShowPreview = !mShowPreview; mStateChanged = true; } if ((mEvents & EVENT_DROP) != 0) { //hard drop dropTetromino(); } if ((mEvents & EVENT_ROTATE_CW) != 0) { rotateTetromino(true); } if ((mEvents & EVENT_MOVE_LEFT) != 0) { moveTetromino(-1, 0); } else if ((mEvents & EVENT_MOVE_RIGHT) != 0) { moveTetromino(1, 0); } if ((mEvents & EVENT_MOVE_DOWN) != 0) { //这是玩家主动按键触发的下降事件,所以算作玩家加速下降,应该加分 mStats.score += (long)(SCORE_2_FILLED_ROW * (mStats.level + 1) / SCORE_MOVE_DOWN_DIVISOR); moveTetromino(0, 1); } mEvents = EVENT_NONE; } //如果没有事件,检查是否到了降落一格方块的时候 if (currentTime - mLastFallTime >= mFallingDelay) { //这个下降是系统被动下降,不是玩家主动下降,所以没有加分 moveTetromino(0, 1); mLastFallTime = currentTime; } } //把mSystemTime更新为调用这次update的时间 mSystemTime = currentTime; } //绘制游戏 mPlatform->renderGame(); }