protected override void Update(GameTime gameTime) { MouseState mouseState = Mouse.GetState(); KeyboardState keyboardState = Keyboard.GetState(); if (ButtonIntersects(ref mouseState, buttonStart) || ButtonIntersects(ref mouseState, buttonExit) || ButtonIntersects(ref mouseState, buttonResume) || ButtonIntersects(ref mouseState, buttonRestart)) { buttonOutline.Enable(spriteBatch); } else { buttonOutline.Disable(spriteBatch); } if (buttonStart.BoundingBox.Contains(mouseState.Position)) { buttonOutline.Position.Y = 360 * 3 / 2; } if (buttonExit.BoundingBox.Contains(mouseState.Position)) { buttonOutline.Position.Y = 440 * 3 / 2; } if (buttonResume.BoundingBox.Contains(mouseState.Position)) { buttonOutline.Position.Y = 360 * 3 / 2; } if (buttonRestart.BoundingBox.Contains(mouseState.Position)) { buttonOutline.Position.Y = 520 * 3 / 2; } switch (GameState) { case STATE_MENU: PlayMusic(0); buttonResume.Disable(spriteBatch); buttonRestart.Disable(spriteBatch); if (Clicked(ref mouseState, buttonStart)) { GameState = STATE_PLAYING; startTime = gameTime.TotalGameTime.TotalSeconds; } if (Clicked(ref mouseState, buttonExit)) { Exit(); } break; case STATE_PLAYING: PlayMusic(1); buttonStart.Disable(spriteBatch); buttonExit.Disable(spriteBatch); buttonResume.Disable(spriteBatch); buttonRestart.Disable(spriteBatch); if (keyboardState.IsKeyDown(Keys.P)) { GameState = STATE_PAUSED; endTime = gameTime.TotalGameTime.TotalSeconds; timeInterval = endTime - startTime; totalTime += timeInterval; } break; case STATE_PAUSED: buttonResume.Enable(spriteBatch); buttonExit.Enable(spriteBatch); buttonRestart.Enable(spriteBatch); if (Clicked(ref mouseState, buttonRestart)) { GameState = STATE_PLAYING; Restart = true; totalTime = 0; startTime = gameTime.TotalGameTime.TotalSeconds; timeCount = false; } if (Clicked(ref mouseState, buttonResume)) { GameState = STATE_PLAYING; startTime = gameTime.TotalGameTime.TotalSeconds; } if (Clicked(ref mouseState, buttonExit)) { Exit(); } break; case STATE_GAMEOVER: buttonRestart.Enable(spriteBatch); buttonExit.Enable(spriteBatch); if (timeCount == false) { endTime = gameTime.TotalGameTime.TotalSeconds; timeInterval = endTime - startTime; totalTime += timeInterval; timeCount = true; } if (Clicked(ref mouseState, buttonRestart)) { GameState = STATE_PLAYING; Restart = true; totalTime = 0; startTime = gameTime.TotalGameTime.TotalSeconds; timeCount = false; } if (Clicked(ref mouseState, buttonExit)) { Exit(); } break; case STATE_GAMEWON: buttonRestart.Enable(spriteBatch); buttonExit.Enable(spriteBatch); if (timeCount == false) { endTime = gameTime.TotalGameTime.TotalSeconds; timeInterval = endTime - startTime; totalTime += timeInterval; timeCount = true; } if (Clicked(ref mouseState, buttonRestart)) { GameState = STATE_PLAYING; Restart = true; totalTime = 0; startTime = gameTime.TotalGameTime.TotalSeconds; timeCount = false; } if (Clicked(ref mouseState, buttonExit)) { Exit(); } break; default: break; } if (GameState == STATE_PLAYING) { if (Restart == true) { player.position = position1; player.velocity = Vector2.Zero; endHeight = 0; Lines = 0; gameBoard.Reset(); currentTetromino?.MoveTo(currentTetromino.Xghost, currentTetromino.Yghost); nextBlockBoards[0].Reset(); nextBlockBoards[1].Reset(); nextTetrominos = new Queue <char>(); for (int k = 0; k < 2; k++) { nextTetrominos.Enqueue(GetRandomCharacter(CHARLIST, new Random())); } hasJumped = false; outOfStart = false; Restart = false; lastActionTime = 0; lastGravityEffectTime = 0; lastSkipTime = 0; skip = 0; dieTime = 0; winTime = 0; dieCount = false; winCount = false; player.sprite.PlayAnimation(idleAnimation); } // Tetromino generation if ((currentTetromino == null || !currentTetromino.IsFalling) && outOfStart == true) { currentTetromino = GenerateNewTetromino(nextTetrominos.Dequeue()); nextTetrominos.Enqueue(GetRandomCharacter(CHARLIST, randomGenerator)); // Reset the nextBlockBoards for (int k = 0; k < 2; k++) { nextBlockBoards[k].Reset(); // add a tetromino in the board new Tetromino(nextBlockBoards[k], 2, 1, nextTetrominos.ElementAt(k), BlockTextures[nextTetrominos.ElementAt(k)]); } } // Apply gravity if (gameTime.TotalGameTime.TotalMilliseconds - lastGravityEffectTime > 1000 / FallSpeed && player.sprite.Animation != dieAnimation) { currentTetromino?.MoveTo(currentTetromino.X, currentTetromino.Y - 1); lastGravityEffectTime = gameTime.TotalGameTime.TotalMilliseconds; } // Check for last action / update bool actionIsAllowed = false; if (gameTime.TotalGameTime.TotalMilliseconds - lastActionTime > ActionDelay) { actionIsAllowed = true; } if (actionIsAllowed) { // ----------------------------------------- // Movement // ----------------------------------------- if (Keyboard.GetState().IsKeyDown(Keys.Left)) { currentTetromino?.MoveTo(currentTetromino.X - 1, currentTetromino.Y); lastActionTime = gameTime.TotalGameTime.TotalMilliseconds; } if (Keyboard.GetState().IsKeyDown(Keys.Right)) { currentTetromino?.MoveTo(currentTetromino.X + 1, currentTetromino.Y); lastActionTime = gameTime.TotalGameTime.TotalMilliseconds; } if (Keyboard.GetState().IsKeyDown(Keys.Down)) { currentTetromino?.MoveTo(currentTetromino.X, currentTetromino.Y - 1); lastActionTime = gameTime.TotalGameTime.TotalMilliseconds; } // ----------------------------------------- // Rotation // ----------------------------------------- if (Keyboard.GetState().IsKeyDown(Keys.Up)) { currentTetromino?.Rotate(1); // clock wise rotation lastActionTime = gameTime.TotalGameTime.TotalMilliseconds; } } currentTetromino?.Update(gameTime); // Row check if (currentTetromino != null && !currentTetromino.IsFalling) { // If the tetromino is outside if (currentTetromino.Y >= 18) { GameState = STATE_GAMEOVER; } // Get the row to remove int rowCleared = gameBoard.ClearRow(lineCompleted); if (rowCleared > 0) { // Update Lines Lines += rowCleared; // decrease end goal endHeight += 64 * 3 / 2 * rowCleared; skip--; if (skip <= 0) { skip = 0; } if (endHeight >= (640 - 160) * 3 / 2) { endHeight = (640 - 160) * 3 / 2; } } } if (Keyboard.GetState().IsKeyDown(Keys.Space)) { if (gameTime.TotalGameTime.TotalMilliseconds - lastSkipTime > ActionDelay && skip < 3) { nextTetrominos.Dequeue(); nextTetrominos.Enqueue(GetRandomCharacter(CHARLIST, randomGenerator)); for (int k = 0; k < 2; k++) { nextBlockBoards[k].Reset(); // add a tetromino in the board new Tetromino(nextBlockBoards[k], 2, 1, nextTetrominos.ElementAt(k), BlockTextures[nextTetrominos.ElementAt(k)]); } skip++; lastSkipTime = gameTime.TotalGameTime.TotalMilliseconds; } } // player movement if (Keyboard.GetState().IsKeyDown(Keys.D) && player.sprite.Animation != dieAnimation && player.sprite.Animation != winAnimation) { temptVelocity.X = speed; nextPosition = new Vector2(player.position.X + temptVelocity.X, player.position.Y); if (player.IsColliding(nextPosition, gameBoard) == false) { player.velocity.X = temptVelocity.X; } else if (player.IsColliding(nextPosition, gameBoard) == true) { player.position.X = (320 + gameBoard.Blocks[player.collideBlock].X * 32 - 32) * 3 / 2; player.velocity.X = 0; } player.sprite.PlayAnimation(runAnimation); } else if (Keyboard.GetState().IsKeyDown(Keys.A) && player.sprite.Animation != dieAnimation && player.sprite.Animation != winAnimation) { temptVelocity.X = -speed; nextPosition = new Vector2(player.position.X + temptVelocity.X, player.position.Y); // Console.WriteLine(player.IsColliding(nextPosition, gameBoard)); if (player.IsColliding(nextPosition, gameBoard) == false) { player.velocity.X = temptVelocity.X; } else if (player.IsColliding(nextPosition, gameBoard) == true) { player.position.X = (320 + gameBoard.Blocks[player.collideBlock].X * 32 + 32) * 3 / 2; player.velocity.X = 0; } player.sprite.PlayAnimation(runAnimation); } else { player.velocity.X = 0; if (player.sprite.Animation != dieAnimation && player.sprite.Animation != winAnimation && player.sprite.Animation != jumpAnimation) { player.sprite.PlayAnimation(idleAnimation); } } player.position.X += player.velocity.X; if (player.position.X >= 320 * 3 / 2) { outOfStart = true; } // SoundEffectInstance Defeat = playerDefeat.CreateInstance(); // Defeat.IsLooped = false; if (Keyboard.GetState().IsKeyDown(Keys.W) && player.sprite.Animation != dieAnimation && player.sprite.Animation != winAnimation) { nextPosition = new Vector2(player.position.X, player.position.Y - jumpStrength); // Console.WriteLine("{0},{1},{2}",player.IsColliding(nextPosition, gameBoard), hasJumped, nextPosition); if (player.IsColliding(nextPosition, gameBoard) == false && hasJumped == false) { if (nextPosition.Y <= 0) { player.position.Y = 0; player.velocity.Y = -8f; hasJumped = true; } else { player.position.Y -= jumpStrength; player.velocity.Y = -8f; hasJumped = true; } playerJump.Play(); player.sprite.PlayAnimation(jumpAnimation); } else if (player.IsColliding(nextPosition, gameBoard) == true && hasJumped == false) { playerJump.Play(); player.sprite.PlayAnimation(jumpAnimation); player.position.Y = (20 - gameBoard.Blocks[player.collideBlock].Y) * 32 * 3 / 2; player.velocity.Y = 0; hasJumped = true; if (belongToCurrent(gameBoard.Blocks[player.collideBlock]) && currentTetromino.CanMoveTo(currentTetromino.X, currentTetromino.Y - 1) == true) { // gamePlayMusic.Stop(); // Defeat.Play(); playerDefeat.Play(); player.sprite.PlayAnimation(dieAnimation); if (dieCount == false) { dieTime = gameTime.TotalGameTime.TotalMilliseconds; dieCount = true; } } } } temptVelocity.Y = player.velocity.Y + gravity; nextPosition = new Vector2(player.position.X, player.position.Y + temptVelocity.Y); // Console.WriteLine(nextPosition); if (player.IsColliding(nextPosition, gameBoard) == false) { player.velocity.Y = temptVelocity.Y; } else if (player.IsColliding(nextPosition, gameBoard) == true && player.velocity.Y < 0) { player.position.Y = (20 - gameBoard.Blocks[player.collideBlock].Y) * 32 * 3 / 2; player.velocity.Y = 0; } else if (player.IsColliding(nextPosition, gameBoard) == true && player.velocity.Y >= 0) { hasJumped = false; if (player.velocity.Y > 0) { player.position.Y = (20 - gameBoard.Blocks[player.collideBlock].Y - 2) * 32 * 3 / 2; player.velocity.Y = 0; if (player.sprite.Animation == jumpAnimation) { player.sprite.PlayAnimation(idleAnimation); } } } if (player.position.Y < endHeight) { if (player.position.X >= (1120 - 320 - 32) * 3 / 2) { player.position.X = (1120 - 320 - 32) * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 320 * 3 / 2) { player.position.X = 320 * 3 / 2; player.velocity.X = 0; } } if (endHeight + 160 * 3 / 2 <= (640 - 160) * 3 / 2) { if (player.position.Y + 32 * 3 / 2 > endHeight + 160 * 3 / 2 && player.position.Y < (640 - 160) * 3 / 2) { if (player.position.X >= (1120 - 320 - 32) * 3 / 2) { player.position.X = (1120 - 320 - 32) * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 320 * 3 / 2) { player.position.X = 320 * 3 / 2; player.velocity.X = 0; } } else if (player.position.Y >= (640 - 160) * 3 / 2) { if (player.position.X >= (1120 - 320 - 32) * 3 / 2) { player.position.X = (1120 - 320 - 32) * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 160 * 3 / 2 && outOfStart == false) { player.position.X = 160 * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 320 * 3 / 2 && outOfStart == true) { player.position.X = 320 * 3 / 2; player.velocity.X = 0; } } } else if (endHeight + 160 * 3 / 2 > (640 - 160) * 3 / 2) { if (player.position.Y < (640 - 160) * 3 / 2 && player.position.Y >= endHeight) { if (player.position.X >= (1120 - 160 - 32) * 3 / 2) { player.position.X = (1120 - 160 - 32) * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 320 * 3 / 2) { player.position.X = 320 * 3 / 2; player.velocity.X = 0; } } else if (player.position.Y >= (640 - 160) * 3 / 2 && player.position.Y + 32 * 3 / 2 <= endHeight + 160 * 3 / 2) { if (player.position.X >= (1120 - 160 - 32) * 3 / 2) { player.position.X = (1120 - 160 - 32) * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 160 * 3 / 2 && outOfStart == false) { player.position.X = 160 * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 320 * 3 / 2 && outOfStart == true) { player.position.X = 320 * 3 / 2; player.velocity.X = 0; } } else if (player.position.Y + 32 * 3 / 2 > endHeight + 160 * 3 / 2) { if (player.position.X >= (1120 - 320 - 32) * 3 / 2) { player.position.X = (1120 - 320 - 32) * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 160 * 3 / 2 && outOfStart == false) { player.position.X = 160 * 3 / 2; player.velocity.X = 0; } else if (player.position.X <= 320 * 3 / 2 && outOfStart == true) { player.position.X = 320 * 3 / 2; player.velocity.X = 0; } } } if (player.position.Y + player.velocity.Y >= (640 - 32) * 3 / 2) { hasJumped = false; player.position.Y = (640 - 32) * 3 / 2; player.velocity.Y = 0; if (player.sprite.Animation == jumpAnimation) { player.sprite.PlayAnimation(idleAnimation); } } if (player.position.X + 32 * 3 / 2 > (320 + 480) * 3 / 2 && player.position.Y + player.velocity.Y >= endHeight + (160 - 32) * 3 / 2) { hasJumped = false; player.position.Y = endHeight + (160 - 32) * 3 / 2; player.velocity.Y = 0; } player.position.Y += player.velocity.Y; if (player.TopColliding(player.position.X, player.position.Y, gameBoard) == true) { if (belongToCurrent(gameBoard.Blocks[player.collideIndex]) && currentTetromino.CanMoveTo(currentTetromino.X, currentTetromino.Y - 1) == true) { playerDefeat.Play(); player.sprite.PlayAnimation(dieAnimation); if (dieCount == false) { dieTime = gameTime.TotalGameTime.TotalMilliseconds; dieCount = true; } } } if (player.IsColliding(player.position, gameBoard) == true) { playerDefeat.Play(); player.sprite.PlayAnimation(dieAnimation); if (dieCount == false) { dieTime = gameTime.TotalGameTime.TotalMilliseconds; dieCount = true; } } if (player.position.X >= (320 + 480) * 3 / 2 && player.position.X <= (320 + 480 + 160 - 32) * 3 / 2 && player.position.Y >= endHeight && player.position.Y <= endHeight + (160 - 32) * 3 / 2) { // player.velocity.X = 0; player.sprite.PlayAnimation(winAnimation); if (winCount == false) { playerVictory.Play(); winTime = gameTime.TotalGameTime.TotalMilliseconds; player.sprite.PlayAnimation(winAnimation); winCount = true; } } if (player.sprite.Animation == dieAnimation && gameTime.TotalGameTime.TotalMilliseconds - dieTime > 500) { GameState = STATE_GAMEOVER; } if (player.sprite.Animation == winAnimation && gameTime.TotalGameTime.TotalMilliseconds - winTime > 500) { GameState = STATE_GAMEWON; } } if (GameState == STATE_PAUSED) { player.velocity = Vector2.Zero; } base.Update(gameTime); }