📄 tetrisgrid.cs
字号:
using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.IO;
namespace GATetrisControl
{
[ToolboxItem(false), EditorBrowsable(EditorBrowsableState.Never)]
public class TetrisGrid : Control
{
#region Exposed events
//Occurs when new figure is about to fall and I use it for updating the score
public event EventHandler NewFigure;
//This is for drawing the preview from the TetrisGridContainer class
public event EventHandler UpdateNextFigure;
//occurs when the game starts
//Thụ lý Event GameStart
public event EventHandler GameStart;
//occurs when the game ends
//Thụ lý Event GameEnd
public event EventHandler GameEnd;
//occurs when the game is paused
//Thụ lý Event GamePause
public event EventHandler GamePaused;
#endregion
#region Constructor
//Khởi tạo TestrisGrid
public TetrisGrid()
{
ResizeRedraw = true;
BackColor = SystemColors.Window;
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.UserPaint, true);
score = 0;
lines = 0;
nextFig = 0;
gameOver = false;
gameStarted = false;
newFigure = false;
invalidRects = new ArrayList();
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(TimerTick);
}
#endregion
#region Event Handlers
void TimerTick(object sender, EventArgs e)
{
currentFigure.Move(MoveDirection.Down);
//if we need new figure
if(newFigure)
{
int linesNum = 0;
bool refresh = false;
//first check for any completed lines
//Tìm các dòng đã hoàn thành
for(int i = 0; i < settings.rows; i++)
{
if(GetLine(i))
{
//clear the line
//Xóa dòng đã hoàn thành
ClearLine(i);
linesNum++;
lines++;
//scroll the line
//Cuộn dòng
ScrollLine(i);
//set the refresh flag to true
refresh = true;
}
}
if(refresh)
SmartRefresh();
//adjust score //Điều chỉnh lại điểm
if(linesNum == 0)
score+= 0;
if(linesNum == 1)
score+= 100;
if(linesNum == 2)
score+= 300;
if(linesNum == 3)
score+= 600;
if(linesNum == 4)
score+= 1000;
//adjust level and ticking //Tăng Level
UpdateLevel();
//fire the NewFigure event
if(NewFigure != null)
NewFigure(this, new EventArgs());
InitFigure();
InitNextFigure();
}
}
#endregion
#region Overriden Methods
protected override void Dispose( bool disposing )
{
timer.Stop();
base.Dispose(disposing);
}
protected override void OnResize(EventArgs e)
{
UpdateSize();
base.OnResize (e);
}
protected override void OnPaint(PaintEventArgs e)
{
SolidBrush brush = new SolidBrush(BackColor);
foreach(SingleSquare sq in squares)
{
//do not paint if not within the invalid rect
if(!e.Graphics.ClipBounds.IntersectsWith(sq.rect))
continue;
//if filled - call the single square to draw itself on this graphics
if(sq.filled)
sq.Draw(e.Graphics);
//otherwise just clear the square - fill it with its parent's back color
else
e.Graphics.FillRectangle(brush, sq.rect);
}
brush.Dispose();
}
//Xứ lý Keypress
protected override bool ProcessDialogKey(Keys key)
{
if(key == settings.pauseKey)
return OnPause();
if(!gameStarted || !timer.Enabled)
return base.ProcessDialogChar((char)(int)key);
bool processed = false;
MoveDirection dir = new MoveDirection();
//Thụ lý phím xoay
if(key == settings.rotateKey)
{
dir = MoveDirection.Rotate;
processed = true;
}
//Thụ lý phím dich phải
else if(key == settings.rightKey)
{
dir = MoveDirection.Right;
processed = true;
}
//Thụ lý phím dịch trái
else if(key == settings.leftKey)
{
dir = MoveDirection.Left;
processed = true;
}
//Thụ lý phím dịch xuống
else if(key == settings.downKey)
{
dir = MoveDirection.Down;
processed = true;
}
if(processed)
{
currentFigure.Move(dir);
return true;
}
return base.ProcessDialogChar((char)(int)key);
}
#endregion
#region Init Methods
internal Figure GetNextFigure()
{
switch(nextFig)
{
case 0:
return new Square(this); //Hình vuông
case 1:
return new Line(this); //Hình thanh dài
case 2:
return new Triangle(this);
case 3:
return new LThunder(this);
case 4:
return new RThunder(this);
case 5:
return new RightT(this);
case 6:
return new LeftT(this);
default:
return null;
}
}
void InitRectangles()
{
squares = new SingleSquare[settings.columns * settings.rows];
int counter = 0;
for(int i = 0; i < settings.rows * settings.squareWidth; i += settings.squareWidth)
{
for(int j = 0; j < settings.columns * settings.squareWidth; j += settings.squareWidth)
{
squares[counter] = new SingleSquare(this);
squares[counter].rect = new Rectangle(j,i,settings.squareWidth,settings.squareWidth);
counter++;
}
}
}
void InitFigure()
{
if(DesignMode)
return;
switch(nextFig)
{
case 0:
currentFigure = new Square(this);
break;
case 1:
currentFigure = new Line(this);
break;
case 2:
currentFigure = new Triangle(this);
break;
case 3:
currentFigure = new LThunder(this);
break;
case 4:
currentFigure = new RThunder(this);
break;
case 5:
currentFigure = new RightT(this);
break;
case 6:
currentFigure = new LeftT(this);
break;
}
if(!currentFigure.CanDraw())
{
gameOver = true;
InitGameOver();
return;
}
currentFigure.direction = settings.rotateDirection;
currentFigure.DrawFigure();
SmartRefresh();
newFigure = false;
}
void InitNextFigure()
{
Random r = new Random();
nextFig = (byte)r.Next(0,7);
if(UpdateNextFigure != null)
UpdateNextFigure(this, new EventArgs());
}
public void InitNewGame()
{
Refresh();
gameOver = false;
gameStarted = true;
level = settings.startLevel;
score = 0;
lines = 0;
InitRectangles();
InitNextFigure();
InitFigure();
UpdateInterval();
timer.Start();
if(GameStart != null)
GameStart(this, new EventArgs());
}
public void InitGameOver()
{
timer.Stop();
if(gameOver)
{
DialogResult dr = MessageBox.Show("The game is over!\nWould you like to play another game?",
"GATetris",MessageBoxButtons.YesNo,MessageBoxIcon.Exclamation);
switch(dr)
{
case DialogResult.Yes:
if(this.GameEnd != null)
GameEnd(this, new EventArgs());
InitNewGame();
return;
case DialogResult.No:
break;
}
}
InitRectangles();
Invalidate();
invalidRects.Clear();
gameStarted = false;
if(GameEnd != null)
GameEnd(this, new EventArgs());
}
public void InitGameSave()
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Tetris Files | *.gat";
saveFileDialog.OverwritePrompt = true;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
string path = saveFileDialog.FileName;
FileStream file = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter bwriter = new BinaryWriter(file);
try
{
SaveTetrisGrid(bwriter);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -