示例#1
0
文件: game.c 项目: ex/blocks
/* Start a new game */
static void startGame(StcGame *game) {
    int i;

    /* Initialize game data */
    game->errorCode = ERROR_NONE;
    game->data->systemTime = platformGetSystemTime();
    game->data->lastFallTime = game->data->systemTime;
    game->data->isOver = 0;
    game->isPaused = 0;
    game->showPreview = 1;
    game->data->events = EVENT_NONE;
    game->data->fallingDelay = STC_INIT_DELAY_FALL;
#ifdef STC_SHOW_GHOST_PIECE
    game->showShadow = 1;
#endif

    /* Initialize game statistics */
    game->stats.score = 0;
    game->stats.lines = 0;
    game->stats.totalPieces = 0;
    game->stats.level = 0;
    for (i = 0; i < TETROMINO_TYPES; ++i) {
        game->stats.pieces[i] = 0;
    }

    /* Initialize game tile map */
    setMatrixCells(&game->map[0][0], BOARD_TILEMAP_WIDTH, BOARD_TILEMAP_HEIGHT, EMPTY_CELL);

    /* Initialize falling tetromino */
    setTetromino(platformRandom() % TETROMINO_TYPES, &game->fallingBlock);
    game->fallingBlock.x = (BOARD_TILEMAP_WIDTH - game->fallingBlock.size) / 2;
    game->fallingBlock.y = 0;

    /* Initialize preview tetromino */
    setTetromino(platformRandom() % TETROMINO_TYPES, &game->nextBlock);

    /* Initialize events */
    onTetrominoMoved(game);

    /* Initialize delayed autoshift */
    game->data->delayLeft = -1;
    game->data->delayRight = -1;
    game->data->delayDown = -1;
#ifdef STC_AUTO_ROTATION
    game->data->delayRotation = -1;
#endif
}
示例#2
0
// Start a new game
void Game::start()
{
    // Initialize game data
    mErrorCode = ERROR_NONE;
    mSystemTime = mPlatform->getSystemTime();
    mLastFallTime = mSystemTime;
    mIsOver = false;
    mIsPaused = false;
    mShowPreview = true;
    mEvents = EVENT_NONE;
    mFallingDelay = INIT_DELAY_FALL;
#ifdef STC_SHOW_GHOST_PIECE
    mShowShadow = true;
#endif

    // Initialize game statistics
    mStats.score = 0;
    mStats.lines = 0;
    mStats.totalPieces = 0;
    mStats.level = 0;
    for (int i = 0; i < TETROMINO_TYPES; ++i)
    {
        mStats.pieces[i] = 0;
    }

    // Initialize game tile map
    setMatrixCells(&mMap[0][0], BOARD_TILEMAP_WIDTH, BOARD_TILEMAP_HEIGHT, EMPTY_CELL);

    // Initialize falling tetromino
    setTetromino(mPlatform->random() % TETROMINO_TYPES, &mFallingBlock);
    mFallingBlock.x = (BOARD_TILEMAP_WIDTH - mFallingBlock.size) / 2;
    mFallingBlock.y = 0;

    // Initialize preview tetromino
    setTetromino(mPlatform->random() % TETROMINO_TYPES, &mNextBlock);

    // Initialize events
    onTetrominoMoved();

    // Initialize delayed autoshift
    mDelayLeft = -1;
    mDelayRight = -1;
    mDelayDown = -1;
#ifdef STC_AUTO_ROTATION
    mDelayRotation = -1;
#endif
}
示例#3
0
void Game::start()
{
    mErrorCode = ERROR_NONE;
    mSystemTime = mPlatform->getSystemTime();
    mLastFallTime = mSystemTime;
    mIsOver = false;
    mIsPaused = false;
    mShowPreview = true;
    mEvents = EVENT_NONE;
    mFallingDelay = INIT_DELAY_FALL;
    mShowShadow = false;
    
    mStats.score = 0;
    mStats.lines = 0;
    mStats.totalPieces = 0;
    mStats.level = 0;
    for (int i = 0; i < TETROMINO_TYPES; ++i) {
        mStats.pieces[i] = 0;
    }
    
    //初始化整个棋盘
    setMatrixCells(&mMap[0][0], BOARD_TILEMAP_WIDTH, BOARD_TILEMAP_HEIGHT, EMPTY_CELL);
    
    //开始时随机设置一个nextblock作为第一个形状
    setTetromino(mPlatform->random() % TETROMINO_TYPES, &mFallingBlock);
    
    //初始化为mFallingBlock的up-left
    mFallingBlock.x = BOARD_TILEMAP_WIDTH / 2 - mFallingBlock.size / 2;
    mFallingBlock.y = 0;
    
    setTetromino(mPlatform->random() % TETROMINO_TYPES, &mNextBlock);
    onTetrominoMoved();
    
    mDelayDown = -1;
    mDelayLeft = -1;
    mDelayRight = -1;
    mDelayRotation = -1;
}
示例#4
0
文件: game.c 项目: ex/blocks
/*
 * Move tetromino in the direction specified by (x, y) (in tile units)
 * This function detects if there are filled rows or if the move
 * lands a falling tetromino, also checks for game over condition.
 */
static void moveTetromino(StcGame *game, int x, int y) {
    int i, j, hasFullRow, numFilledRows;

    /* Check if the move would create a collision */
    if (checkCollision(game, x, y)) {
        /* In case of collision check if move was downwards (y == 1) */
        if (y == 1) {
            /* Check if collision occurs when the falling
             * tetromino is on the 1st or 2nd row */
            if (game->fallingBlock.y <= 1) {
                game->data->isOver = 1;   /* if this happens the game is over */
            }
            else {
                /* The falling tetromino has reached the bottom,
                 * so we copy their cells to the board map */
                for (i = 0; i < game->fallingBlock.size; ++i) {
                    for (j = 0; j < game->fallingBlock.size; ++j) {
                        if (game->fallingBlock.cells[i][j] != EMPTY_CELL) {
                            game->map[game->fallingBlock.x + i][game->fallingBlock.y + j]
                                    = game->fallingBlock.cells[i][j];
                        }
                    }
                }

                /* Check if the landing tetromino has created full rows */
                numFilledRows = 0;
                for (j = 1; j < BOARD_TILEMAP_HEIGHT; ++j) {
                    hasFullRow = 1;
                    for (i = 0; i < BOARD_TILEMAP_WIDTH; ++i) {
                        if (game->map[i][j] == EMPTY_CELL) {
                            hasFullRow = 0;
                            break;
                        }
                    }
                    /* If we found a full row we need to remove that row from the map
                     * we do that by just moving all the above rows one row below */
                    if (hasFullRow != 0) {
                        for (x = 0; x < BOARD_TILEMAP_WIDTH; ++x) {
                            for (y = j; y > 0; --y) {
                                game->map[x][y] = game->map[x][y - 1];
                            }
                        }
                        numFilledRows++;    /* increase filled row counter */
                    }
                }

                /* Update game statistics */
                if (numFilledRows > 0) {
                    onFilledRows(game, numFilledRows);
                }
                game->stats.totalPieces++;
                game->stats.pieces[game->fallingBlock.type]++;

                /* Use preview tetromino as falling tetromino.
                 * Copy preview tetromino for falling tetromino */
                for (i = 0; i < TETROMINO_SIZE; ++i) {
                    for (j = 0; j < TETROMINO_SIZE; ++j) {
                        game->fallingBlock.cells[i][j] = game->nextBlock.cells[i][j];
                    }
                }
                game->fallingBlock.size = game->nextBlock.size;
                game->fallingBlock.type = game->nextBlock.type;

                /* Reset position */
                game->fallingBlock.y = 0;
                game->fallingBlock.x = (BOARD_TILEMAP_WIDTH - game->fallingBlock.size) / 2;
                onTetrominoMoved(game);

                /* Create next preview tetromino */
                setTetromino(platformRandom() % TETROMINO_TYPES, &game->nextBlock);
            }
        }
    }
    else {
        /* There are no collisions, just move the tetromino */
        game->fallingBlock.x += x;
        game->fallingBlock.y += y;
    }
    onTetrominoMoved(game);
}
示例#5
0
// Move tetromino in the direction specified by (x, y) (in tile units)
// This function detects if there are filled rows or if the move
// lands a falling tetromino, also checks for game over condition.
void Game::moveTetromino(int x, int y)
{
    int i, j;

    // Check if the move would create a collision
    if (checkCollision(x, y))
    {
        // In case of collision check if move was downwards (y == 1)
        if (y == 1)
        {
            // Check if collision occurs when the falling
            // tetromino is on the 1st or 2nd row
            if (mFallingBlock.y <= 1)
            {
                mIsOver = true; // if this happens the game is over
            }
            else
            {
                // The falling tetromino has reached the bottom,
                // so we copy their cells to the board map
                for (i = 0; i < mFallingBlock.size; ++i)
                {
                    for (j = 0; j < mFallingBlock.size; ++j)
                    {
                        if (mFallingBlock.cells[i][j] != EMPTY_CELL)
                        {
                            mMap[mFallingBlock.x + i][mFallingBlock.y + j]
                                    = mFallingBlock.cells[i][j];
                        }
                    }
                }

                // Check if the landing tetromino has created full rows
                int numFilledRows = 0;
                for (j = 1; j < BOARD_TILEMAP_HEIGHT; ++j)
                {
                    bool hasFullRow = true;
                    for (i = 0; i < BOARD_TILEMAP_WIDTH; ++i)
                    {
                        if (mMap[i][j] == EMPTY_CELL)
                        {
                            hasFullRow = false;
                            break;
                        }
                    }

                    // If we found a full row we need to remove that row from the map
                    // we do that by just moving all the above rows one row below
                    if (hasFullRow)
                    {
                        for (x = 0; x < BOARD_TILEMAP_WIDTH; ++x)
                        {
                            for (y = j; y > 0; --y)
                            {
                                mMap[x][y] = mMap[x][y - 1];
                            }
                        }
                        numFilledRows++; // increase filled row counter
                    }
                }

                // Update game statistics
                if (numFilledRows > 0)
                {
                    onFilledRows(numFilledRows);
                }
                mStats.totalPieces++;
                mStats.pieces[mFallingBlock.type]++;

                // Use preview tetromino as falling tetromino.
                // Copy preview tetromino for falling tetromino
                for (i = 0; i < TETROMINO_SIZE; ++i)
                {
                    for (j = 0; j < TETROMINO_SIZE; ++j)
                    {
                        mFallingBlock.cells[i][j] = mNextBlock.cells[i][j];
                    }
                }
                mFallingBlock.size = mNextBlock.size;
                mFallingBlock.type = mNextBlock.type;

                // Reset position
                mFallingBlock.y = 0;
                mFallingBlock.x = (BOARD_TILEMAP_WIDTH - mFallingBlock.size) / 2;
                onTetrominoMoved();

                // Create next preview tetromino
                setTetromino(mPlatform->random() % TETROMINO_TYPES, &mNextBlock);
            }
        }
    }
    else
    {
        // There are no collisions, just move the tetromino
        mFallingBlock.x += x;
        mFallingBlock.y += y;
    }
    onTetrominoMoved();
}
示例#6
0
//将方块向x,y方向移动
//检测是否与已有的cell冲突或者已经落地,同时检查游戏是否结束
void Game::moveTetromino(int x, int y)
{
    //如果有冲突
    if (checkCollision(x, y)) {
        //如果是往下移动的
        if (y == 1) {
            //如果mFallingBlock刚向下移动了一格,或者还没移动就冲突了,代表游戏结束
            if (mFallingBlock.y <= 1) {
                mIsOver = true;
            }
            else {
                //游戏没有结束,mFallingBlock落地
                //那么把mFallingBlock内的元素copy到mMap中
                for (int i = 0; i < mFallingBlock.size; ++i) {
                    for (int j = 0; j < mFallingBlock.size; ++j) {
                        if (mFallingBlock.cells[i][j] != EMPTY_CELL) {
                            mMap[mFallingBlock.x + i][mFallingBlock.y + j]
                            = mFallingBlock.cells[i][j];
                        }
                    }
                }
            }
            
            //检查落地是否能够得分
            /*
             x x x x x x x x x
             x x x x x x x x x
             x x x x x x x x x
             x x x x x x x x x
             这是mMap的形状
             */
            int numFilledRows = 0;
            for (int j = 1; j < BOARD_TILEMAP_HEIGHT; ++j) {
                bool hasFullRow = true;
                for (int i = 0; i < BOARD_TILEMAP_WIDTH; ++i) {
                    if (mMap[i][j] == EMPTY_CELL) {
                        hasFullRow = false;
                        break;
                    }
                }
                
                //这一排满了
                //将这一排上面的都往下移动一排,相当于消除这一排
                //注意:(0, 0)点在上面图形的右上角,也就是屏幕的左上角
                if (hasFullRow) {
                    for (int t = j; t > 0; --t) {
                        for (int p = 0; p < BOARD_TILEMAP_WIDTH; ++p) {
                            mMap[p][t] = mMap[p][t - 1];
                        }
                    }
                    numFilledRows++;
                }
            }
            
            //计算分数
            if (numFilledRows > 0) {
                onFilledRows(numFilledRows);
            }
            
            mStats.totalPieces++;
            mStats.pieces[mFallingBlock.type]++;
            
            //用下一个形状代替fallingblock
            for (int i = 0; i < TETROMINO_SIZE; ++i) {
                for (int j = 0; j < TETROMINO_SIZE; ++j) {
                    mFallingBlock.cells[i][j] = mNextBlock.cells[i][j];
                }
            }
            mFallingBlock.size = mNextBlock.size;
            mFallingBlock.type = mNextBlock.type;
            
            mFallingBlock.y = 0;
            mFallingBlock.x = BOARD_TILEMAP_WIDTH / 2 - mFallingBlock.size / 2;
            onTetrominoMoved();
            
            //随机选择下一个方块
            setTetromino(mPlatform->random() % TETROMINO_TYPES, &mNextBlock);
        }
    }
    else {
        //没有冲突,直接移动
        mFallingBlock.x += x;
        mFallingBlock.y += y;
    }
    onTetrominoMoved();
}