예제 #1
1
int main()
{
    enum GameState
    {
        MainMenu,
        Playing,
        GameOver
    };

    GameState state = GameState::MainMenu;
    VideoMode videoMode(SCREEN_WIDTH, SCREEN_HEIGHT);
    RenderWindow renderWindow(videoMode, "SFML Tetris");
    Event gameEvent;
    Texture backgroundTexture;
    Texture brickPreviewBackground;
    Texture gameOverBackground;
    Texture mainMenuBackground;
    Sprite mainMenuBackgroundSprite;
    Sprite brickPreviewSprite;
    Sprite backgroundSprite;
    Sprite gameOverBackgroundSprite;
    SoundBuffer dropSoundBuffer;
    Sound dropSound;
    Music music;
    Text scoreHeaderText("Score: ");
    Text scoreDisplayText;
    Text levelHeaderText("Level: ");
    Text levelDisplayText;
    Text nextBrickText("Next: ");
    Text gameOverHeaderText("\t  GAME OVER!\nHere are your final stats:");
    Text mainMenuHeaderText("SFML TETRIS!");
    Text mainMenuStartText("Start");
    Text mainMenuQuitText("Quit");
    Text brickCountText[NUMBER_OF_BRICK_TYPES];
    bool gameBoard[GB_HEIGHT][GB_WIDTH];
    unsigned int score = 0;
    unsigned int level = 1;
    unsigned int totalLines = 0;
    unsigned int brickCount[NUMBER_OF_BRICK_TYPES] = {0};
    vector<Brick> brickQueue;
    vector<Brick> brickList;
    Clock brickLockTimer;
    Clock brickFallTimer;
    bool isCheckingLockTime = false;

    backgroundTexture.LoadFromFile("Images/background.png");
    brickPreviewBackground.LoadFromFile("Images/previewBG.png");
    gameOverBackground.LoadFromFile("Images/gameOverBG.png");
    mainMenuBackground.LoadFromFile("Images/mainMenuBG.png");

    brickPreviewSprite.SetTexture(brickPreviewBackground);
    brickPreviewSprite.SetPosition(450, 150);

    backgroundSprite.SetTexture(backgroundTexture);

    gameOverBackgroundSprite.SetTexture(gameOverBackground);
    gameOverBackgroundSprite.SetPosition(110, 82);

    mainMenuBackgroundSprite.SetTexture(mainMenuBackground);

    scoreHeaderText.SetCharacterSize(TEXT_CHAR_SIZE);
    scoreHeaderText.SetPosition(450, 20);

    char* scoreDisplayBuffer = new char;
    scoreDisplayText.SetCharacterSize(TEXT_CHAR_SIZE);
    scoreDisplayText.SetPosition(520, 20);

    levelHeaderText.SetCharacterSize(TEXT_CHAR_SIZE);
    levelHeaderText.SetPosition(450, 60);

    char* levelDisplayBuffer = new char;
    levelDisplayText.SetCharacterSize(TEXT_CHAR_SIZE);
    levelDisplayText.SetPosition(520, 60);

    nextBrickText.SetCharacterSize(TEXT_CHAR_SIZE);
    nextBrickText.SetPosition(450, 120);

    gameOverHeaderText.SetCharacterSize(TEXT_CHAR_SIZE);
    gameOverHeaderText.SetPosition(210, 265);

    mainMenuHeaderText.SetCharacterSize(40);
    mainMenuHeaderText.SetPosition(180, 50);

    mainMenuStartText.SetCharacterSize(32);
    mainMenuStartText.SetPosition(285, 210);

    mainMenuQuitText.SetCharacterSize(32);
    mainMenuQuitText.SetPosition(285, 310);

    char* brickCountTextBuffer[NUMBER_OF_BRICK_TYPES];
    for (int i = 0; i < NUMBER_OF_BRICK_TYPES; i++)
    {
        brickCountTextBuffer[i] = new char;
        brickCountText[i].SetPosition(100, 50 * (i + 1));
    }

    dropSoundBuffer.LoadFromFile("Sounds/drop.wav");
    dropSound.SetBuffer(dropSoundBuffer);

    for (int i = 0; i < GB_HEIGHT; i++)
    {
        for (int j = 0; j < GB_WIDTH; j++)
        {
            gameBoard[i][j] = false;
        }
    }

    RefillBrickQueue(&brickQueue);
    Brick activeBrick = PullBrickFromQueue(&brickQueue);
    Brick previewBrick = PullBrickFromQueue(&brickQueue);
    previewBrick.SetPreviewPosition();

    bool isGameOver = false;

    while (renderWindow.IsOpen())
    {
        switch (state)
        {
        case GameState::MainMenu:
        {
            while (renderWindow.PollEvent(gameEvent))
            {
                if (gameEvent.Type == Event::Closed || gameEvent.Key.Code == Keyboard::Escape)
                {
                    renderWindow.Close();
                }
                else if (gameEvent.Type == Event::MouseButtonPressed)
                {
                    Vector2i mousePos = Mouse::GetPosition(renderWindow);

                    if (mousePos.x >= 220 && mousePos.x <= 420 &&
                            mousePos.y >= 200 && mousePos.y <= 260)
                    {
                        state = GameState::Playing;
                    }
                    else if ((mousePos.x >= 220 && mousePos.x <= 420 &&
                              mousePos.y >= 300 && mousePos.y <= 360) ||
                             gameEvent.Key.Code == Keyboard::Escape)
                    {
                        renderWindow.Close();
                    }
                }
            }

            renderWindow.Draw(mainMenuBackgroundSprite);
            renderWindow.Draw(mainMenuHeaderText);
            renderWindow.Draw(mainMenuStartText);
            renderWindow.Draw(mainMenuQuitText);
            renderWindow.Display();
            break;
        }

        case GameState::GameOver:
        {
            Text gameOverScoreHeaderText = scoreHeaderText;
            gameOverScoreHeaderText.SetPosition(130, 320);
            Text gameOverScoreDisplayText = scoreDisplayText;
            gameOverScoreDisplayText.SetPosition(210, 320);
            Text gameOverLevelHeaderText = levelHeaderText;
            gameOverLevelHeaderText.SetPosition(130, 350);
            Text gameOverLevelDisplayText = levelDisplayText;
            gameOverLevelDisplayText.SetPosition(210, 350);

            while (renderWindow.PollEvent(gameEvent))
            {
                if (gameEvent.Type == Event::Closed || gameEvent.Key.Code == Keyboard::Escape)
                {
                    renderWindow.Close();
                }
            }

            renderWindow.Draw(gameOverBackgroundSprite);
            renderWindow.Draw(gameOverHeaderText);
            renderWindow.Draw(gameOverScoreHeaderText);
            renderWindow.Draw(gameOverScoreDisplayText);
            renderWindow.Draw(gameOverLevelHeaderText);
            renderWindow.Draw(gameOverLevelDisplayText);
            renderWindow.Display();
            break;
        }

        case GameState::Playing:
        {
            if (activeBrick.IsLocked())
            {
                dropSound.Play();
                brickList.push_back(activeBrick);
                brickCount[(int)activeBrick.GetBrickType()]++;
                int linesCleared = 0;

                for (int i = 0; i < SPRITES_IN_BRICK; i++)
                {
                    if (activeBrick.GetSpriteYPosition(i) < BRICK_UPPER_BOUNDRY)
                    {
                        state = GameState::GameOver;
                        break;
                    }
                    else
                    {
                        gameBoard[activeBrick.GetSpriteYPosition(i)][activeBrick.GetSpriteXPosition(i)] = true;
                    }
                }

                if (state == GameState::GameOver)
                {
                    break;
                }

                //Check if there are any full rows that need to be cleared.
                for (int i = BRICK_UPPER_BOUNDRY; i < GB_HEIGHT; i++)
                {
                    for (int j = 0; j < GB_WIDTH; j++)
                    {
                        if (gameBoard[i][j])
                        {
                            if (j == GB_WIDTH - 1)
                            {
                                ClearRow(&brickList, i, gameBoard);
                                linesCleared++;
                                totalLines++;

                                if (totalLines % 8 == 0 && level < LEVEL_MAX)
                                {
                                    level++;
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (linesCleared > 0)
                {
                    if (linesCleared > 1 && linesCleared < 4)
                    {
                        score += (linesCleared * MULTI_LINE_CLEAR_SCORE) + BRICK_LOCK_SCORE;
                    }
                    else if (linesCleared == 4)
                    {
                        score += TETRIS_CLEAR_SCORE + BRICK_LOCK_SCORE;
                    }
                    else
                    {
                        score += SINGLE_LINE_CLEAR_SCORE + BRICK_LOCK_SCORE;
                    }
                }
                else
                {
                    score += BRICK_LOCK_SCORE;
                }

                activeBrick = previewBrick;
                activeBrick.SetActivePosition();
                previewBrick = PullBrickFromQueue(&brickQueue);
                previewBrick.SetPreviewPosition();
            }

            else
            {
                Time fallTimer = brickFallTimer.GetElapsedTime();
                Time lockTimer = brickLockTimer.GetElapsedTime();
                float dropSpeed = 1 - (float)(level * 0.05f);

                if (!IsBottomCollision(activeBrick, gameBoard) && fallTimer.AsSeconds() >= dropSpeed)
                {
                    for (int i = 0; i < SPRITES_IN_BRICK; i++)
                    {
                        activeBrick.SetSpriteYPosition(i, 1);
                        brickFallTimer.Restart();
                        isCheckingLockTime = false;
                    }
                }

                else if (IsBottomCollision(activeBrick, gameBoard))
                {
                    if (!isCheckingLockTime)
                    {
                        isCheckingLockTime = true;
                        brickLockTimer.Restart();
                    }

                    else if (lockTimer.AsSeconds() >= 0.5f)
                    {
                        activeBrick.LockBrick();
                        isCheckingLockTime = false;
                    }
                }

            }

            while (renderWindow.PollEvent(gameEvent))
            {
                if (gameEvent.Type == Event::Closed || gameEvent.Key.Code == Keyboard::Escape)
                {
                    renderWindow.Close();
                }

                if (gameEvent.Type == Event::KeyPressed)
                {
                    CheckInput(&gameEvent, &activeBrick, gameBoard, &score);
                }
            }

            scoreDisplayText.SetString(_itoa(score, scoreDisplayBuffer, 10));
            levelDisplayText.SetString(_itoa(level, levelDisplayBuffer, 10));

            for (int i = 0; i < NUMBER_OF_BRICK_TYPES; i++)
            {
                brickCountText[i].SetString(_itoa(brickCount[i], brickCountTextBuffer[i], 10));
            }

            renderWindow.Clear(Color(0, 255, 255));
            renderWindow.Draw(backgroundSprite);
            renderWindow.Draw(scoreHeaderText);
            renderWindow.Draw(scoreDisplayText);
            renderWindow.Draw(levelHeaderText);
            renderWindow.Draw(levelDisplayText);
            renderWindow.Draw(brickPreviewSprite);
            renderWindow.Draw(nextBrickText);

            for (int i = 0; i < NUMBER_OF_BRICK_TYPES; i++)
            {
                renderWindow.Draw(brickCountText[i]);
            }

            for (int i = 0; i < brickList.size(); i++)
            {
                for (int j = 0; j < SPRITES_IN_BRICK; j++)
                {
                    renderWindow.Draw(brickList[i].GetSpriteArray()[j]);
                }
            }

            for (int i = 0; i < SPRITES_IN_BRICK; i++)
            {
                renderWindow.Draw(activeBrick.GetSpriteArray()[i]);
                renderWindow.Draw(previewBrick.GetSpriteArray()[i]);
            }
            renderWindow.Display();
            break;

        }	//END CASE

        }	//END SWITCH

    } //END GAME LOOP

    return 0;
}
예제 #2
0
파일: Text.cpp 프로젝트: r-lyeh/moon9
void Text::RefreshSizeWrap()
{
	RemoveAllChildren();

	for( TextLines::const_iterator it = m_Lines.begin(), end = m_Lines.end(); it != end; ++it )
	{
		Text *t = *it;
		delete t, t = 0;
	}

	m_Lines.clear();

	std::vector<Gwen::UnicodeString> words;
	SplitWords( GetText().GetUnicode(), L' ', words );

	// Adding a bullshit word to the end simplifies the code below
	// which is anything but simple.
	words.push_back( L"" );

	if ( !GetFont() )
	{
		Debug::AssertCheck( 0, "Text::RefreshSize() - No Font!!\n" );
		return;
	}

	Point pFontSize = GetSkin()->GetRender()->MeasureText( GetFont(), L" " );

	int w = GetParent()->Width();
	int x = 0, y = 0;

	Gwen::UnicodeString strLine;

	std::vector<Gwen::UnicodeString>::iterator it = words.begin();
	for ( it; it != words.end(); ++it )
	{
		bool bFinishLine = false;
		bool bWrapped = false;

		// If this word is a newline - make a newline (we still add it to the text)
		if ( (*it).c_str()[0] == L'\n' ) bFinishLine = true;

		// Does adding this word drive us over the width?
		{
			strLine += (*it);
			Gwen::Point p = GetSkin()->GetRender()->MeasureText( GetFont(), strLine );
			if ( p.x > Width() ) { bFinishLine = true; bWrapped = true; }
		}

		// If this is the last word then finish the line
		if ( --words.end() == it )
		{
			bFinishLine = true;
		}

		if ( bFinishLine )
		{
			Text* t = new Text( this );
				t->SetFont( GetFont() );
				t->SetString( strLine.substr( 0, strLine.length() - (*it).length() ) );
				t->RefreshSize();
				t->SetPos( x, y );
			m_Lines.push_back( t );

			// newline should start with the word that was too big
			strLine = *it;

			// Position the newline
			y += pFontSize.y;
			x = 0;

			//if ( strLine[0] == L' ' ) x -= pFontSize.x;
		}

	}

	// Size to children height and parent width
	{
		Point childsize = ChildrenSize();
		SetSize( w, childsize.y );
	}

	InvalidateParent();
	Invalidate();
}
예제 #3
0
void Text::RefreshSizeWrap()
{
	RemoveAllChildren();

	for ( TextLines::iterator it = m_Lines.begin(); it != m_Lines.end(); ++it )
	{
		delete *it;
	}

	m_Lines.clear();
	std::vector<Gwen::UnicodeString> words;
	SplitWords( GetText().GetUnicode(), words );
	// Adding a bullshit word to the end simplifies the code below
	// which is anything but simple.
	words.push_back( L"" );

	if ( !GetFont() )
	{
		Debug::AssertCheck( 0, "Text::RefreshSize() - No Font!!\n" );
		return;
	}

	Point pFontSize = GetSkin()->GetRender()->MeasureText( GetFont(), L" " );
	int w = GetParent()->Width() - GetParent()->GetPadding().left-GetParent()->GetPadding().right; 
	int x = 0, y = 0;
	Gwen::UnicodeString strLine;

	for ( std::vector<Gwen::UnicodeString>::iterator it = words.begin(); it != words.end(); ++it )
	{
		bool bFinishLine = false;
		bool bWrapped = false;

		// If this word is a newline - make a newline (we still add it to the text)
		if ( ( *it ).c_str() [0] == L'\n' ) { bFinishLine = true; }

		// Does adding this word drive us over the width?
		{
			strLine += ( *it );
			Gwen::Point p = GetSkin()->GetRender()->MeasureText( GetFont(), strLine );

			if ( p.x > w ) { bFinishLine = true; bWrapped = true; }
		}

		// If this is the last word then finish the line
		if ( --words.end() == it )
		{
			bFinishLine = true;
		}

		if ( bFinishLine )
		{
			Text* t = new Text( this );
			t->SetFont( GetFont() );
			t->SetTextColor( m_Color );
			if(bWrapped)
			{
				t->SetString( strLine.substr( 0, strLine.length() - (*it).length() ) );
				// newline should start with the word that was too big
				strLine = *it;
			}
			else
			{
				t->SetString( strLine.substr( 0, strLine.length()) );
				//new line is empty
				strLine.clear();
			} 
			t->RefreshSize();
			t->SetPos( x, y );
			m_Lines.push_back( t );

			// newline should start with the word that was too big
			// strLine = *it;

			// Position the newline
			y += pFontSize.y;
			x = 0;
			//if ( strLine[0] == L' ' ) x -= pFontSize.x;
		}
	}

	// Size to children height and parent width
	Point childsize = ChildrenSize();
	{
		SetSize( w, childsize.y );
	}

	// Align the text within the parent
	int y_offset = 0;
	for ( TextLines::iterator it = m_Lines.begin(); it != m_Lines.end(); ++it )
	{
		Text* text = *it;
		const Rect & bounds = GetInnerBounds();

		int x = 0;
		int y = 0;

		if ( m_iAlign & Pos::Left )		{ x = bounds.x; }
		if ( m_iAlign & Pos::Right )	{ x = bounds.x + ( bounds.w - text->Width() ); }
		if ( m_iAlign & Pos::CenterH )	{ x = bounds.x + ( bounds.w - text->Width() )  * 0.5; }
		if ( m_iAlign & Pos::Top )		{ y = bounds.y; }
		if ( m_iAlign & Pos::Bottom )	{ y = bounds.y + ( bounds.h - childsize.y ); }
		if ( m_iAlign & Pos::CenterV )	{ y = bounds.y + ( bounds.h - childsize.y )  * 0.5; }

		text->SetPos( x, y + y_offset );

		y_offset += text->Height();
	}

	InvalidateParent();
	Invalidate();
}
예제 #4
0
void Text::RefreshSizeWrap()
{
    RemoveAllChildren();
    m_Lines.clear();

    stl::vector<Gwen::String> words;
    SplitWords( GetText().Get(), ' ', words );

    // Adding a bullshit word to the end simplifies the code below
    // which is anything but simple.
    words.push_back( "" );

    if ( !GetFont() )
    {
        Debug::AssertCheck( 0, "Text::RefreshSize() - No Font!!\n" );
        return;
    }

    Point pFontSize = GetSkin()->GetRender()->MeasureText( GetFont(), " " );

    int w = GetParent()->Width();
    int x = 0, y = 0;

    Gwen::String strLine;

    stl::vector<Gwen::String>::iterator it = words.begin();
    for (; it != words.end(); ++it )
    {
        bool bFinishLine = false;
        //bool bWrapped = false;

        // If this word is a newline - make a newline (we still add it to the text)
        if ( (*it).c_str()[0] == '\n' ) bFinishLine = true;

        // Does adding this word drive us over the width?
        {
            strLine += (*it);
            Gwen::Point p = GetSkin()->GetRender()->MeasureText( GetFont(), strLine );
            if ( p.x > Width() ) {
                bFinishLine = true; /*bWrapped = true;*/
            }
        }

        // If this is the last word then finish the line
        // if ( --words.end() == it )
        // NOTE: replaced above commented out 'if' statement with this to appease
        //       the GCC compiler that comes with Marmalade SDK 6.0
        stl::vector<Gwen::String>::iterator temp = words.end() - 1;
        if ( temp == it )
        {
            bFinishLine = true;
        }

        if ( bFinishLine )
        {
            Text* t = new Text( this );
            t->SetFont( GetFont() );
            t->SetString( strLine.substr( 0, strLine.length() - (*it).length() ) );
            t->RefreshSize();
            t->SetPos( x, y );
            m_Lines.push_back( t );

            // newline should start with the word that was too big
            strLine = *it;

            // Position the newline
            y += pFontSize.y;
            x = 0;

            //if ( strLine[0] == ' ' ) x -= pFontSize.x;
        }

    }

    // Size to children height and parent width
    {
        Point childsize = ChildrenSize();
        SetSize( w, childsize.y );
    }

    InvalidateParent();
    Invalidate();
}