C#实现俄罗斯方块

作者:alert(''''Csharp'''') 时间:2023-10-29 05:44:27 

本文实例为大家分享了C#实现俄罗斯方块的具体代码,供大家参考,具体内容如下

1.调色板代码


namespace Tetris
{
class Palette
{
private int _width = 15;//画板宽度
private int _height = 25;//画板高度
private Color[,] coorArr;//固定砖块数组
private Color disapperColor;//背景色
private Graphics gpPalette;//砖块活动画板
private Graphics gpReady;//下一个砖块样式画板
private BlockGroup bGroup;//砖块生产机制
private Block runBlock;//正在活动的砖块
private Block readyBlock;//下一个砖块
private int rectPix;//单元格像
public delegate void IniCountHandle(int _count,int state);//分数变量
public event IniCountHandle CountEvent;
public static int _Count = 0;

static int mark = 100;//静态变量衡量过关的标准
public static int state = 1;

private System.Timers.Timer timerBlock;//定时器
private static int timeSpan = 800;//定时器的时间间隔

public Palette(int x, int y, int pix, Color dColor, Graphics gp, Graphics gr)//构造函数
{
 _width = x;
 _height = y;
 coorArr = new Color[_width, _height];
 disapperColor = dColor;
 gpPalette = gp;
 gpReady = gr;
 rectPix = pix;
}
public void Start()//游戏开始
{
 state = 1;
 _Count = 0;
 bGroup = new BlockGroup();
 runBlock = bGroup.GetABlock();
 runBlock.XPos = _width / 2;
 int y = 0;
 for (int i = 0; i < runBlock.Length ; i++)//垂直位置
 {
 if (runBlock[i].Y > y)
 {
  y = runBlock[i].Y;
 }
 }
 runBlock.YPos = y;
 gpPalette.Clear(disapperColor);//清空画板
 runBlock.Paint(gpPalette);//画运行砖块
 Thread.Sleep(20);
 readyBlock = bGroup.GetABlock();
 readyBlock.XPos = 2;
 readyBlock.YPos = 2;
 gpReady.Clear(disapperColor);//清空画板
 readyBlock.Paint(gpReady);
 //初始化并启动定时器
 timerBlock = new System.Timers.Timer(timeSpan);
 timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
 timerBlock.AutoReset = true;
 timerBlock.Start();
}
public void nextstate()
{

PaintBackground(gpPalette);
 timerBlock = new System.Timers.Timer(timeSpan);
 timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
 timerBlock.AutoReset = true;
 timerBlock.Start();
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
 CheckAndOverBlock();
 Down();
}
public bool Down()//砖块下移
{
 int xPos = runBlock.XPos;
 int yPos = runBlock.YPos + 1;
 for (int i = 0; i < runBlock.Length; i++)
 {
 if (yPos - runBlock[i].Y > _height - 1)//如果超出下边界则失败
  return false;
 if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果下边有东西挡则失败
  return false;
 }
 runBlock.erase(gpPalette);//擦除原来位置砖块
 runBlock.YPos++;
 runBlock.Paint(gpPalette);
 return true;
}
public void Drop()//丢下砖块
{
 timerBlock.Stop();
 while (Down()) ;
 timerBlock.Start();
}
public void MoveLeft()//向左移动
{
 int xPos = runBlock.XPos - 1;
 int yPos = runBlock.YPos;
 for (int i = 0; i < runBlock.Length; i++)
 {
 if (xPos + runBlock[i].X < 0)
  return;
 if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果左边有东西挡则失败
  return;
 }
 runBlock.erase(gpPalette);
 runBlock.XPos--;
 runBlock.Paint(gpPalette);
}
public void MoveRight()//向右移动
{
 int xPos = runBlock.XPos + 1;
 int yPos = runBlock.YPos;
 for (int i = 0; i < runBlock.Length; i++)
 {
 if (xPos + runBlock[i].X > _width -1)//如果超出右边界则失败
  return;
 if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果右边有东西挡则失败
  return;
 }
 runBlock.erase(gpPalette);
 runBlock.XPos++;
 runBlock.Paint(gpPalette);
}
public void DeasilRotate()//顺时针旋转
{
 for (int i = 0; i < runBlock.Length; i++)
 {
 int x = runBlock.XPos + runBlock[i].Y;
 int y = runBlock.YPos + runBlock[i].X;
 if (x < 0 || x > _width - 1)
  return;
 if (y < 0 || y > _height - 1)
  return;
 if (!coorArr[x, y].IsEmpty)
  return;
 }
 runBlock.erase(gpPalette);
 runBlock.DeasilRotate();
 runBlock.Paint(gpPalette);
}
public void ContraRotate()//逆时针旋转
{
 for (int i = 0; i < runBlock.Length; i++)
 {
 int x = runBlock.XPos - runBlock[i].Y;
 int y = runBlock.YPos - runBlock[i].X;
 if (x < 0 || x > _width - 1)
  return;
 if (y < 0 || y > _height - 1)
  return;
 if (!coorArr[x, y].IsEmpty)
  return;
 }
 runBlock.erase(gpPalette);
 runBlock.ContraRotate();
 runBlock.Paint(gpPalette);
}
private void PaintBackground(Graphics gp)//重画画板背景
{
 gp.Clear(Color.Black);//清空画板
 for (int i = 0; i < _height; i++)
 {
 for (int j = 0; j < _width; j++)
 {
  if (!coorArr[j, i].IsEmpty)
  {
  SolidBrush sb = new SolidBrush(coorArr[j, i]);
  gp.FillRectangle(sb, j * rectPix + 1,
   i * rectPix + 1,
   rectPix - 2,
   rectPix - 2);
  }
 }
 }
}
public void PaintPalette(Graphics gp)//重画整个画板
{
 PaintBackground(gp);//先画背景
 if (runBlock != null)//再画活动的砖块
 {
 runBlock.Paint(gp);
 }
}
public void PaintReady(Graphics gp)//重画下一个砖块
{
 if (readyBlock != null)
 {
 readyBlock.Paint(gp);
 }
}
 public void CheckAndOverBlock()//检查砖块是否到底
{
 bool over = false;
 for (int i = 0; i < runBlock.Length; i++)
 {
 int x = runBlock.XPos + runBlock[i].X;
 int y = runBlock.YPos - runBlock[i].Y;
 if (y == _height - 1)
 {
  over = true;
  break;
 }
 if (!coorArr[x, y + 1].IsEmpty)//如果下面有砖块,则当前砖块结束
 {
  over = true;
  break;
 }
 }
 if (over)//如果当前砖块已经结束
 {
  for (int i = 0; i < runBlock.Length; i++)//把当前砖块归入coordinatearr
  {
  coorArr[runBlock.XPos + runBlock[i].X, runBlock.YPos - runBlock[i].Y] = runBlock.BlockColor;
  }
  //检查是否有满行现象,如果有,则删除
  CheckAndDelFullRow();
  //产生新的砖块
  runBlock = readyBlock;//新的砖块为准备好的砖块
  runBlock.XPos = _width / 2;
  int y = 0;
  for (int i = 0; i < runBlock.Length; i++)//垂直位置
  {
  if (runBlock[i].Y > y)
  {
   y = runBlock[i].Y;
  }
  }
  runBlock.YPos = y;
  //检查新产生的砖块所占用的地方是否已经有砖块,如果有,则游戏结束
  for (int i = 0; i < runBlock.Length; i++)
  {
  if (!coorArr[runBlock.XPos + runBlock[i].X, runBlock.YPos - runBlock[i].Y].IsEmpty)
  {
   //游戏结束
   StringFormat drawFormat = new StringFormat();
   drawFormat.Alignment = StringAlignment.Center;
   gpPalette.DrawString("GAME OVER"+"\r\n"+"得分:" + _Count.ToString()+"\r\n等级:"+state .ToString (),
   new Font("Arial Black", 25f),
   new SolidBrush(Color.Yellow ),
   new RectangleF(0, _height * rectPix / 2 - 100, _width * rectPix, 150),
   drawFormat);
   timerBlock.Stop();
   return;
  }
  }
  runBlock.Paint(gpPalette);
  //获取新的准备砖块
  readyBlock = bGroup.GetABlock();
  readyBlock.XPos = 2;
  readyBlock.YPos = 2;
  gpReady.Clear(Color.Black);
  readyBlock.Paint(gpReady);
 }
}
private void CheckAndDelFullRow()//检查并删除满行
{
 //找出当前砖块所在行范围
 int lowRow = runBlock.YPos - runBlock[0].Y;//lowRow代表当前砖块的Y轴的最小值
 int highRow = lowRow;//highRow代表当前砖块的y轴的最大值
 for (int i = 0; i < runBlock.Length;i++ )//找出当前砖块所占行的范围,放入low,high变量内
 {
 int y = runBlock.YPos - runBlock[i].Y;
 if (y < lowRow)
 {
  lowRow = y;
 }
 if (y > highRow)
 {
  highRow = y;
 }
 }
 int count=0;
 bool repaint = false;//判断是否重画
 for (int i = lowRow; i <= highRow; i++)//检查是否满行
 {
 bool rowFull = true;

for (int j = 0; j < _width; j++)
 {
  if (coorArr[j, i].IsEmpty)//如果有一个单元格为空,说明这一行不可能为满行
  {
  rowFull = false;
  break;
  }
 }
 if (rowFull)//如果满行,则删除这一行
 {
  count ++;
  repaint = true;//如果删除,则需重画
  for (int k = i; k > 0; k--)
  {
  for (int j = 0; j < _width; j++)
  {
   coorArr[j, k] = coorArr[j, k - 1];
  }
  }
  for (int j = 0; j < _width; j++)//清空第0行
  {
  coorArr[j, 0] = Color.Empty;
  }
 }

}
 //计算每满几行加的分值
 if (count == 1)
 {
 _Count += 10;
 CountEvent(_Count,state);
 }
 if (count == 2)
 {
 _Count += 30;
 CountEvent(_Count,state);
 }
 if (count == 3)
 {
 _Count += 60;
 CountEvent(_Count,state );
 }
 if (count >= 4)
 {
 _Count += 80;
 CountEvent(_Count,state);
 }
 if (repaint)//重画
 {
 PaintBackground(gpPalette);
 }
 if (_Count >= 1000)//如果通关初始化为原来的值
 {
 StringFormat drawFormat = new StringFormat();
 drawFormat.Alignment = StringAlignment.Center;
 gpPalette.DrawString("O(∩_∩)O"+"\r\n"+"***通关***"+"\r\n"+"按“开始”按钮\r\n王者归来",
  new Font("Arial Black", 20f),
  new SolidBrush(Color.Red),
  new RectangleF(0, _height * rectPix / 2 - 100, _width * rectPix, 120),
  drawFormat);
 timeSpan = 800;
 state = 1;
 _Count = 0;
 timerBlock.Close();
 }

if (_Count >= mark)
 {
 mark += 100;
 timeSpan -= 70;
 state++;
 CountEvent(_Count ,state);
 StringFormat drawFormat = new StringFormat();
 drawFormat.Alignment = StringAlignment.Center;
 gpPalette.DrawString("\tO(∩_∩)O~\r\n***恭喜过关***\r\n按“下一关”按钮\r\n开始新的远征",
  new Font("Arial Black", 20f),
  new SolidBrush(Color.DodgerBlue ),
  new RectangleF(0, _height * rectPix / 2 - 80, _width * rectPix, 120),
  drawFormat);
 timerBlock.Stop();//关闭计时器
 }
}
public void Pause()//暂停
{
 if (timerBlock.Enabled == true)
 {
 timerBlock.Enabled = false;
 StringFormat drawFormat = new StringFormat();
 drawFormat.Alignment = StringAlignment.Center;
 gpPalette.DrawString("暂停" + "\r\n" + "得分:" + _Count.ToString(),
   new Font("Arial Black", 25f),
   new SolidBrush(Color.Aqua),
   new RectangleF(0, _height * rectPix / 2 - 100, _width * rectPix, 100),
   drawFormat);
 }
}
public void EndPause()//结束暂停
{
 if (timerBlock.Enabled == false)
 {
 timerBlock.Enabled = true;
 PaintBackground(gpPalette);
 }
}
public void Close()//关闭
{
 timerBlock.Close();
 gpPalette.Dispose();//释放画布
 gpReady.Dispose();
}
}
}

2.保存信息数组代码


namespace Tetris
{
class InfoArr
{
private ArrayList info = new ArrayList();//存放多个BlockInfo累得的数组
private int _length = 0;//存放Arraylist的长度,以供访问
public int Length
{
 get
 {
 return _length;
 }
}
public BlockInfo this[int index]//索引器,根据下标,返回一个blockinfo的值
{
 get
 {
 return (BlockInfo)info[index];
 }
}
public string this[string id]//索引器,根据一个字符串的id值下标,给相应id的颜色赋值
{
 set
 {
 if (value == "")
 {
  return;
 }
 for (int i = 0; i < info.Count; i++)
 {
  if (((BlockInfo)info[i]).GetIdStr() == id)
  {
  try
  {
   ((BlockInfo)info[i]).BColor = Color.FromArgb(Convert.ToInt32(value));
  }
  catch (System.FormatException)
  {
   MessageBox.Show("颜色信息错误!请删除BlockSet.xml文件,并重新启动程序,很抱歉给您带来麻烦", "错误信息",
   MessageBoxButtons.OK,
   MessageBoxIcon.Error);
  }
  }
 }
 }
}
public BitArray StrToBit(string id)//把字符串转换为bitArray
{
 if (id.Length != 25)
 {
 throw new System.FormatException("砖块样式信息不合法!请删除BlockSet.xml文件,并重新启动程序");
 }
 BitArray ba = new BitArray(25);
 for (int i = 0; i < 25; i++)
 {
 ba[i] = (id[i] == '0') ? false : true;
 }
 return ba;
}
public void Add(BitArray id, Color bColor)//添加一个砖块信息
{
 if (id.Length != 25)
 {
 throw new System.FormatException("砖块样式信息不合法!请删除blockset.xml文件,并重新启动程序");
 }
 info.Add(new BlockInfo(id, bColor));//给动态数组info添加一个砖块信息
 _length++;//长度加一
}
public void Add(string id, string bColor)

{
 Color temp;
 if (!(bColor == ""))
 {
 temp = Color.FromArgb(Convert.ToInt32(bColor));//把字符串转换为颜色类
 }
 else
 {
 temp = Color.Empty;
 }
 info.Add(new BlockInfo(StrToBit(id), temp));//把字符串转换为bitarray类
 _length++;
}

}
}

3.方块信息代码


namespace Tetris
{
class BlockInfo
{
private BitArray _id;//存放砖块样式
private Color _bColor;//存放颜色信息
public BlockInfo(BitArray id, Color bColor)//构造函数,给似有函数变量赋值
{
 _id = id;
 _bColor = bColor;
}
public BitArray ID
{
 get
 {
 return _id;
 }
 set
 {
 _id = value;
 }

}
public Color BColor
{
 get
 {
 return _bColor;
 }
 set
 {
 _bColor = value;
 }
}
public string GetIdStr()
{
 StringBuilder s = new StringBuilder(25);
 foreach (bool b in _id)
 {
 s.Append(b ? "1" : "0");
 }
 return s.ToString();
}
public string GetColorStr()
{
 return Convert.ToString(_bColor.ToArgb());
}
}
}

4.方块组代码


namespace Tetris
{
class BlockGroup
{
private InfoArr info;//存放所有砖块样式信息
private Color disapperColor;//背景色
private int rectPix;//单元格像素
public BlockGroup()//构造函数
{
 Config config = new Config();
 config.LoadFromXmlFile();
 info = new InfoArr();
 info = config.Info;
 disapperColor = config.BackColor;
 rectPix = config.RectPix;
}
public Block GetABlock()//从砖块组中随机抽取一个砖块样式并返回
{
 Random rd = new Random();//声明一个产生随机数的类
 int keyOrder = rd.Next(0, info.Length);//产生一个随机数
 BitArray ba = info[keyOrder].ID;//把抽取出的砖块样式赋给BitArray类对象ba
 int struNum = 0;//确定这个砖块样式中被填充方块的个数
 foreach (bool b in ba)//需要确定point数组的长度
 {
 if (b)
 {
  struNum++;
 }
 }
 Point[] structArr = new Point[struNum];//新建一个point数组,并确定其长度,以创建新的block
 int k = 0;
 for (int j = 0; j < ba.Length; j++)//用循环给point数组structarr赋坐标值
 {
 if (ba[j])
 {
  structArr[k].X = j / 5 - 2;
  structArr[k].Y = 2 - j % 5;
  k++;
 }
 }
 return new Block(structArr, info[keyOrder].BColor, disapperColor, rectPix);//创建一个新砖块并返回

}
}

5.方块的基本属性代码


namespace Tetris
{
class Block
{
protected Point[] structArr;//存放砖块组成信息的坐标数组
protected int _xPos;//砖块中心点所在的X坐标
protected int _yPos;//砖块中心点所在的y坐标
protected Color _blockColor;//砖块颜色
protected Color disapperColor;//擦除颜色
protected int rectPix;//每单元格像素
public Block()//默认构造函数,声明此构造函数是为了子类能创建
{

}
public Block(Point[] sa, Color bColor, Color dColor, int pix)
{
 //重载构造函数,给成员变量赋值
 _blockColor = bColor;
 disapperColor = dColor;
 rectPix = pix;
 structArr = sa;
}
public Point this[int index]//索引器,根据索引访问砖块里的小方块坐标
{
 get
 {
 return structArr[index];
 }
}
public int Length//属性,表示structArr的长度
{
 get
 {
 return structArr.Length;
 }
}
#region 成员变量相应的属性
public int XPos
{
 get
 {
 return _xPos;
 }
 set
 {
 _xPos = value;
 }
}
public int YPos
{
 get
 {
 return _yPos;
 }
 set
 {
 _yPos = value;
 }
}
public Color BlockColor
{
 get
 {
 return _blockColor;
 }
}
#endregion
public void DeasilRotate()//顺时针旋转
{
 int temp;
 for (int i = 0; i < structArr.Length; i++)
 {
 temp = structArr[i].X;
 structArr[i].X = structArr[i].Y;
 structArr[i].Y = -temp;
 }
}
public void ContraRotate()//逆时针旋转
{
 int temp;
 for (int i = 0; i < structArr.Length; i++)
 {
 temp = structArr[i].X;
 structArr[i].X = -structArr[i].Y;
 structArr[i].Y = temp;
 }
}
private Rectangle PointToRect(Point p)//把坐标点转化为画布的坐标值
{
 return new Rectangle((_xPos + p.X) * rectPix + 1,
 (_yPos - p.Y) * rectPix + 1,
 rectPix - 2,
 rectPix - 2);
}
public virtual void Paint(Graphics gp)//在指定画板下绘制砖块
{
 SolidBrush sb = new SolidBrush(_blockColor );
 foreach (Point p in structArr)
 {
 lock (gp)
 {
  gp.FillRectangle(sb, PointToRect(p));
 }
 }
}
public void erase(Graphics gp)//擦除矩形
{
 SolidBrush sb = new SolidBrush(disapperColor);
 foreach (Point p in structArr)
 {
 lock (gp)
 {
  gp.FillRectangle(sb, PointToRect(p));
 }
 }
}
}
}

6.俄罗斯方块窗体代码


namespace Tetris
{
public partial class FrmTetris : Form
{
public FrmTetris()
{
 InitializeComponent();
 CheckForIllegalCrossThreadCalls = false;
}

private Palette p;
private Keys downKey;
private Keys dropKey;
private Keys moveLeftKey;
private Keys moveRightKey;
private Keys deasilRotateKey;
private Keys contraRotateKey;
private int paletteWidth;
private int paletteHeight;
private Color paletteColor;
private int rectPix;

private void btnStart_Click(object sender, EventArgs e)
{
 lblState.Text = "等级:1";
 lblcount.Text = "得分:0";
 if (p != null)
 {
 p.Close();
 }
 p = new Palette(paletteWidth, paletteHeight, rectPix, paletteColor,
 Graphics.FromHwnd(pbRun.Handle),
 Graphics.FromHwnd(lblReady.Handle));
 p.CountEvent += new Palette.IniCountHandle(p_CountEvent);
 p.Start();
}
void p_CountEvent(int _count,int state)
{
 lblcount.Text = "得分:"+_count.ToString();
 lblState.Text = "等级:" + state.ToString();
}
private void pbRun_Paint(object sender, PaintEventArgs e)
{
 if (p != null)
 {
 p.PaintPalette(e.Graphics);
 }
}

private void lblReady_Paint(object sender, PaintEventArgs e)
{
 if (p != null)
 {
 p.PaintReady(e.Graphics);
 }
}

private void FrmTetris_Load(object sender, EventArgs e)
{
 //读取xml文件中的参数配置信息,并依次赋给似有成员变量
 Config config = new Config();
 config.LoadFromXmlFile();
 downKey = config.DownKey;
 dropKey = config.DropKey;
 moveLeftKey = config.MoveLeftKey;
 moveRightKey = config.MoveRightKey;
 deasilRotateKey = config.DeasilRotateKey;
 contraRotateKey = config.ContraRotateKey;
 paletteWidth = config.CoorWidth;
 paletteHeight = config.CoorHeight;
 paletteColor = config.BackColor;
 rectPix = config.RectPix;
 //根据画板的长度和宽度信息动态改变窗体及画板的规格
 this.Width = paletteWidth * rectPix + 215;
 this.Height = paletteHeight * rectPix + 38;
 pbRun.Width = paletteWidth * rectPix;
 pbRun.Height = paletteHeight * rectPix;

}

private void FrmTetris_KeyDown(object sender, KeyEventArgs e)
{
 if (e.KeyValue == 32)//屏蔽回车键
 {
 e.Handled = true;
 }
 if (e.KeyCode == downKey)//下降
 {
 p.Down();
 }
 else if (e.KeyCode == dropKey)
 {
 p.Drop();
 }
 else if (e.KeyCode == moveLeftKey)
 {
 p.MoveLeft();
 }
 else if (e.KeyCode == moveRightKey)
 {
 p.MoveRight();
 }
 else if (e.KeyCode == deasilRotateKey)
 {
 p.DeasilRotate();
 }
 else if (e.KeyCode == contraRotateKey)
 {
 p.ContraRotate();
 }
}

private void btnPause_Click(object sender, EventArgs e)
{
 if (p == null)
 {
 return;
 }
 if (btnPause.Text == "暂停")
 {
 p.Pause();
 btnPause.Text = "继续";
 }
 else
 {
 p.EndPause();
 btnPause.Text = "暂停";
 }

}

private void btnConfig_Click(object sender, EventArgs e)
{
 if (btnPause.Text == "暂停")
 {
 btnPause.PerformClick();
 }
 using (Frmconfig frmconfig= new Frmconfig())
 {
 frmconfig.ShowDialog();
 }
}

private void FrmTetris_FormClosing(object sender, FormClosingEventArgs e)
{
 if (p !=null )
 {
 p.Close ();
 }
}

private void button5_Click(object sender, EventArgs e)
{
 p.Down();
}

private void button1_Click(object sender, EventArgs e)
{
 p.MoveLeft();
}

private void button2_Click(object sender, EventArgs e)
{
 p.MoveRight();
}

private void button3_Click(object sender, EventArgs e)
{
 p.DeasilRotate();
}

private void button4_Click(object sender, EventArgs e)
{
 p.ContraRotate();
}

private void button6_Click(object sender, EventArgs e)
{
 p.Drop();
}

private void button7_Click(object sender, EventArgs e)
{
 OpenFileDialog ofDialog = new OpenFileDialog();
 ofDialog.AddExtension = true;
 ofDialog.CheckFileExists = true;
 ofDialog.CheckPathExists = true;

//the next sentence must be in single line
 ofDialog.Filter = "MP3文件(*.mp3)|*.mp3|Audio文件(*.avi)|*.avi|VCD文件(*.dat)|*.dat|WAV文件(*.wav)|*.wav|所有文件 (*.*)|*.*";
 ofDialog.DefaultExt = "*.mp3";
 if (ofDialog.ShowDialog() == DialogResult.OK)
 {
 this.axWindowsMediaPlayer1.URL = ofDialog.FileName;
 }
}

private void timer1_Tick(object sender, EventArgs e)
{
 DateTime dt = DateTime.Now; //当前时间的实例;
 lbltime.Text = dt.ToString(); //转为string类型 把值交给lbltime的Text属性;
}

private void button8_Click(object sender, EventArgs e)
{

p.CountEvent += new Palette.IniCountHandle(p_CountEvent);
 p.nextstate();
}

}
}

7.游戏设置窗体代码


namespace Tetris
{
public partial class Frmconfig : Form
{
public Frmconfig()
{
 InitializeComponent();
}
private bool[,] struArr = new bool[5, 5];
private Color blockColor = Color.Red;
private void lblMode_Paint(object sender, PaintEventArgs e)
{
 Graphics gp = e.Graphics;
 gp.Clear(Color.Black);
 Pen p = new Pen(Color.White);
 for (int i = 31; i < 155; i = i + 31)
 gp.DrawLine(p, 1, i, 155, i);
 for (int i = 31; i < 155; i = i + 31)
 gp.DrawLine(p, i, 1, i, 155);
 //填充颜色
 SolidBrush s = new SolidBrush(blockColor);
 for (int x = 0; x < 5; x++)
 {
 for (int y = 0; y < 5; y++)
 {
  if (struArr[x, y])
  {
  gp.FillRectangle(s, 31 * x + 1, 31 * y + 1, 30, 30);
  }
 }
 }

}

private void lblMode_MouseClick(object sender, MouseEventArgs e)
{
 if (e.Button != MouseButtons.Left)
 return;
 int xPos, yPos;
 xPos = e.X / 31;
 yPos = e.Y / 31;
 struArr[xPos, yPos] = !struArr[xPos, yPos];
 bool b = struArr[xPos, yPos];
 Graphics gp = lblMode.CreateGraphics();
 SolidBrush s = new SolidBrush(b ? blockColor : Color.Black);
 gp.FillRectangle(s, 31 * xPos + 1, 31 * yPos + 1, 30, 30);
 gp.Dispose();
}
}
}

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

java经典小游戏汇总

javascript经典小游戏汇总

来源:https://blog.csdn.net/qq_37344688/article/details/109937677

标签:C#,俄罗斯方块
0
投稿

猜你喜欢

  • C#多线程学习之(四)使用线程池进行多线程的自动管理

    2021-07-17 10:04:43
  • C#中timer定时器用法实例

    2023-01-23 02:23:17
  • ELK搭建线上日志收集系统

    2021-11-01 17:34:41
  • SpringBoot 如何编写配置文件

    2023-07-14 10:38:24
  • 浅谈Java 中的引用类型

    2023-07-25 16:33:38
  • Java解决约瑟夫问题代码实例

    2023-09-20 19:17:02
  • java如何删除以逗号隔开的字符串中某一个值

    2023-06-12 11:59:19
  • SpringBoot深入探究@Conditional条件装配的使用

    2021-08-18 00:06:53
  • Toolbar制作菜单条过程详解

    2022-11-29 04:13:59
  • 简单记事本java源码实例

    2023-11-26 02:03:17
  • Android Retrofit 2.0框架上传图片解决方案

    2022-02-23 06:25:27
  • 浅谈Spring6中的反射机制

    2022-06-04 13:23:33
  • 详解C#如何读写config配置文件

    2023-09-23 01:18:34
  • C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

    2023-03-28 14:49:53
  • spring cloud Ribbon用法及原理解析

    2021-11-28 15:27:21
  • 详解使用Spring Boot开发Restful程序

    2023-01-24 09:20:09
  • Android重要控件SnackBar使用方法详解

    2022-11-10 04:49:41
  • Flutter如何轻松实现动态更新ListView浅析

    2023-05-23 09:32:37
  • 详解C# 不能用于文件名的字符

    2023-03-05 07:44:45
  • Android如何实现一个DocumentProvider示例详解

    2022-12-30 20:10:13
  • asp之家 软件编程 m.aspxhome.com