using System;
using System.Drawing;
using System.Windows.Forms;
namespace MyGame
{
public delegate void KillWoodEventHandler();
public interface IGameBo
{
int[,] Grids { get; }
int XPos { get; }
int YPos { get; }
}
public interface IGameBiz
{
void Run();
}
public interface IGameLogic
{
void Draw(Graphics e);
void KeyDown(KeyEventArgs e);
}
public interface IGameWood : IGameLogic
{
event KillWoodEventHandler KillWood;
}
public interface IWoodBo
{
int[,] Grids { get; }
}
public interface IWoodBiz
{
bool OnAngle();
bool CanLeft();
bool CanRight();
bool CanDown();
}
public interface IWood : IWoodBiz, IWoodBo
{
}
public class WoodGame : IGameBo, IGameBiz, IGameLogic, IGameWood
{
public const int X = 20, Y = 20;
public const int StartPos = 7;
public const int Dimension = 18;
public const int XDimension = XSize * Dimension;
public const int YDimension = YSize * Dimension;
public const int XSize = 16;
public const int YSize = 26;
public event KillWoodEventHandler KillWood;
int[,] Grids { get; set; }
int XPos { get; set; }
int YPos { get; set; }
int[,] IGameBo.Grids { get { return this.Grids; } }
int IGameBo.XPos { get { return this.XPos; } }
int IGameBo.YPos { get { return this.YPos; } }
Random Random = new Random();
IWood CurrentWood, NextWood;
Bitmap bmp;
public WoodGame()
{
Init();
}
~WoodGame()
{
UnInit();
}
public void Draw(Graphics e)
{
using (Graphics graphics = Graphics.FromImage(bmp))
{
graphics.Clear(Color.White);
DrawContext(graphics);
}
e.DrawImage(bmp, X, Y);
}
public void KeyDown(KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Left:
if (CurrentWood.CanLeft())
{
XPos--;
this.OnDraw();
}
break;
case Keys.Right:
if (CurrentWood.CanRight())
{
XPos++;
this.OnDraw();
}
break;
case Keys.Down:
Run();
break;
case Keys.Space:
if (CurrentWood.OnAngle())
this.OnDraw();
break;
}
}
public void Run()
{
if (CurrentWood.CanDown())
{
YPos++;
}
else
{
FinishWood();
StartWood();
}
this.OnDraw();
}
void Init()
{
bmp = new Bitmap(XDimension + 1, YDimension + 1);
Grids = new int[XSize, YSize];
NextWood = GetWood();
StartWood();
}
void UnInit()
{
bmp.Dispose();
}
void StartWood()
{
CurrentWood = NextWood;
NextWood = GetWood();
XPos = StartPos;
YPos = 0;
}
void FinishWood()
{
int size = CurrentWood.Grids.GetLength(0);
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
if (CurrentWood.Grids[x, y] != 0)
Grids[XPos + x, YPos + y] = 1;
}
}
PriKillWood();
OnDraw();
}
void PriKillWood()
{
int size = CurrentWood.Grids.GetLength(0);
int y1 = Math.Min(YPos + size, YSize) - 1;
int y2 = y1;
while (y1 >= YPos)
{
int x1 = 0;
while (x1 < XSize)
{
if (Grids[x1, y1] == 0)
break;
x1++;
}
if (x1 == XSize)
{
OnKillWood();
}
else
{
for (int x = 0; x < XSize; x++)
Grids[x, y2] = Grids[x, y1];
y2--;
}
y1--;
}
while (y1 >= 0)
{
for (int x = 0; x < XSize; x++)
Grids[x, y2] = Grids[x, y1];
y2--;
y1--;
}
}
void OnDraw()
{
if (Form.ActiveForm != null)
Form.ActiveForm.Refresh();
}
void DrawContext(Graphics e)
{
for (int x = 0; x <= XDimension; x += Dimension)
e.DrawLine(Pens.SlateGray, x, 0, x, YDimension);
for (int y = 0; y <= YDimension; y += Dimension)
e.DrawLine(Pens.SlateGray, 0, y, XDimension, y);
int size = CurrentWood.Grids.GetLength(0);
for (int x = 0; x < XSize; x++)
{
for (int y = 0; y < YSize; y++)
{
if (Grids[x, y] == 1)
e.FillRectangle(Brushes.Black, new Rectangle(x * Dimension + 2, y * Dimension + 2, Dimension - 3, Dimension - 3));
}
}
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
if (CurrentWood.Grids[x, y] == 1)
e.FillRectangle(Brushes.Black, new Rectangle((XPos + x) * Dimension + 2, (YPos + y) * Dimension + 2, Dimension - 3, Dimension - 3));
}
}
}
private void OnKillWood()
{
if (KillWood != null)
{
KillWood();
}
}
Wood GetWood()
{
int rnd = Random.Next() % 8;
switch (rnd)
{
case 0:
rnd = Random.Next() % 2;
return new AngleWood(this, new int[,,]
{
{{0,0,0,0},
{0,0,0,0},
{1,1,1,1},
{0,0,0,0}},
{{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0}},
}, rnd);
case 1:
rnd = Random.Next() % 4;
return new AngleWood(this, new int[,,]
{
{{1,0,0},
{1,0,0},
{1,1,0}},
{{0,0,0},
{1,1,1},
{1,0,0}},
{{1,1,0},
{0,1,0},
{0,1,0}},
{{0,0,0},
{0,0,1},
{1,1,1}}
}, rnd);
case 2:
rnd = Random.Next() % 2;
return new AngleWood(this, new int[,,]
{
{{1,1,0},
{0,1,1},
{0,0,0}},
{{0,1,0},
{1,1,0},
{1,0,0}},
}, rnd);
case 3:
rnd = Random.Next() % 2;
return new AngleWood(this, new int[,,]
{
{{0,1,1},
{1,1,0},
{0,0,0}},
{{1,0,0},
{1,1,0},
{0,1,0}},
}, rnd);
case 4:
rnd = Random.Next() % 4;
return new AngleWood(this, new int[,,]
{
{{0,0,1},
{0,0,1},
{0,1,1}},
{{0,0,0},
{1,0,0},
{1,1,1}},
{{0,1,1},
{0,1,0},
{0,1,0}},
{{0,0,0},
{1,1,1},
{0,0,1}}
}, rnd);
case 5:
return new AngleWood(this, new int[,,]
{
{{1,1},
{1,1}}
}, 0);
case 6:
rnd = Random.Next() % 4;
return new AngleWood(this, new int[,,]
{
{{0,1,1},
{0,0,1},
{0,1,1}},
{{0,0,0},
{1,0,1},
{1,1,1}},
{{1,1,0},
{1,0,0},
{1,1,0}},
{{1,1,1},
{1,0,1},
{0,0,0}}
}, rnd);
case 7:
rnd = Random.Next() % 4;
return new AngleWood(this, new int[,,]
{
{{1,1,1},
{0,1,0},
{0,0,0}},
{{0,0,1},
{0,1,1},
{0,0,1}},
{{0,0,0},
{0,1,0},
{1,1,1}},
{{1,0,0},
{1,1,0},
{1,0,0}}
}, rnd);/*
case 8:
rnd = Random.Next() % 4;
return new AngleWood(this, new int[,,]
{
{{0,1,0},
{0,1,0},
{1,1,1}},
{{1,0,0},
{1,1,1},
{1,0,0}},
{{1,1,1},
{0,1,0},
{0,1,0}},
{{0,0,1},
{1,1,1},
{0,0,1}}
}, rnd);
case 9:
rnd = Random.Next() % 4;
return new AngleWood(this, new int[,,]
{
{{1,0,0,0},
{1,1,0,0},
{1,1,1,0},
{1,1,1,1}},
{{1,1,1,1},
{1,1,1,0},
{1,1,0,0},
{1,0,0,0}},
{{1,1,1,1},
{0,1,1,1},
{0,0,1,1},
{0,0,0,1}},
{{0,0,0,1},
{0,0,1,1},
{0,1,1,1},
{1,1,1,1}}
}, rnd);
case 10:
rnd = Random.Next() % 2;
return new AngleWood(this, new int[,,]
{
{{1,1,1},
{0,0,0},
{1,1,1}},
{{1,0,1},
{1,0,1},
{1,0,1}}
}, rnd);*/
}
throw new Exception();
}
}
public abstract class Wood : IWood
{
public IGameBo Game;
public int[,] Grids { get; set; }
public Wood(IGameBo mGame, int[,] mGrids)
{
this.Game = mGame;
this.Grids = mGrids;
}
public abstract bool OnAngle();
public virtual bool CanLeft()
{
return Check(Grids, Game.XPos - 1, Game.YPos);
}
public virtual bool CanRight()
{
return Check(Grids, Game.XPos + 1, Game.YPos);
}
public virtual bool CanDown()
{
return Check(Grids, Game.XPos, Game.YPos + 1);
}
public virtual int GetSize()
{
return Grids.GetLength(0);
}
protected bool Check(int[,] mGrids, int mXPos, int mYPos)
{
int size = this.GetSize();
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
if (mGrids[x, y] == 0)
continue;
if (mXPos + x < 0 || mXPos + x >= WoodGame.XSize || mYPos + y >= WoodGame.YSize || (mXPos + x >= 0 && mYPos + y >= 0 && Game.Grids[mXPos + x, mYPos + y] != 0))
return false;
}
}
return true;
}
}
public class AngleWood : Wood
{
int Angle;
int AngleTime;
int[, ,] AngleGrids;
public AngleWood(IGameBo mGame, int[, ,] mAngleGrids, int mAngle)
: base(mGame, GetAngle(mAngleGrids, mAngle))
{
this.Angle = mAngle;
this.AngleTime = mAngleGrids.GetLength(0);
this.AngleGrids = mAngleGrids;
}
public override bool OnAngle()
{
int angle = this.Angle;
if (angle == this.AngleTime - 1)
angle = 0;
else
angle++;
int[,] newGrids;
if (CanAngle(angle, out newGrids))
{
Grids = newGrids;
this.Angle = angle;
return true;
}
return false;
}
static int[,] GetAngle(int[, ,] mAngleGrids, int mAngle)
{
int size = mAngleGrids.GetLength(1);
int[,] grids = new int[size, size];
for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
grids[x, y] = mAngleGrids[mAngle, y, x];
return grids;
}
public virtual bool CanAngle(int mAngle, out int[,] mNewGrids)
{
int size = this.GetSize();
int[,] newAngle = GetAngle(AngleGrids, mAngle);
mNewGrids = null;
if (!Check(newAngle, Game.XPos, Game.YPos))
return false;
mNewGrids = newAngle;
return true;
}
}
static class GameProgram
{
class GameForm : Form
{
const string text = "俄罗斯方块,分数:";
IGameWood game;
public GameForm()
{
int cx = WoodGame.XDimension + WoodGame.X * 2 + SystemInformation.Border3DSize.Width * 2 + 3;
int cy = WoodGame.YDimension + WoodGame.Y * 2 + SystemInformation.Border3DSize.Height * 2 + SystemInformation.CaptionHeight + 3;
this.Size = new Size(cx, cy);
this.DoubleBuffered = true;
this.MaximizeBox = false;
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Text = text + "0";
game = new WoodGame();
game.KillWood += game_KillWood;
}
int i = 0;
void game_KillWood()
{
i += 100;
this.Text = text + i;
}
protected override void OnPaint(PaintEventArgs e)
{
game.Draw(e.Graphics);
}
protected override void OnKeyDown(KeyEventArgs e)
{
game.KeyDown(e);
}
}
static void Main()
{
Application.Run(new GameForm());
}
}
}
转载于:https://www.cnblogs.com/softcreator/articles/softcreator_8627537.html
相关资源:Qt5实现的俄罗斯方块