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(); }
/// <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++; }
/// <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(); } }
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); } }
/// <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); } }
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); }
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(); }