using System; using System.ComponentModel; using System.Collections; using System.Diagnostics; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; namespace WahooControlLibrary { [DockingAttribute(DockingBehavior.Ask)] public class WahooGameControl : Control { int linesRemoved = 0; int tick = 500; int speed = 0; Keys leftKey = Keys.J; Keys rightKey = Keys.L; Keys rotateRightKey = Keys.I; Keys rotateLeftKey = Keys.Oemcomma; Keys dropKey = Keys.K; bool isPlaying = false; bool isPaused = false; Game game = new Game(); private System.Windows.Forms.Timer timer; private System.ComponentModel.IContainer components; public delegate void GameOverCallback(); public delegate void LinesRemovedCallback(int linesRemoved); public event GameOverCallback GameOver; public event LinesRemovedCallback LinesRemoved; public WahooGameControl() { // Required for the designer InitializeComponent(); // Custom init this.game.Rows = 20; this.game.Columns = 10; this.game.CellPadding = 2; // Turn off the flicker SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.timer = new System.Windows.Forms.Timer(this.components); // // timer // this.timer.Tick += new System.EventHandler(this.timer_Tick); } public int TickInterval { get { return this.tick; } set { this.tick = value; } } public int Speed { get { return this.speed; } } public int Rows { get { return this.game.Rows; } set { this.game.Rows = value; Invalidate(); } } public int Columns { get { return this.game.Columns; } set { this.game.Columns = value; Invalidate(); } } public int CellPadding { get { return this.game.CellPadding; } set { this.game.CellPadding = value; Invalidate(); } } public bool IsPaused { get { return this.isPaused; } } public bool IsPlaying { get { return this.isPlaying; } } public void New() { this.game.Reset(); this.linesRemoved = 0; timer.Interval = this.tick; timer.Enabled = true; this.isPlaying = true; this.isPaused = false; } public void Pause() { timer.Enabled = false; this.isPaused = true; } public void Resume() { timer.Enabled = true; this.isPaused = false; } public bool ProcessKey(Keys keyData) { if( DesignMode || !this.isPlaying || this.isPaused ) return false; // Check for the arrow keys, too bool processed = false; if( keyData == this.dropKey || keyData == Keys.Down ) processed = this.game.Drop(); else if( keyData == this.leftKey || keyData == Keys.Left ) processed = this.game.Left(); else if( keyData == this.rightKey || keyData == Keys.Right ) processed = this.game.Right(); else if( keyData == this.rotateRightKey || keyData == Keys.Up ) processed = this.game.RotateRight(); else if( keyData == this.rotateLeftKey ) processed = this.game.RotateLeft(); if( processed ) Invalidate(); return processed; } void Draw(Graphics g) { this.game.Draw(g); } void DrawDesignMode(Graphics g) { for( int row = 0; row != this.game.Rows; ++row ) { for( int col = 0; col != this.game.Columns; ++col ) { g.DrawRectangle(Pens.Black, Game.GetCellRectangle(ClientSize, this.game.Rows, this.game.Columns, this.game.CellPadding, row, col)); } } } #region Event handlers // protected override void OnKeyDown(KeyEventArgs e) // { // if( ProcessKey(e.KeyData) ) // { // Invalidate(); // } // // base.OnKeyDown(e); // } protected override void OnPaint(PaintEventArgs args) { base.OnPaint(args); if( DesignMode ) DrawDesignMode(args.Graphics); else Draw(args.Graphics); } protected override void OnSizeChanged(EventArgs e) { this.game.Size = ClientSize; Invalidate(); } private void timer_Tick(object sender, System.EventArgs e) { // Update the game this.game.Tick(); // Redraw Invalidate(); // Check for removed lines if( this.game.LinesRemoved > this.linesRemoved ) { if( LinesRemoved != null ) LinesRemoved(this.game.LinesRemoved - this.linesRemoved); this.linesRemoved = this.game.LinesRemoved; // Increase the speed (in chunks) if( this.tick - this.linesRemoved * 10 > 0 ) { this.speed = (this.linesRemoved / 10) * 100; timer.Interval = this.tick - this.speed; } } // Check for game over if( this.game.IsOver ) { timer.Enabled = false; this.isPlaying = false; this.isPaused = false; if( GameOver != null ) GameOver(); } } #endregion } }