TetrisGame.cs :  » Game » DotNETris » KP » Tetris » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » DotNETris 
DotNETris » KP » Tetris » TetrisGame.cs
// (c) 2005 kp@kp73.com

using System;
using System.Collections;
using System.Threading;

namespace KP.Tetris{
  /// <summary>
  /// Controls a game of tetirs.
  /// </summary>
  public class TetrisGame : IDisposable
  {
    #region Game instance values

    /// <summary>
    /// 10000000
    /// </summary>
    private const int TICKS_PER_SECOND = 1000;

    /// <summary>
    /// The player of the game.
    /// </summary>
    private Player m_player;

    /// <summary>
    /// Indicates when the game has finished.
    /// </summary>
    private bool m_isOver;

    /// <summary>
    /// Level of difficulty.
    /// </summary>
    private int m_level;

    /// <summary>
    /// Maximum amount of time between downward tetramino movements.
    /// </summary>
    private long dropDelayTicks;

    /// <summary>
    /// Number of tetraminos to queue up ready for play.
    /// </summary>
    private int queueLength = 4;

    /// <summary>
    /// Collection of tetraminos queued up to be played next.
    /// </summary>
    private Queue m_tetraminoQueue;

    /// <summary>
    /// The active tetramino.
    /// </summary>
    private Tetramino m_activeTetramino;

    /// <summary>
    /// The game play area.
    /// </summary>
    private Board m_playArea;

    /// <summary>
    /// Game observers, for UI presentation.
    /// </summary>
    private IGameViewer viewer;

    /// <summary>
    /// Game control thread.
    /// </summary>
    Thread gameLoopThread;

    private bool _paused;

    private int spawnRow;
    private int spawnColumn;

    private object sync = new object();
    #endregion

    /// <summary>
    /// Initialises a new instance of the TetrisGame class.
    /// </summary>
    public TetrisGame(IGameViewer gameViewer)
    {
      m_isOver = true;
      viewer = gameViewer; 
    }

    public event TetrisEventHandler TetraminoLanded;

    public event TetrisEventHandler RowCompleted;

    /// <summary>
    /// Get the player of the game.
    /// </summary>
    public Player Player
    {
      get { return m_player; } 
    }

    /// <summary>
    /// Get the current game level of difficulty.
    /// </summary>    
    public int Level
    {
      get { return m_level + ((PlayArea.RowsCompleted - 1) / 10); }
    }

    /// <summary>
    /// Start the game.
    /// </summary>
    public void Start(Player gamePlayer, int gameStartLevel)
    {
      m_player = gamePlayer;
      m_level = gameStartLevel;
      spawnColumn = (Board.Width / 2);
      spawnRow = Board.Height - 1;

      Reset();

      ThreadStart threadStart = new ThreadStart(GameLoop);
      gameLoopThread = new Thread(threadStart);
      gameLoopThread.IsBackground = true;
      gameLoopThread.Start();
    }

    /// <summary>
    /// Stop the game.
    /// </summary>
    public void Stop()
    {
      m_isOver = true;
      // not supported by compact framework, probably not even needed anyway!
      // gameLoopThread.Join(); 
    }

    /// <summary>
    /// Main game loop.
    /// </summary>
    private void GameLoop()
    {
      SpawnNewTetramino();
      while (!IsOver) 
      {
        if (!IsOver && !IsPaused) 
        {
          DoGameRound();
        }
        Thread.Sleep(100);
      }
    }

    /// <summary>
    /// Get game over indicator.
    /// </summary>
    public bool IsOver
    {
      get { return m_isOver; }
    }

    /// <summary>
    /// Initialise the game instance ready to begin  a new game.
    /// </summary>
    private void Reset()
    {
      m_isOver = false;
      m_tetraminoQueue = null; 
      m_activeTetramino = null;
      m_playArea = new Board();

      UpdateDropDelay();
      TetraminoFactory.SeedRandom();
      FillTetraminoQueue();
    }

    /// <summary>
    /// Populate the tetramino queue collection with 
    /// psudeo random tetramino instances.
    /// </summary>
    private void FillTetraminoQueue()
    {
      m_tetraminoQueue = new Queue();
      while (TetraminoQueue.Count < queueLength)
      {
        TetraminoQueue.Enqueue(TetraminoFactory.NewTetramino);
      }
    }

    /// <summary>
    /// Run one round of the game.
    /// </summary>
    private void DoGameRound()
    {
      bool refeshView = false;
      if (DropDelayReached())
      {
        if (ActiveTetramino.State.HasLanded(PlayArea))
        {
          Player.AwardPoints(Level, ActiveTetramino.State.DropCount);      

          if (ActiveTetramino.State.Location.X == spawnColumn
            && ActiveTetramino.State.Location.Y == spawnRow) 
          {
            m_isOver = true;
          }
          else
          {              
            PlayArea.MergeTetramino(ActiveTetramino.State);
            int removedRows = PlayArea.RemoveCompletedRows();
            if (removedRows > 0 && RowCompleted != null)
              RowCompleted(this, null); // fire row competed event
            SpawnNewTetramino();
          }
          UpdateDropDelay();

          if (TetraminoLanded != null)
            TetraminoLanded(this, null);  // fire tetramino landed event
        }
        else 
        {
          ActiveTetramino.State.DropOneRow(false);          
        }
        refeshView = true; 
      }

      if (refeshView)
      {
        viewer.Refresh(PlayArea.GetGameView(this));
      }
    }

    private bool DropDelayReached()
    {
      bool reached = false;
      if (ActiveTetramino != null)
      {
        long nowTicks = Environment.TickCount; // was System.DateTime.Now.Ticks;
        long ticksElapsed = nowTicks - ActiveTetramino.State.LastDropTicks;
        reached = (ticksElapsed < 0 || ticksElapsed > dropDelayTicks);
      }
      return reached;
    }

    /// <summary>
    /// Places a new tetramino into play at top of the play area.
    /// </summary>
    private void SpawnNewTetramino()
    {
      m_activeTetramino = (Tetramino)TetraminoQueue.Dequeue();
      m_activeTetramino.SetState(new TetraminoState(ActiveTetramino));
      m_activeTetramino.State.Location = new Coordinate(spawnColumn , spawnRow);
      m_tetraminoQueue.Enqueue(TetraminoFactory.NewTetramino);
    }

    /// <summary>
    /// Set the minimum amount of time between downward tetramino movements.
    /// </summary>
    private void UpdateDropDelay()
    {
      float dropDelaySeconds = (10.0f - Level) / 20.0f;
      dropDelayTicks = (long)(dropDelaySeconds * TICKS_PER_SECOND);
    }

    /// <summary>
    /// Get the active tetramino.
    /// </summary>
    internal Tetramino ActiveTetramino
    {
      get { return m_activeTetramino; }
    }

    /// <summary>
    /// Attempt to move the active tetramino within the play area.
    /// </summary>
    /// <param name="movement"></param>
    public void RequestMove(Movement movement)
    {
      if (!IsPaused && !IsOver && ActiveTetramino.State.RequestMove(movement, PlayArea))
        viewer.Refresh(PlayArea.GetGameView(this));
    }

    /// <summary>
    /// Get the collection of tetraminos queued up to play.
    /// </summary>
    public Queue TetraminoQueue
    {
      get { return m_tetraminoQueue; }
    }

    /// <summary>
    /// Get the active play area.
    /// </summary>
    internal Board PlayArea
    {
      get { return m_playArea; }
    }

    /// <summary>
    /// Get or set game paused indicator.
    /// </summary>
    public bool IsPaused
    {
      get { return _paused; }
      set { _paused = value; }
    }

    #region IDisposable Members

    /// <summary>
    /// Cleanup.
    /// </summary>
    public void Dispose()
    {
      if (Player != null) Player.Dispose();
      disposed = true;
      GC.SuppressFinalize(this);
    }

    #endregion

    bool disposed;

    /// <summary>
    /// Destructor dispose if not already disposed.
    /// </summary>
    ~TetrisGame()
    {
      if (!disposed) this.Dispose();
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.