/// <summary>Make a new tetris block.</summary> /// <param name="blockSprites">The sprite string containing the block sprites.</param> /// <param name="field">The field that the block is in.</param> /// <param name="isColor">Are colors enabled?</param> /// <param name="blockType">The shape of the block</param> public static TetrisBlock createBlock(Texture2D blockSprites, PlayingField field, bool isColor = false, sbyte blockKind = -1) { TetrisBlock block; if (blockKind == -1) { blockKind = (sbyte)rand.Next(8); } switch (blockKind) { case 0: // square block = new blockSquare(blockSprites, field, isColor); break; case 1: // horizontal line block = new blockLineH(blockSprites, field, isColor); break; case 2: // Z shape block = new blockZ(blockSprites, field, isColor); break; case 3: // reverse Z shape block = new blockReverseZ(blockSprites, field, isColor); break; case 4: // L shape block = new blockFlatL(blockSprites, field, isColor); break; case 5: // reverse L shape block = new blockFlatReverseL(blockSprites, field, isColor); break; case 6: // vertical line block = new blockLineV(blockSprites, field, isColor); break; case 7: // T shape block = new blockRoof(blockSprites, field, isColor); break; default: // square block = new blockSquare(blockSprites, field, isColor); break; } return block; }
/// <summary>Updates the game.</summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // base updates gameState = reserveGameState; input.Update(gameTime); switch (gameState) { case GameStates.Menu: // menu buttons foreach(Button button in menuButtons) { if (button.isClicked(input)) { switch (button.Action) { case MenuActions.Mono: // start monochrome mode reserveGameState = GameStates.Playing; isColor = false; break; case MenuActions.Color: // start color mode reserveGameState = GameStates.Playing; isColor = true; break; case MenuActions.Info: // open info screen reserveGameState = GameStates.Info; break; case MenuActions.Quit: // quir the game Exit(); break; } } } if (reserveGameState == GameStates.Playing) { // set up for playing the selected mode // create the field field = new PlayingField(fieldWidth, fieldHeight, blockSprites, isColor); // create the blocks tetrisBlockCurrent = TetrisBlock.createBlock(blockSprites, field, isColor); tetrisBlockNext = TetrisBlock.createBlock(blockSprites, field, isColor); tetrisBlockCurrent.placeBlock(); tetrisBlockCurrent.setMoveTimer(moveTimerLim); // score viewer scoreViewerCurrent = isColor ? scoreViewerColor : scoreViewerMono; numbersCurrent = isColor ? numbersColor : numbersMono; scoreSplicer(); speedLvlSplicer(); } break; case GameStates.Info: // button for going back to the menu if (backButton.isClicked(input)) { reserveGameState = GameStates.Menu; } break; case GameStates.Playing: // make new blocks if (tetrisBlockCurrent == null) { if (newBlockTimer >= newBlockTimerLim) { tetrisBlockCurrent = tetrisBlockNext; tetrisBlockNext = TetrisBlock.createBlock(blockSprites, field, isColor); if (!tetrisBlockCurrent.placeBlock()) { // could not place the block // GAME OVER reserveGameState = GameStates.GameOver; break; } tetrisBlockCurrent.setMoveTimer(moveTimerLim); } else { newBlockTimer += gameTime.ElapsedGameTime.Milliseconds; } } if (tetrisBlockCurrent != null) { // make the tetris block handle it's user inputs and movement couldGoDown = tetrisBlockCurrent.handleMovement(gameTime, input); if (!couldGoDown) { // reached bottom or hit existing block blockHitSound.Play(); field.placeBlock(tetrisBlockCurrent); scorePoints(field.checkClearedRows(tetrisBlockCurrent.OffsetY)); if (field.reachedTop()) { // the top of the field could not be cleared // GAME OVER reserveGameState = GameStates.GameOver; gameOverString1 = "You made it to speed level " + (Math.Min(finishedRows, (moveTimerLimBase - moveTimerLimMin) / 2)).ToString(); gameOverString2 = "and earned " + score.ToString() + " points!"; } resetBlock(); } } break; case GameStates.GameOver: // TODO: GAME OVER text and score view // buttons if (menuButton.isClicked(input)) { // back to menu reserveGameState = GameStates.Menu; // reset for next playthrough score = 0; finishedRows = 0; moveTimerLim = moveTimerLimBase; } if (menuButtons[3].isClicked(input)) { Exit(); } // quit game break; } // you can always exit the game if (input.KeyPressed(Keys.Escape)) { Exit(); } base.Update(gameTime); }
/// <summary>Make a new tetris block. (first 16 parameters are the internal positions)</summary> /// <param name="blockSprites">The sprite string containing the block sprites.</param> /// <param name="field">The field that the block is in.</param> /// <param name="isColor">Are colors enabled?</param> /// <param name="blockType">The shape of the block</param> public TetrisBlock(bool x1y1, bool x2y1, bool x3y1, bool x4y1, bool x1y2, bool x2y2, bool x3y2, bool x4y2, bool x1y3, bool x2y3, bool x3y3, bool x4y3, bool x1y4, bool x2y4, bool x3y4, bool x4y4, Texture2D blockSprites, PlayingField field, BlockType blockType, bool isColor) : base(4, 4, blockSprites, isColor) { this.field = field; this.blockType = blockType; isNext = true; fillStruct(x1y1, x2y1, x3y1, x4y1, x1y2, x2y2, x3y2, x4y2, x1y3, x2y3, x3y3, x4y3, x1y4, x2y4, x3y4, x4y4); if (isColor) { color = (byte)rand.Next(1, 7); colorBlock(); } }
/// <summary>Make an L shaped block.</summary> public blockFlatL(Texture2D blockSprites, PlayingField field, bool isColor) : base(false, false, true, false, true, true, true, false, false, false, false, false, false, false, false, false, blockSprites, field, BlockType.FlatL, isColor) { }
/// <summary>Make a reversed Z shape block.</summary> public blockReverseZ(Texture2D blockSprites, PlayingField field, bool isColor) : base(false, true, true, false, true, true, false, false, false, false, false, false, false, false, false, false, blockSprites, field, BlockType.ReverseZ, isColor) { }