/Samples/Breakout/BreakoutGame.cs
C# | 248 lines | 146 code | 32 blank | 70 comment | 12 complexity | 6991bc6e2c26cac271aef0a4e943b041 MD5 | raw file
Possible License(s): Apache-2.0
- using System;
- using System.Collections.Generic;
- using Delta.Engine.Dynamic;
- using Delta.Utilities.Datatypes;
- using Delta.Rendering.Basics.Fonts;
- using Delta.InputSystem;
- using Delta.Engine;
- using Delta.Rendering.Basics.Materials;
- using Delta.Multimedia;
- using Delta.Utilities.Helpers;
-
- namespace Breakout
- {
- /// <summary>
- /// Breakout game
- /// </summary>
- public class BreakoutGame : DynamicModule
- {
- //TODO: known bug: the collision particle effect is blinking around, there is an issue with the effect system we have to fix soon!
- //TODO: better and more effects (explosions? ball collision)
- //TODO: add better trail and when adding trail, we still have to fix geometry and material rendering issues
-
- #region Constants
- /// <summary>
- /// Name of the command for 'Yes/No' decision of restart the game.
- /// </summary>
- private const string CommandYesNoClick = "YesNoClick";
- /// <summary>
- /// Name of the command for quitting the game.
- /// </summary>
- private const string CommandQuitGame = "Quit";
- #endregion
-
- #region Private
- /// <summary>
- /// The background of the game.
- /// </summary>
- private Material2D background;
-
- /// <summary>
- /// Block material
- /// </summary>
- private Material2DColored block;
-
- /// <summary>
- /// Material to visualize the player paddle.
- /// </summary>
- private Material2D paddle;
-
- /// <summary>
- /// Material to visualize the ball in the game.
- /// </summary>
- private Material2DColored ball;
-
- /// <summary>
- /// The collision sound between the ball and a player paddle.
- /// </summary>
- private Sound sound;
-
- private List<Point> lastBallPositions;
- private Board board;
- private int oldScore;
-
- private Rectangle scoreTextArea;
- private Rectangle gameOverTextArea;
- private Rectangle tryAgainTextArea;
- private Rectangle yesTextArea;
- private Rectangle noTextArea;
- #endregion
-
- #region Constructor
- /// <summary>
- /// Create breakout game
- /// </summary>
- public BreakoutGame()
- : base(typeof(BreakoutGame).Name, typeof(IGraphic))
- {
- // Load all needed content
- background = new Material2D("SpaceBackground");
- block = new Material2DColored("BreakoutBlock");
-
- paddle = new Material2D("Paddle");
- ball = new Material2DColored("Ball");
- sound = new Sound("DefaultSound");
- //disabled: music = new Music("DefaultMusic");
-
- lastBallPositions = new List<Point>();
- board = new Board();
- Settings.Extra.LimitFramerateNumber = 60;
- oldScore = MathHelper.InvalidIndex;
-
- scoreTextArea = Rectangle.FromCenter(0.5f, 0.6f, 0.25f, 0.05f);
- gameOverTextArea = Rectangle.FromCenter(0.5f, 0.25f, 0.15f, 0.05f);
- tryAgainTextArea = Rectangle.FromCenter(0.5f, 0.4f, 0.15f, 0.05f);
- yesTextArea = Rectangle.FromCenter(0.25f, 0.75f, 0.1f, 0.05f);
- noTextArea = Rectangle.FromCenter(0.75f, 0.75f, 0.1f, 0.05f);
-
- RegisterInputCommands();
- }
- #endregion
-
- #region RegisterInputCommands
- /// <summary>
- /// Register input commands
- /// </summary>
- private void RegisterInputCommands()
- {
- // Restart game
- Input.Commands[CommandYesNoClick].Add(this,
- delegate(CommandTrigger trigger)
- {
- // Check if the player wants to replay
- if (yesTextArea.Contains(trigger.Position))
- {
- sound.Play();
- board.StartGame();
- board.GameOver = false;
- }
-
- // or just quit the game now
- if (noTextArea.Contains(trigger.Position))
- {
- sound.Play();
- Application.Quit();
- }
- });
-
- // Quit game
- Input.Commands[CommandQuitGame].Add(this, delegate
- {
- Application.Quit();
- });
- }
- #endregion
-
- #region Run (override)
- /// <summary>
- /// Run
- /// </summary>
- public override void Run()
- {
- // Render background (resolution independent)
- background.Draw(Rectangle.One);
-
- Font textFont = Font.Default;
-
- if (board.GameOver)
- {
- #region Game over menu
- textFont.Draw("Game over", gameOverTextArea);
- textFont.Draw("Try again?", tryAgainTextArea);
-
- textFont.Draw("Score: " + board.Score, scoreTextArea);
-
- textFont.Draw("Yes", yesTextArea);
- textFont.Draw("No", noTextArea);
- #endregion
- }
- else
- {
- Rectangle drawArea = ScreenSpace.DrawArea;
-
- #region Ingame
- board.UpdateGame();
- // Use the score to detect if we had some collision
- if (oldScore != board.Score)
- {
- // Initialization?
- if (oldScore == MathHelper.InvalidIndex)
- {
- //disabled: music.Looping = true;
- //disabled: music.Play();
- }
-
- // If this was just a paddle collision (1 score), use less volume
- sound.Volume = (board.Score == oldScore + 1) ? 0.5f : 1.0f;
- sound.Play();
-
- oldScore = board.Score;
- }
-
- // Render all blocks with their color
- for (int x = 0; x < board.Level; x++)
- {
- for (int y = 0; y < board.Level; y++)
- {
- Brick brick = board.Bricks[x, y];
-
- if (brick.IsDead == false)
- {
- block.BlendColor = brick.Color;
- block.Draw(drawArea.GetInnerRectangle(brick.Bounds));
- } // if
- } // for
- } // for
-
- // Remaining Lives text rendering
- string livesString = "Lives: " + board.Lives;
- Size livesStringSize = textFont.Measure(livesString);
- textFont.Draw(livesString, new Rectangle(drawArea.BottomLeft +
- new Point(0.005f, -livesStringSize.Height), livesStringSize));
-
- // Scores Rendering
- string scoreString = "Score: " + board.Score;
- Size scoreStringSize = textFont.Measure(scoreString);
- textFont.Draw(scoreString, new Rectangle(drawArea.BottomRight -
- scoreStringSize - new Point(0.005f, 0.0f), scoreStringSize));
-
- // And finally the bonus for each hit in the middle
- textFont.Draw("Bonus: " + board.DestroyedBlocks,
- new Rectangle(0.0f, drawArea.Bottom - textFont.LineHeight, 1.0f,
- textFont.LineHeight));
-
- // Render the paddle itself
- Size ballSize = new Size(board.Ball.Radius, board.Ball.Radius);
- paddle.Draw(drawArea.GetInnerRectangle(
- new Rectangle(board.PlayerPaddle.Position -
- new Size(board.PlayerPaddle.Size.WidthHalf,
- -ballSize.Height * 0.5f),
- board.PlayerPaddle.Size)));
-
- // And finally draw the animated ball with trail
- //TODO: add better trail (maybe as effect)
- //if (lastBallPositions.Count > 10)
- //{
- // // Remove first if we have more than 10 ball trail positions
- // lastBallPositions.RemoveAt(0);
- //}
- //lastBallPositions.Add(board.Ball.Position);
- //// Draw all trails (0-9, in the first frames we will have less)
- //for (int num = 0; num < lastBallPositions.Count; num++)
- //{
- Rectangle ballRect = drawArea.GetInnerRectangle(
- //new Rectangle(lastBallPositions[num] - ballSize,
- new Rectangle(board.Ball.Position - ballSize, ballSize * 2));
- // Set size back to quadratic space for the correct aspect ratio
- //float trailAlpha = (num + 1) / 10.0f;
- ballRect.Size = ballSize * 2;// * trailAlpha;
- //ballRect.Position -= ballSize * 2 * trailAlpha / 2.0f;
- //ball.BlendColor = new Color(Color.White, trailAlpha);
- ball.Draw(ballRect);
- //}
- #endregion
- }
- }
- #endregion
- }
- }