예제 #1
0
        public void EnterSelection(GameData data)
        {
            switch (pauseSelection)
            {
            case PauseSelection.Continue:
                data.State.RemoveState();
                break;

            case PauseSelection.Restart:
                data.State.AddState(new GamePlayState(), true);
                break;

            case PauseSelection.Quit:
                data.State.RemoveState();
                data.State.AddState(new MenuState(), true);
                break;
            }

            _selectSound.Play();
        }
예제 #2
0
        /// <summary>
        /// Adds a random block in the top middle
        /// </summary>
        public void AddRandomBlock()
        {
            // Randomize block type and rotation
            mCurrentBlockType = (int)mNextBlock.SetNewRandomBlock();
            mCurrentBlockRot  = RandomHelper.GetRandomInt(4);

            // Get precalculated shape
            int[,] shape = mBlockTypeShapes[mCurrentBlockType, mCurrentBlockRot];
            int xPos = GridWidth / 2 - shape.GetLength(0) / 2;

            // Center block at top most position of our grid
            mCurrentBlockPos = new Point(xPos, 0);

            // Add new block
            for (int x = 0; x < shape.GetLength(0); x++)
            {
                for (int y = 0; y < shape.GetLength(1); y++)
                {
                    if (shape[x, y] > 0)
                    {
                        // Check if there is already something
                        if (mGrid[x + xPos, y] != EBlockTypes.Empty)
                        {
                            // Then game is over dude!
                            GameOver = true;
                            Sound.Play(ESoundTypes.Lose);
                        }
                        else
                        {
                            mGrid[x + xPos, y]         = (EBlockTypes)mCurrentBlockType;
                            mFloatingGrid[x + xPos, y] = true;
                        }
                    }
                }
            }

            // Add 1 point per block!
            TotalScore++;
        }
예제 #3
0
        /// <summary>
        /// Update whole field, move current floating stuff down
        /// and check if any full lines are given.
        /// Note: Do not use the override Update(gameTime) method here,
        /// Update is ONLY called when 1000ms have passed (level 1), or
        /// 100ms for level 10.
        /// </summary>
        public void Update()
        {
            if (GameOver || TetrisGame.Paused)
            {
                return;
            }

            if (MoveBlock(EMoveTypes.Down) == false || MovingDownWasBlocked)
            {
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        mFloatingGrid[x, y] = false;
                    }
                }
                Sound.Play(ESoundTypes.BlockFalldown);
            }
            MovingDownWasBlocked = false;

            bool canMove = false;

            for (int x = 0; x < GridWidth; x++)
            {
                for (int y = 0; y < GridHeight; y++)
                {
                    if (mFloatingGrid[x, y])
                    {
                        canMove = true;
                    }
                }
            }

            if (canMove == false)
            {
                int linesKilled = 0;
                for (int y = 0; y < GridHeight; y++)
                {
                    bool fullLine = true;
                    for (int x = 0; x < GridWidth; x++)
                    {
                        if (mGrid[x, y] == EBlockTypes.Empty)
                        {
                            fullLine = false;
                            break;
                        }
                    }

                    if (fullLine)
                    {
                        for (int yDown = y - 1; yDown > 0; yDown--)
                        {
                            for (int x = 0; x < GridWidth; x++)
                            {
                                mGrid[x, yDown + 1] = mGrid[x, yDown];
                            }
                        }

                        for (int x = 0; x < GridWidth; x++)
                        {
                            mGrid[0, x] = EBlockTypes.Empty;
                        }

                        TotalScore += 10;
                        CrushedLines++;
                        linesKilled++;
                        Sound.Play(ESoundTypes.LineKill);
                    }
                }

                if (linesKilled >= 2)
                {
                    TotalScore += 5;
                }
                if (linesKilled >= 3)
                {
                    TotalScore += 10;
                }
                if (linesKilled >= 4)
                {
                    TotalScore += 25;
                }

                AddRandomBlock();
            }
        }
예제 #4
0
        public void RotateBlock()
        {
            // Clear old pos
            for (int x = 0; x < GridWidth; x++)
            {
                for (int y = 0; y < GridHeight; y++)
                {
                    if (mFloatingGrid[x, y])
                    {
                        mGrid[x, y] = EBlockTypes.Empty;
                    }
                }
            }

            // Rotate and check if new position is valid
            bool anythingBlocking = false;

            Point[] newPos    = new Point[4];
            int     newPosNum = 0;

            int newRotation = (mCurrentBlockRot + 1) % 4;

            int[,] shape = mBlockTypeShapes[mCurrentBlockType, newRotation];
            for (int x = 0; x < shape.GetLength(0); x++)
            {
                for (int y = 0; y < shape.GetLength(1); y++)
                {
                    if (shape[x, y] > 0)
                    {
                        if (mCurrentBlockPos.X + x >= GridWidth ||
                            mCurrentBlockPos.Y + y >= GridHeight ||
                            mCurrentBlockPos.X + x < 0 ||
                            mCurrentBlockPos.Y + y < 0 ||
                            mGrid[mCurrentBlockPos.X + x, mCurrentBlockPos.Y + y] != EBlockTypes.Empty)
                        {
                            anythingBlocking = true;
                        }
                        else if (newPosNum < 4)
                        {
                            newPos[newPosNum] = new Point(mCurrentBlockPos.X + x, mCurrentBlockPos.Y + y);
                            newPosNum++;
                        }
                    }
                }
            }

            // If anything is blocking restore old state
            // Or we didn't get all 4 new positions?
            if (anythingBlocking || newPosNum != 4)
            {
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        if (mFloatingGrid[x, y])
                        {
                            mGrid[x, y] = (EBlockTypes)mCurrentBlockType;
                        }
                    }
                }
            }
            else
            {
                // Else we can rotate, lets do it!
                mCurrentBlockRot = newRotation;
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        mFloatingGrid[x, y] = false;
                    }
                }

                for (int i = 0; i < 4; i++)
                {
                    mGrid[newPos[i].X, newPos[i].Y]         = (EBlockTypes)mCurrentBlockType;
                    mFloatingGrid[newPos[i].X, newPos[i].Y] = true;
                }

                Sound.Play(ESoundTypes.BlockRotate);
            }
        }
예제 #5
0
        /// <summary>
        /// Move current floating block to left, right or down.
        /// If anything is blocking, moving is not possible and
        /// nothing gets changed!
        /// </summary>
        /// <returns>Returns true if moving was successful, otherwise false</returns>
        public bool MoveBlock(EMoveTypes moveType)
        {
            // Clear old pos
            for (int x = 0; x < GridWidth; x++)
            {
                for (int y = 0; y < GridHeight; y++)
                {
                    if (mFloatingGrid[x, y])
                    {
                        mGrid[x, y] = EBlockTypes.Empty;
                    }
                }
            }

            // Move stuff to new position
            bool anythingBlocking = false;

            Point[] newPos    = new Point[4];
            int     newPosNum = 0;

            if (moveType == EMoveTypes.Left)
            {
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        if (mFloatingGrid[x, y])
                        {
                            if (x - 1 < 0 || mGrid[x - 1, y] != EBlockTypes.Empty)
                            {
                                anythingBlocking = true;
                            }
                            else if (newPosNum < 4)
                            {
                                newPos[newPosNum] = new Point(x - 1, y);
                                newPosNum++;
                            }
                        }
                    }
                }
            }
            else if (moveType == EMoveTypes.Right)
            {
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        if (mFloatingGrid[x, y])
                        {
                            if (x + 1 >= GridWidth || mGrid[x + 1, y] != EBlockTypes.Empty)
                            {
                                anythingBlocking = true;
                            }
                            else if (newPosNum < 4)
                            {
                                newPos[newPosNum] = new Point(x + 1, y);
                                newPosNum++;
                            }
                        }
                    }
                }
            }
            else if (moveType == EMoveTypes.Down)
            {
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        if (mFloatingGrid[x, y])
                        {
                            if (y + 1 >= GridHeight || mGrid[x, y + 1] != EBlockTypes.Empty)
                            {
                                anythingBlocking = true;
                            }
                            else if (newPosNum < 4)
                            {
                                newPos[newPosNum] = new Point(x, y + 1);
                                newPosNum++;
                            }
                        }
                    }
                }
                if (anythingBlocking == true)
                {
                    MovingDownWasBlocked = true;
                }
            }

            // If anything is blocking restore old state
            // Or we didn't get all 4 new positions?
            if (anythingBlocking || newPosNum != 4)
            {
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        if (mFloatingGrid[x, y])
                        {
                            mGrid[x, y] = (EBlockTypes)mCurrentBlockType;
                        }
                    }
                }
                return(false);
            }
            else
            {
                if (moveType == EMoveTypes.Left)
                {
                    mCurrentBlockPos = new Point(mCurrentBlockPos.X - 1, mCurrentBlockPos.Y);
                }
                else if (moveType == EMoveTypes.Right)
                {
                    mCurrentBlockPos = new Point(mCurrentBlockPos.X + 1, mCurrentBlockPos.Y);
                }
                else if (moveType == EMoveTypes.Down)
                {
                    mCurrentBlockPos = new Point(mCurrentBlockPos.X, mCurrentBlockPos.Y + 1);
                }

                // Else we can move to the new position, lets do it!
                for (int x = 0; x < GridWidth; x++)
                {
                    for (int y = 0; y < GridHeight; y++)
                    {
                        mFloatingGrid[x, y] = false;
                    }
                }
                for (int i = 0; i < 4; i++)
                {
                    mGrid[newPos[i].X, newPos[i].Y]         = (EBlockTypes)mCurrentBlockType;
                    mFloatingGrid[newPos[i].X, newPos[i].Y] = true;
                }

                Sound.Play(ESoundTypes.BlockMove);

                return(true);
            }
        }
예제 #6
0
        protected override void Update(GameTime gameTime)
        {
            if (Paused == true)
            {
                if (Input.KeyboardKeyJustPressed(Keys.P) == false)
                {
                    base.Update(gameTime);
                    return;
                }
                Paused = false;
            }
            else if (Input.KeyboardKeyJustPressed(Keys.P) == true)
            {
                Paused = true;
                base.Update(gameTime);
                return;
            }

            int oldGameMs = mElapsedGameMs;
            int frameMs   = (int)gameTime.ElapsedGameTime.TotalMilliseconds;

            mElapsedGameMs += frameMs;

            // Game tick time, 1000 for difficutly=0, 100 for difficutly=9
            int gameTickTime = 1000 / (mLevel + 1);

            if (mElapsedGameMs / gameTickTime != oldGameMs / gameTickTime || mTetrisGrid.MovingDownWasBlocked == true)
            {
                mTetrisGrid.Update();
            }

            // Official way to raise level - after 10 crushed lines
            if ((mTetrisGrid.CrushedLines / 10) > mLevel)
            {
                mLevel++;
                Sound.Play(ESoundTypes.Victory);
            }

            // We sum up the elapsed time after a button/key was pressed.
            // If some time has been reached, the action will be executed.
            // If we just execute it after the button/key was pressed,
            // the block would move extrem fast.
            // Current speed of 75ms is kind enough.
            if (Input.KeyboardLeftPressed || Input.GamePadLeftPressed)
            {
                mPressedLeftMs += frameMs;
            }
            else
            {
                mPressedLeftMs = 0;
            }
            if (Input.KeyboardRightPressed || Input.GamePadRightPressed)
            {
                mPressedRightMs += frameMs;
            }
            else
            {
                mPressedRightMs = 0;
            }
            if (Input.KeyboardDownPressed || Input.GamePadDownPressed || Input.Keyboard.IsKeyDown(Keys.Space) || Input.GamePadAPressed)
            {
                mPressedDownMs += frameMs;
            }
            else
            {
                mPressedDownMs = 0;
            }

            if (Input.KeyboardLeftJustPressed || Input.GamePadLeftJustPressed || mPressedLeftMs > 200)
            {
                if (mPressedLeftMs > 75)
                {
                    mPressedLeftMs -= 75;
                }
                mTetrisGrid.MoveBlock(EMoveTypes.Left);
            }
            else if (Input.KeyboardRightJustPressed || Input.GamePadRightJustPressed || mPressedRightMs > 200)
            {
                if (mPressedRightMs > 75)
                {
                    mPressedRightMs -= 75;
                }
                mTetrisGrid.MoveBlock(EMoveTypes.Right);
            }
            else if (Input.KeyboardDownJustPressed || Input.GamePadDownJustPressed || Input.KeyboardSpaceJustPressed || Input.GamePadAJustPressed || mPressedDownMs > 150)
            {
                if (mPressedDownMs > 50)
                {
                    mPressedDownMs -= 50;
                }
                mTetrisGrid.MoveBlock(EMoveTypes.Down);
            }
            else if (Input.KeyboardUpJustPressed || Input.GamePadUpJustPressed)
            {
                mTetrisGrid.RotateBlock();
            }

            if (mTetrisGrid.TotalScore != mHighscore)
            {
                mHighscore = mTetrisGrid.TotalScore;
            }

            // Restart using Enter
            if (mTetrisGrid.GameOver && (Input.KeyboardSpaceJustPressed || Input.GamePadAJustPressed || Input.KeyboardEnterJustPressed))
            {
                mTetrisGrid.GameOver     = false;
                mTetrisGrid.TotalScore   = 0;
                mTetrisGrid.CrushedLines = 0;
                mLevel = 0;
                mTetrisGrid.Restart();
            }

            base.Update(gameTime);
        }
예제 #7
0
        public void TryRotate(Tetrimino piece, bool clockwise)
        {
            // Copy Active Piece And Simulate Rotation
            Tetrimino copy = GeneratePiece(piece.GetBlockValue());

            piece.MakeCopy(copy);
            copy.Rotate(clockwise);

            // If Everything Looks Good, Rotate Active Piece
            if (copy.IsInBounds(_tower))
            {
                piece.Rotate(clockwise);
            }
            // If It Doesn't, Try To Apply An Offset To The Rotation
            else
            {
                int rotationOffsetValue = -1;

                while (!copy.IsInBounds(_tower))
                {
                    rotationOffsetValue++;

                    switch (rotationOffsetValue)
                    {
                    case 0:
                        // 1 Space Left
                        copy.MoveLeftRight(-1);
                        break;

                    case 1:
                        // 2 Spaces Left
                        copy.MoveLeftRight(-1);
                        break;

                    case 2:
                        // 1 Space Right
                        copy.MoveLeftRight(3);
                        break;

                    case 3:
                        // 2 Spaces Right
                        copy.MoveLeftRight(1);
                        break;

                    case 4:
                        // 1 Space Down
                        copy.MoveLeftRight(-2);
                        copy.MoveUpDown(1);
                        break;

                    case 5:
                        // 2 Spaces Down
                        copy.MoveUpDown(1);
                        break;

                    default:
                        return;
                    }
                }

                // Rotate And Apply Offset
                piece.Rotate(clockwise);
                switch (rotationOffsetValue)
                {
                case 0:
                    piece.MoveLeftRight(-1);
                    break;

                case 1:
                    piece.MoveLeftRight(-2);
                    break;

                case 2:
                    piece.MoveLeftRight(1);
                    break;

                case 3:
                    piece.MoveLeftRight(2);
                    break;

                case 4:
                    piece.MoveUpDown(1);
                    break;

                case 5:
                    piece.MoveUpDown(2);
                    break;
                }
            }

            _rotateSound.Play();
        }