twoplayersstate.cpp

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

CPP
804
字号
//// Cross-platform free Puyo-Puyo clone.// Copyright (C) 2006, 2007 Emma's Software//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.//#if defined (HAVE_CONFIG_H)#include <config.h>#endif // HAVE_CONFIG_H#include <cassert>#include <SDL.h>#include <sstream>
#include <algorithm>
#include "Amoeba.h"#include "DrawAmoeba.h"#include "DrawChainLabel.h"#include "File.h"#include "NormalState.h"#include "System.h"#include "TwoPlayersState.h"using namespace Amoebax;/// The size of the silhouettes' border in pixels.static const uint8_t k_SilhouetteBorder = 8;////// \brief Default constructor.////// \param leftPlayer The player that will control the left grid./// \param rightPlayer The player that will control the right grid./// \param backgroundFileName The file to use as background./// \param leftPlayerScore The initial score of the left player./// \param rightPlayerScore The initial score of the right player./// \param observer The class that will receive an end of match notify.///TwoPlayersState::TwoPlayersState (IPlayer *leftPlayer, IPlayer *rightPlayer,                                  const std::string &backgroundFileName,                                  uint32_t leftPlayerScore,                                  uint32_t rightPlayerScore,                                  IMatchObserver *observer):    IState (),    m_Amoebas (0),    m_AmoebasSize (k_MaxAmoebasSize),    m_Background (0),    m_BackgroundFileName (backgroundFileName),    m_BackgroundMusic (0),    m_ChainLabel (0),    m_GameIsOver (false),    m_Generator (new PairGenerator ()),    m_Go (0),    m_GoTime (k_DefaultGoTime),    m_LeftPlayer (leftPlayer),    m_Observer(observer),    m_Ready (0),    m_ReadyTime (k_DefaultGoTime * 2),    m_RightPlayer (rightPlayer),    m_ScoreFont (0),    m_SilhouetteBorder (k_SilhouetteBorder),    m_Silhouettes (0),    m_StateAlreadyRemoved (false),    m_YouLose (0),    m_YouWin (0),    m_Winner (IPlayer::RightSide){    assert ( 0 < getAmoebasSize () && "The amoebas' size is invalid." );    assert ( 0 != getLeftPlayer () && "The left player is NULL." );    assert ( 0 != getRightPlayer () && "The right player is NULL." );    loadGraphicsResources ();    float screenScale = System::getInstance ().getScreenScaleFactor ();    getLeftPlayer ()->setGrid (            new Grid (static_cast<uint16_t>(k_PositionXLeftGrid * screenScale),                      static_cast<uint16_t>(k_PositionYLeftGrid * screenScale),                      static_cast<uint16_t>(k_PositionXLeftQueue * screenScale),                      static_cast<uint16_t>(k_PositionYLeftQueue * screenScale),                      static_cast<uint16_t>(k_PositionXLeftWaiting * screenScale),                      static_cast<uint16_t>(k_PositionYLeftWaiting * screenScale),                      getAmoebasSize (), Grid::QueueSideRight, leftPlayerScore));    m_Generator->addGrid (getLeftGrid ());    getRightPlayer ()->setGrid (            new Grid (static_cast<uint16_t>(k_PositionXRightGrid * screenScale),                      static_cast<uint16_t>(k_PositionYRightGrid * screenScale),                      static_cast<uint16_t>(k_PositionXRightQueue * screenScale),                      static_cast<uint16_t>(k_PositionYRightQueue * screenScale),                      static_cast<uint16_t>(k_PositionXRightWaiting * screenScale),                      static_cast<uint16_t>(k_PositionYRightWaiting * screenScale),                      getAmoebasSize (), Grid::QueueSideLeft, rightPlayerScore));    m_Generator->addGrid (getRightGrid ());    // Generate the four first amoebas.    m_Generator->generate (4);    // Load music.    std::string musicFileName (backgroundFileName);    musicFileName.replace (musicFileName.rfind (".png"), 4, ".ogg");    m_BackgroundMusic.reset (            Music::fromFile (File::getMusicFilePath (musicFileName)));}voidTwoPlayersState::activate (void){    getLeftPlayer ()->loadOptions ();    getRightPlayer ()->loadOptions ();    if ( Music::isPaused () )    {        Music::resume ();    }    else    {        m_BackgroundMusic->play ();    }}////// \brief Checks if the key should remove the current state.////// If the game is over and the user presses any key different/// to the player's keys, then the state should be removed from the/// system.////// \param key The key to check to see if it's an already mapped key///            to a player.///voidTwoPlayersState::checkForRemoveStateKey (uint32_t key){    Options::PlayerControls leftPlayer =        Options::getInstance ().getPlayerControls (IPlayer::LeftSide);    Options::PlayerControls rightPlayer =        Options::getInstance ().getPlayerControls (IPlayer::RightSide);    if ( gameIsOver () && !m_StateAlreadyRemoved &&#if defined IS_GP2X_HOST && !defined __SYMBIAN32__        (key == GP2X_BUTTON_START ||         key == GP2X_BUTTON_SELECT ||         key == GP2X_BUTTON_X)#else // !IS_GP2X_HOST         key != leftPlayer.keyboard.moveLeft &&         key != leftPlayer.keyboard.moveRight &&         key != leftPlayer.keyboard.pushDown &&         key != leftPlayer.keyboard.rotateClockwise &&         key != leftPlayer.keyboard.rotateCounterClockwise &&         key != rightPlayer.keyboard.moveLeft &&         key != rightPlayer.keyboard.moveRight &&         key != rightPlayer.keyboard.pushDown &&         key != rightPlayer.keyboard.rotateClockwise &&         key != rightPlayer.keyboard.rotateCounterClockwise#endif // IS_GP2X_HOST         )    {        System::getInstance ().removeActiveState ();        m_StateAlreadyRemoved = true;    }}////// \brief Tells if the game is over.////// \return \a true if the game is over, \a false otherwise.///inline boolTwoPlayersState::gameIsOver (void) const{    return m_GameIsOver;}////// \brief Gets the amoebas' size.////// \return The size of the amoebas. Since the amoebas are squared, this///         size is the same for width and for height.///inline uint8_tTwoPlayersState::getAmoebasSize (void) const{    return m_AmoebasSize;}////// \brief Gets the time to display the "Go!" label.////// \return The time that the "Go!" label should be visible.///inline int32_tTwoPlayersState::getGoTime (void) const{    return m_GoTime;}////// \brief Gets the left player's grid.////// \return The grid of the left player.///inline Grid *TwoPlayersState::getLeftGrid (void) const{    IPlayer *player = getLeftPlayer ();    assert ( 0 != player && "The left player is NULL." );    return player->getGrid ();}////// \brief Gets the player of the left grid.////// \return The pointer to the player that controls the left grid.///inline IPlayer *TwoPlayersState::getLeftPlayer (void) const{    return m_LeftPlayer.get ();}////// \brief Gets the time to display the "Ready?" label.////// \return The time that the "Ready?" label should be visible.///inline int32_tTwoPlayersState::getReadyTime (void) const{    return m_ReadyTime;}////// \brief Gets the right player's grid.////// \return The grid of the right player.///inline Grid *TwoPlayersState::getRightGrid (void) const{    IPlayer *player = getRightPlayer ();    assert ( 0 != player && "The right player is NULL." );    return player->getGrid ();}////// \brief Gets the player of the right grid.////// \return The pointer to the player that controls the left grid.///inline IPlayer *TwoPlayersState::getRightPlayer (void) const{    return m_RightPlayer.get ();}////// \brief Gets the size of the silhouettes' border.////// \return The size of the silhouettes's border.///inline uint8_tTwoPlayersState::getSilhouetteBorder (void) const{    return m_SilhouetteBorder;}////// \brief Gets the winner's side.////// \return The side whose player is the winner.///inline IPlayer::PlayerSideTwoPlayersState::getWinnerSide (void) const{    return m_Winner;}voidTwoPlayersState::joyMotion (uint8_t joystick, uint8_t axis, int16_t value){    getLeftPlayer ()->joyMotion (joystick, axis, value);    getRightPlayer ()->joyMotion (joystick, axis, value);}voidTwoPlayersState::joyDown (uint8_t joystick, uint8_t button){    if ( gameIsOver () )    {#if defined (IS_GP2X_HOST)        checkForRemoveStateKey (static_cast<uint32_t>(button));#endif // IS_GP2X_HOST    }#if defined (IS_GP2X_HOST)&& !defined (__SYMBIAN32__)    else if ( button == GP2X_BUTTON_START ||              button == GP2X_BUTTON_X )    {        System::getInstance ().pause ();    }#endif // IS_GP2X_HOST    else    {        getLeftPlayer ()->joyDown (joystick, button);        getRightPlayer ()->joyDown (joystick, button);    }}voidTwoPlayersState::joyUp (uint8_t joystick, uint8_t button){    if ( !gameIsOver () )    {        getLeftPlayer ()->joyUp (joystick, button);        getRightPlayer ()->joyUp (joystick, button);    }}#if !defined (IS_GP2X_HOST)|| defined (__SYMBIAN32__)voidTwoPlayersState::keyDown (uint32_t key){    if ( gameIsOver () )    {        checkForRemoveStateKey (key);    }    else if ( SDLK_ESCAPE == key )    {        System::getInstance ().pause ();    }    else    {        getLeftPlayer ()->keyDown (key);        getRightPlayer ()->keyDown (key);    }}voidTwoPlayersState::keyUp (uint32_t key){    if ( !gameIsOver () )    {        getRightPlayer ()->keyUp (key);        getLeftPlayer ()->keyUp (key);    }}#endif // !IS_GP2X_HOST////// \brief Loads all graphical resources.///voidTwoPlayersState::loadGraphicsResources (void){    float screenScale = System::getInstance ().getScreenScaleFactor ();    m_Amoebas.reset (            Surface::fromFile (File::getGraphicsFilePath ("amoebas.png")));    m_Amoebas->resize (screenScale);    setAmoebasSize (static_cast<uint8_t> (k_MaxAmoebasSize * screenScale));    m_Background.reset (            Surface::fromFile (File::getGraphicsFilePath (m_BackgroundFileName)));    {        std::auto_ptr<Surface> gridBackground (            Surface::fromFile (File::getGraphicsFilePath ("twoplayers.png")));        gridBackground->blit (m_Background->toSDLSurface ());    }    m_Background->resize (screenScale);    m_ChainLabel.reset (            Surface::fromFile (File::getGraphicsFilePath ("chain.png")));    m_ChainLabel->resize (screenScale);    m_Silhouettes.reset (            Surface::fromFile (File::getGraphicsFilePath ("silhouettes.png")));    m_Silhouettes->resize (screenScale);    setSilhouetteBorder (static_cast<uint8_t> (screenScale *                                               k_SilhouetteBorder));    m_YouLose.reset (            Surface::fromFile (File::getGraphicsFilePath ("YouLose.png")));    m_YouLose->resize (screenScale);    m_YouWin.reset (            Surface::fromFile (File::getGraphicsFilePath ("YouWin.png")));    m_YouWin->resize (screenScale);    m_ScoreFont.reset (Font::fromFile (File::getFontFilePath ("score")));    // Load the "Go!" and "Ready?" labels only if they are going to be shown.    if ( mustShowInitialLabels () )    {

⌨️ 快捷键说明

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