using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoMac.Foundation;
namespace Tetris
{
///
/// This is the main type for your game
///
public class Engine : Microsoft.Xna.Framework.Game
{
// Graphics
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D tetrisBackground, tetrisTextures;
SpriteFont gameFont;
readonly Rectangle[] blockRectangles = new Rectangle[7];
// Game
Board board;
Score score;
bool pause = false;
// Input
KeyboardState oldKeyboardState = Keyboard.GetState ();
public Engine ()
{
graphics = new GraphicsDeviceManager (this);
//Content.RootDirectory = "Content";
Content.RootDirectory = "Content";
// Create sprite rectangles for each figure in texture file
// O figure
blockRectangles [0] = new Rectangle (312, 0, 24, 24);
// I figure
blockRectangles [1] = new Rectangle (0, 24, 24, 24);
// J figure
blockRectangles [2] = new Rectangle (120, 0, 24, 24);
// L figure
blockRectangles [3] = new Rectangle (216, 24, 24, 24);
// S figure
blockRectangles [4] = new Rectangle (48, 96, 24, 24);
// Z figure
blockRectangles [5] = new Rectangle (240, 72, 24, 24);
// T figure
blockRectangles [6] = new Rectangle (144, 96, 24, 24);
}
///
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
///
protected override void Initialize ()
{
Window.Title = "MonoGame XNA Tetris 2D";
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 800;
this.TargetElapsedTime = TimeSpan.FromSeconds (1.0f / 10.0f);
// Try to open file if it exists, otherwise create it
using (FileStream fileStream = File.Open ("record.dat", FileMode.OpenOrCreate)) {
fileStream.Close ();
}
base.Initialize ();
}
///
/// LoadContent will be called once per game and is the place to load
/// all of your content.
///
protected override void LoadContent ()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch (GraphicsDevice);
// Add the SpriteBatch service
Services.AddService (typeof(SpriteBatch), spriteBatch);
//Load 2D textures
tetrisBackground = Content.Load ("background");
tetrisTextures = Content.Load ("tetris");
// Load game font
//gameFont = Content.Load ("font");
gameFont = Content.Load ("Arial");
// Create game field
board = new Board (this, ref tetrisTextures, blockRectangles);
board.Initialize ();
Components.Add (board);
// Save player's score and game level
score = new Score (this, gameFont);
score.Initialize ();
Components.Add (score);
// Load game record
using (StreamReader streamReader = File.OpenText ("record.dat")) {
string player = null;
if ((player = streamReader.ReadLine ()) != null)
score.RecordPlayer = player;
int record = 0;
if ((record = Convert.ToInt32 (streamReader.ReadLine ())) != 0)
score.RecordScore = record;
}
}
///
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
///
/// Provides a snapshot of timing values.
protected override void Update (GameTime gameTime)
{
// Allows the game to exit
KeyboardState keyboardState = Keyboard.GetState ();
if (keyboardState.IsKeyDown (Keys.Escape))
this.Exit ();
// Check pause
bool pauseKey = (oldKeyboardState.IsKeyDown (Keys.P) && (keyboardState.IsKeyUp (Keys.P)));
oldKeyboardState = keyboardState;
if (pauseKey)
pause = !pause;
if (!pause) {
// Find dynamic figure position
board.FindDynamicFigure ();
// Increase player score
int lines = board.DestroyLines ();
if (lines > 0) {
score.Value += (int)((5.0f / 2.0f) * lines * (lines + 3));
board.Speed += 0.005f;
}
score.Level = (int)(10 * board.Speed);
// Create new shape in game
if (!board.CreateNewFigure ())
GameOver ();
else {
// If left key is pressed
if (keyboardState.IsKeyDown (Keys.Left))
board.MoveFigureLeft ();
// If right key is pressed
if (keyboardState.IsKeyDown (Keys.Right))
board.MoveFigureRight ();
// If down key is pressed
if (keyboardState.IsKeyDown (Keys.Down))
board.MoveFigureDown ();
// Rotate figure
if (keyboardState.IsKeyDown (Keys.Up) || keyboardState.IsKeyDown (Keys.Space))
board.RotateFigure ();
// Moving figure
if (board.Movement >= 1) {
board.Movement = 0;
board.MoveFigureDown ();
} else
board.Movement += board.Speed;
}
}
base.Update (gameTime);
}
private void GameOver ()
{
if (score.Value > score.RecordScore) {
score.RecordScore = score.Value;
pause = true;
Record record = new Record ();
//record.ShowDialog ();
score.RecordPlayer = record.Player;
using (StreamWriter writer = File.CreateText ("record.dat")) {
writer.WriteLine (score.RecordPlayer);
writer.WriteLine (score.RecordScore);
}
pause = false;
}
board.Initialize ();
score.Initialize ();
}
///
/// This is called when the game should draw itself.
///
/// Provides a snapshot of timing values.
protected override void Draw (GameTime gameTime)
{
spriteBatch.Begin ();
spriteBatch.Draw (tetrisBackground, Vector2.Zero, Color.White);
base.Draw (gameTime);
spriteBatch.End ();
}
}
}