grid.cpp

来自「Source code (C++) of the Amoebax game fo」· C++ 代码 · 共 1,733 行 · 第 1/5 页

CPP
1,733
字号
                   DeleteObject<Amoeba> ());    m_QueuedAmoebas.clear ();    std::for_each (m_WaitingGhostAmoebas.begin (), m_WaitingGhostAmoebas.end (),                   DeleteObject<Amoeba> ());    m_WaitingGhostAmoebas.clear ();}////// \brief Adds a new step chain label.////// An step chain label is the text that appears on the grid/// when a chain is made to let know the user which step the/// chain was made in. The label will move a little to the top/// and then will disappear.////// \param stepChain The step in which the chain was made in. It starts///                  from 1, not 0./// \param x The screen X position where the label should appear centered at./// \param y The screen Y position where the label should appear centered at.///voidGrid::addChainLabel (uint8_t stepChain, int16_t x, int16_t y){    m_ChainLabels.push_back (new ChainLabel (stepChain, x, y,                                             y - getAmoebaSize ()));}////// \brief Adds a new amoebas pair.////// \param main The main amoeba of the pair./// \param satellite The satellite amoeba of the pair. This is the one that///                  will rotate around \a main.///voidGrid::addNewPair (Amoeba *main, Amoeba *satellite){    // Just add the to the list of waiting amoebas.    m_InactiveAmoebas.push_back (main);    m_InactiveAmoebas.push_back (satellite);    // Set up the initial amoebas.    // We need to how 6 amoebas for the set up: The falling pair and    // the two waiting pairs.    if ( m_WaitingInitialAmoebas && 8 == m_InactiveAmoebas.size () )    {        m_WaitingInitialAmoebas = false;        getNextPair ();        getNextPair ();        setupFallingPair ();    }}////// \brief Removes all dying amoebas.////// Once all dying amoebas are deleted checks for floating amoebas and if/// no floating amoeba is found then sets up the falling pair.///voidGrid::clearDyingAmoebas (void){    m_DieSound->play ();    uint8_t amoebasErased = 0;    for (std::vector<FallingAmoeba>::iterator currentAmoeba =            m_DyingAmoebas.begin () ;         currentAmoeba != m_DyingAmoebas.end () ; ++currentAmoeba )    {        if ( Amoeba::ColourGhost != currentAmoeba->amoeba->getColour () )        {            ++amoebasErased;        }        setAmoebaAt (currentAmoeba->x, currentAmoeba->y, 0);        m_ActiveAmoebas.remove (currentAmoeba->amoeba);        delete currentAmoeba->amoeba;    }    m_DyingAmoebas.clear ();    // Activates all chain label.    std::for_each (getChainLabels ().begin (), getChainLabels ().end (),                   std::mem_fun (&ChainLabel::activate));    // Increment the score based on the number of non-ghost amoebas erased    // and the current step chain (starting from 0.)    uint16_t score = ((2 * amoebasErased - 4) *                      10) << getCurrentStepChain ();    incrementScore (score);    incrementCurrentStepChain ();    // Compute the number of ghost amoebas the score generates, subtracts    // the number of waiting amoebas and then set the remaining    // ghost amoebas as ghost amoebas for the opponent.    uint8_t newGhostAmoebas = static_cast<uint16_t>(std::ceil (score / static_cast<double>(70.0f)));    uint8_t remainingGhostAmoebas = removeGhostAmoebas (newGhostAmoebas);    setOpponentGhostAmoebas (remainingGhostAmoebas);    findFloatingAmoebas ();    // If there's no floating amoebas, set up the falling pair.    if ( m_FloatingAmoebas.empty () )    {        // If the positions above the grid of the 3rd column (from        // the right) is occuped by an amoeba, then the grid is        // considered filled.  If any amobea is sitting over the grid in        // any other column, this is not considered filled.        if ( 0 != getAmoebaAt (3, k_FirstVisibleHeight - 1) )        {            markAsFilled ();        }        else        {            scheduleFallingPair ();        }    }}////// \brief Finds floating amoebas.////// A floating amoeba is an amoeaba that just lost its supporting amoeba/// and hence "is floating" on the air and must start to fall.////// Checks each and every amoeba, except for those in the last line, to/// see if it's a floating amoeba and adds it to the m_FloatingAmoeba/// list if so.///voidGrid::findFloatingAmoebas (void){    // Now check which amoebas are "floating" and make them fall.    m_FloatingAmoebasVerticalOffset = 0;    for ( int16_t row = k_GridHeight - 2 ; row >= 0 ; --row )    {        for ( int16_t column = 0 ; column < k_GridWidth ; ++column )        {            Amoeba *amoeba = getAmoebaAt (column, row);            if ( 0 != amoeba && 0 == getAmoebaAt (column, row + 1) )            {                // This amoeba no longer occupes the current position.                setAmoebaAt (column, row, 0);                // Now is a falling amoeba.                FallingAmoeba floatingAmoeba;                floatingAmoeba.amoeba = amoeba;                floatingAmoeba.x = column;                floatingAmoeba.y = row;                m_FloatingAmoebas.push_back (floatingAmoeba);                // Set the state of the current and neighbour amoebas.                amoeba->setState (Amoeba::StateNone);                setAmoebaStateAt (column, row, true);            }        }    }}////// \brief Gets the amoeba at a given grid's position.////// \param x The X position of the grid to get the amoeba from./// \param y The Y position of the grid to get the amoeba from./// \return The amoeba at position \p x and \p y or 0 if there's///         no amoeba at this position or the position is incorrect (i.e.,///         out of grid's limits.)///Amoeba *Grid::getAmoebaAt (int16_t x, int16_t y) const{    if ( 0 <= x && x < k_GridWidth &&         0 <= y && y < k_GridHeight )    {        return m_Grid[y * k_GridWidth + x];    }    return 0;}////// \brief Gets the current satellite rotation degree.////// \return The current satellite rotation degree.///inline int16_tGrid::getCurrentRotationDegree (void) const{    return static_cast<int16_t> (m_CurrentRotationDegrees);}////// \brief Gets the main amoeba of the falling pair.////// \return The main falling amoeba of the falling pair.///Grid::FallingAmoebaGrid::getFallingMainAmoeba (void) const{    return m_FallingPair.main;}////// \brief Gets the satellite amoeba of the falling pair.////// \return The satellite falling amoeba of the falling pair.///Grid::FallingAmoebaGrid::getFallingSatelliteAmoeba (void) const{    return m_FallingPair.satellite;}////// \brief Gets the main amoeba that is going to fall after the next pair.////// Since this amoeba doesn't have a position, yet, we set it to/// bet at the center of the grid at the top position.////// \return The main amoeba that is going to fall after the next pair.///Grid::FallingAmoebaGrid::getFollowingFallingMainAmoeba (void) const{    FallingAmoeba followingMain;    followingMain.x = k_GridWidth / 2;    followingMain.y = -1;    std::list<FallingPair>::const_iterator pair = m_Queue.begin ();    ++pair;    assert (m_Queue.end () != pair &&            "The pairs queue doesn't have two pairs" );    followingMain.amoeba = pair->main.amoeba;    return followingMain;}////// \brief Gets the satellite amoeba that is going to fall after the next pair.////// Since this amoeba doesn't have a position, yet, we set it to/// bet at the center of the grid at the top position.////// \return The satellite amoeba that is going to fall after the next pair.///Grid::FallingAmoebaGrid::getFollowingFallingSatelliteAmoeba (void) const{    FallingAmoeba followingSatellite;    followingSatellite.x = k_GridWidth / 2;    followingSatellite.y = -1;    std::list<FallingPair>::const_iterator pair = m_Queue.begin ();    ++pair;    assert (m_Queue.end () != pair &&            "The pairs queue doesn't have two pairs" );    followingSatellite.amoeba = pair->satellite.amoeba;    return followingSatellite;}////// \brief Gets the main amoeba that is going to fall next.////// Since this amoeba doesn't have a position, yet, we set it to/// be at the center of the grid at the top position.////// \return The main amoeba that is going to fall next.///Grid::FallingAmoebaGrid::getNextFallingMainAmoeba (void) const{    FallingAmoeba nextMain;    nextMain.x = k_GridWidth / 2;    nextMain.y = -1;    std::list<FallingPair>::const_iterator pair = m_Queue.begin ();    assert (m_Queue.end () != pair && "The pairs queue is empty" );    nextMain.amoeba = pair->main.amoeba;    return nextMain;}////// \brief Gets the main amoeba that is going to fall next.////// Since this amoeba doesn't have a position, yet, we set it to/// be at the center of the grid at the top position.////// \return The main amoeba that is going to fall next.///Grid::FallingAmoebaGrid::getNextFallingSatelliteAmoeba (void) const{    FallingAmoeba nextSatellite;    nextSatellite.x = k_GridWidth / 2;    nextSatellite.y = -2;    std::list<FallingPair>::const_iterator pair = m_Queue.begin ();    assert (m_Queue.end () != pair && "The pairs queue is empty" );    nextSatellite.amoeba = pair->satellite.amoeba;    return nextSatellite;}////// \brief Gets the next pair from the inactive list and sets it to the queue.////// The next pair will be the last element in the queue, so it should/// be called when the first element of the queue becomes the falling pair.////// If the inactive amoebas list becomes empty, this function request/// to the pair generator a new pair.///voidGrid::getNextPair (void){    assert ( 0 != m_Generator &&            "Tried to get the next pair without a generator.");    assert ( 2 <= m_InactiveAmoebas.size () &&            "Tried to get the next pair, but the inactive list is empty.");    // Gets the next pair from the inactive list.    Amoeba *main = m_InactiveAmoebas.front ();    m_InactiveAmoebas.pop_front ();    Amoeba *satellite = m_InactiveAmoebas.front ();    m_InactiveAmoebas.pop_front ();    // And set them to queued.    m_QueuedAmoebas.push_back (main);    m_QueuedAmoebas.push_back (satellite);    // Sets they position to be the last pair on the queue.    // Take into account the side where the queue is located at    // to choose the offset to apply to this pair.    uint16_t lastPairOffsetX = getAmoebaSize () / 2;    if ( LayoutVertical == getLayout () )    {        if ( Grid::QueueSideLeft == getQueueSide () )        {            lastPairOffsetX = -lastPairOffsetX;        }        main->setX (getQueuePositionX () + lastPairOffsetX);        main->setY (getQueuePositionY () + getAmoebaSize () * 3);        satellite->setX (getQueuePositionX () + lastPairOffsetX);        satellite->setY (getQueuePositionY () + getAmoebaSize () * 2);    }    else    {        if (Grid::QueueSideLeft == getQueueSide () )        {            main->setX (getQueuePositionX () - getAmoebaSize () * 4);            main->setY (getQueuePositionY () + lastPairOffsetX);            satellite->setX (getQueuePositionX () - getAmoebaSize () * 3);            satellite->setY (getQueuePositionY () + lastPairOffsetX);        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?