C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#俄罗斯方块

C#实现俄罗斯方块基本功能

作者:717606641

这篇文章主要为大家详细介绍了C#实现俄罗斯方块的基本功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
 
namespace 俄罗斯方块
{
 public partial class MainForm : Form
 {
 public MainForm()
 {
  InitializeComponent();
 }
 PictureBox pb;
 const int w = 10;
 const int h = 20;
 const int a = 40;
 int speed = 400;
 int marks = 0;
 bool gameoverflag = false;
 int[,] p = new int[w, h];
 int[,] c = new int[w, h];
 int[,] c_old = new int[w, h];
 Timer timer;
 
 void MainForm_Load(object sender, EventArgs e)
 {
  this.StartPosition = FormStartPosition.CenterScreen;
  this.AutoSize = true;
  this.MaximizeBox = false;
  this.FormBorderStyle = FormBorderStyle.FixedSingle;
  pb = new PictureBox();
  pb.Margin = new Padding(0, 0, 0, 0);
  pb.Width = w * a;
  pb.Height = h * a;
  pb.Location = new Point(0, 0);
  pb.BackColor = Color.LightGray;
  this.Controls.Add(pb);
  this.KeyDown += new KeyEventHandler(MainForm_KeyDown);
  this.KeyUp += new KeyEventHandler(MainForm_KeyUp);
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   p[i, j] = 0;
  }
  }
  c = make_diamond(0);
  c_old = make_emptydiamond();
  timer = new Timer();
  timer.Interval = speed;
  timer.Tick += new EventHandler(timer_Tick);
  draw();
 }
 
 void timer_Tick(object sender, EventArgs e)
 {
  if(isequal(c, c_old))
  {
  p = add_p_c(c);
  int[] l_temp = detect_fullline();
  int lines = 0;
  for(int i = 0; i < h; i++)
  {
   if(l_temp[i] == 1)
   {
   lines++;
   }
  }
  marks += lines * lines;
  p = clear_fullline();
  if(isgameover())
  {
   timer.Enabled = false;
   gameoverflag = true;
   MessageBox.Show("Game Over!");
   return;
  }
  c = make_diamond(0);
  c_old = make_emptydiamond();
  }
  else if(isequal(c, move_down()))
  {
  c_old = c;
  }
  else if(!isequal(c, move_down()))
  {
  c = move_down();
  }
  draw();
  this.Text = "俄罗斯方块 得分:" + marks.ToString();
 }
 
 int[,] make_diamond(int n)
 {
  int[,] c_temp = new int[w, h];
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   c_temp[i, j] = 0;
  }
  }
  switch (n)
  {
  case 0:
   int seed = (int)DateTime.Now.Millisecond;
   Random rd = new Random(seed);
   return make_diamond(rd.Next(1, 25));
  case 1:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[0, 2] = 1;
   c_temp[0, 3] = 1;
   break;
  case 2:
   c_temp[0, 0] = 1;
   c_temp[1, 0] = 1;
   c_temp[2, 0] = 1;
   c_temp[3, 0] = 1;
   break;
  case 3:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 1] = 1;
   c_temp[1, 2] = 1;
   break;
  case 4:
   c_temp[1, 0] = 1;
   c_temp[2, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 1] = 1;
   break;
  case 5:
   c_temp[0, 1] = 1;
   c_temp[0, 2] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   break;
  case 6:
   c_temp[0, 0] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   c_temp[2, 1] = 1;
   break;
  case 7:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[0, 2] = 1;
   c_temp[1, 1] = 1;
   break;
  case 8:
   c_temp[0, 0] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   c_temp[2, 0] = 1;
   break;
  case 9:
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   c_temp[1, 2] = 1;
   break;
  case 10:
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   c_temp[2, 1] = 1;
   break;
  case 11:
   c_temp[0, 0] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   c_temp[1, 2] = 1;
   break;
  case 12:
   c_temp[0, 1] = 1;
   c_temp[1, 1] = 1;
   c_temp[2, 0] = 1;
   c_temp[2, 1] = 1;
   break;
  case 13:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[0, 2] = 1;
   c_temp[1, 2] = 1;
   break;
  case 14:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[2, 0] = 1;
   break;
  case 15:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[0, 2] = 1;
   c_temp[1, 0] = 1;
   break;
  case 16:
   c_temp[0, 0] = 1;
   c_temp[1, 0] = 1;
   c_temp[2, 0] = 1;
   c_temp[2, 1] = 1;
   break;
  case 17:
   c_temp[0, 2] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   c_temp[1, 2] = 1;
   break;
  case 18:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 1] = 1;
   c_temp[2, 1] = 1;
   break;
  case 19:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   break;
  case 20:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   break;
  case 21:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   break;
  case 22:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[1, 0] = 1;
   c_temp[1, 1] = 1;
   break;
  case 23:
   c_temp[0, 0] = 1;
   c_temp[0, 1] = 1;
   c_temp[0, 2] = 1;
   c_temp[0, 3] = 1;
   break;
  case 24:
   c_temp[0, 0] = 1;
   c_temp[1, 0] = 1;
   c_temp[2, 0] = 1;
   c_temp[3, 0] = 1;
   break;
  }
  return c_temp;
 }
 
 int[,] add_p_c(int[,] c_temp)
 {
  int[,] p_temp = new int[w, h];
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   p_temp[i, j] = p[i, j] + c_temp[i, j];
  }
  }
  return p_temp;
 }
 
 int[] detect_border()
 {
  int i_min = w;
  int i_max = -1;
  int j_min = h;
  int j_max = -1;
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   if(c[i, j] != 0)
   {
   i_min = i;
   break;
   }
  }
  if(i_min != w)
  {
   break;
  }
  }
  for(int i = w - 1; i >= 0; i--)
  {
  for(int j = 0; j < h; j++)
  {
   if(c[i, j] != 0)
   {
   i_max = i;
   break;
   }
  }
  if(i_max != -1)
  {
   break;
  }
  }
  for(int j = 0; j < h; j++)
  {
  for(int i = 0; i < w; i++)
  {
   if(c[i, j] != 0)
   {
   j_min = j;
   break;
   }
  }
  if(j_min != h)
  {
   break;
  }
  }
  for(int j = h - 1; j >= 0; j--)
  {
  for(int i = 0; i < w; i++)
  {
   if(c[i, j] != 0)
   {
   j_max = j;
   break;
   }
  }
  if(j_max != -1)
  {
   break;
  }
  }
  int[] border = {j_min, j_max, i_min, i_max};//上下左右边界
  return border;
 }
 
 bool overlap(int[,] c_temp)
 {
  bool bl = false;
  int[,] p_temp = add_p_c(c_temp);
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   if(p_temp[i, j] > 1)
   {
   return true;
   }
  }
  }
  return bl;
 }
 
 int[,] make_emptydiamond()
 {
  int[,] c_temp = new int[w, h];
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   c_temp[i, j] = 0;
  }
  }
  return c_temp;
 }
 
 bool isempty(int[,] c_temp)
 {
  bool bl = true;
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   if(c_temp[i, j] > 0)
   {
   return false;
   }
  }
  } 
  return bl;
 }
 
 bool isequal(int[,] c1, int[,] c2)
 {
  bool bl = true;
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   if(c1[i, j] != c2[i, j])
   {
   return false;
   }
  }
  }
  return bl;
 }
 
 int[] detect_fullline()
 {
  int[] l = new int[h];
  for(int i = 0; i < h; i++)
  {
  l[i] = 1;
  }
  for(int j = 0; j < h; j ++)
  {
  for(int i = 0; i < w; i++)
  {
   if(p[i, j] == 0)
   {
   l[j] = 0;
   break;
   }
  }
  }
  return l;
 }
 
 int[,] clear_fullline()
 {
  int[,] p_temp = make_emptydiamond();
  int flag = h - 1;
  int[] l = detect_fullline();
  for(int i = h - 1; i >= 0; i--)
  {
  if(l[i] == 0)
  {
   for(int j = 0; j < w; j++)
   {
   p_temp[j, flag] = p[j, i];
   }
   flag--;
  }
  }
  return p_temp;
 }
 
 bool isgameover()
 {
  bool bl = false;
  for(int i = 0; i < w; i++)
  {
  if(p[i, 0] > 0)
  {
   return true;
  }
  }
  return bl;
 }
 
 int[,] turn()
 {
  int[,] c_temp = make_emptydiamond();
  int[] border_temp = detect_border();
  int u = border_temp[0];
  int d = border_temp[1];
  int l = border_temp[2];
  int r = border_temp[3];
  if(!(w - 1 - l < d - u || h - 1 - u < r - l))
  {
  if(r - l == 1 && d - u == 1)
  {
   return c;
  }
  else if(r - l == 3)
  {
   c_temp[l, u] = c[l, u];
   c_temp[l, u + 1] = c[l + 1, u];
   c_temp[l, u + 2] = c[l + 2, u];
   c_temp[l, u + 3] = c[l + 3, u];
  }
  else if(d - u == 3)
  {
   c_temp[l, u] = c[l, u];
   c_temp[l + 1, u] = c[l, u + 1];
   c_temp[l + 2, u] = c[l, u + 2];
   c_temp[l + 3, u] = c[l, u + 3];
  }
  else if(r - l == 2)
  {
   c_temp[l, u] = c[l, u + 1];
   c_temp[l + 1, u] = c[l, u];
   c_temp[l, u + 1] = c[l + 1, u + 1];
   c_temp[l + 1, u + 1] = c[l + 1, u];
   c_temp[l, u + 2] = c[l + 2, u + 1];
   c_temp[l + 1, u + 2] = c[l + 2, u];
  }
  else if(d - u == 2)
  {
   c_temp[l, u] = c[l, u + 2];
   c_temp[l + 1, u] = c[l, u + 1];
   c_temp[l + 2, u] = c[l, u];
   c_temp[l, u + 1] = c[l + 1, u + 2];
   c_temp[l + 1, u + 1] = c[l + 1, u + 1];
   c_temp[l + 2, u + 1] = c[l + 1, u];
  }
  }
  if(overlap(c_temp) || isempty(c_temp))
  {
  return c;
  }
  return c_temp;
 }
 
 int[,] move_down()
 {
  int[,] c_temp = make_emptydiamond();
  if(!(detect_border()[1] == h - 1))
  {
  for (int i = 0; i < w; i++)
        {
          for (int j = 1; j < h; j++)
          {
            c_temp[i, j] = c[i, j - 1];
          }
        }
  }
  if(overlap(c_temp) || isempty(c_temp))
  {
  return c;
  }
  return c_temp;
 }
 
 int[,] move_left()
 {
  int[,] c_temp = make_emptydiamond();
  if(!(detect_border()[2] == 0))
  {
  for (int j = 0; j < h; j++)
        {
          for (int i = 0; i < w - 1; i++)
          {
            c_temp[i, j] = c[i + 1, j];
          }
        }
  }
  if(overlap(c_temp) || isempty(c_temp))
  {
  return c;
  }
  return c_temp;
 }
 
 int[,] move_right()
 {
  int[,] c_temp = make_emptydiamond();
  if(!(detect_border()[3] == w - 1))
  {
  for (int j = 0; j < h; j++)
        {
          for (int i = 1; i < w; i++)
          {
            c_temp[i, j] = c[i - 1, j];
          }
        }
  }
  if(overlap(c_temp) || isempty(c_temp))
  {
  return c;
  }
  return c_temp;
 }
 
 void draw()
 {
  int[,] p_temp = add_p_c(c);
  Bitmap bmp = new Bitmap(pb.Width, pb.Height);
  Graphics g = Graphics.FromImage(bmp);
  g.FillRectangle(new SolidBrush(pb.BackColor), new Rectangle(0, 0, pb.Width, pb.Height));
  for(int i = 1; i < w; i++)
  {
  g.DrawLine(new Pen(Color.Black, 1), i * a, 0, i * a, h * a);
  }
  for(int j = 1; j < h; j++)
  {
  g.DrawLine(new Pen(Color.Black, 1), 0, j * a, w * a, j * a);
  }
  for(int i = 0; i < w; i++)
  {
  for(int j = 0; j < h; j++)
  {
   switch(p_temp[i, j])
   {
   case 1:
    g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(a * i, a * j, a, a));
    break;
   default:
    break;
   }
  }
  }
  pb.Image = bmp;
  GC.Collect();
 }
 
 void MainForm_KeyDown(object sender, KeyEventArgs e)
 {
  if(gameoverflag)
  {
  return;
  }
  switch (e.KeyData)
  {
  case Keys.W:
   c = turn();
   break;
  case Keys.Up:
   c = turn();
   break;
  case Keys.S:
   timer.Interval = speed / 10;
   break;
  case Keys.Down:
   timer.Interval = speed / 10;
   break;
  case Keys.A:
   c = move_left();
   break;
  case Keys.Left:
   c = move_left();
   break;
  case Keys.D:
   c = move_right();
   break;
  case Keys.Right:
   c = move_right();
   break;
  case Keys.Space:
   timer.Enabled = timer.Enabled == false ? true : false;
   break;
  default:
   break;
  }
  draw();
 }
 
 void MainForm_KeyUp(object sender, KeyEventArgs e)
 {
  if(e.KeyData == Keys.S || e.KeyData == Keys.Down)
  {
  timer.Interval = speed;
  }
 }
 }
}

很短点的一段代码,实现了俄罗斯方块的基本功能,可以很方便的修改和扩展。

更多俄罗斯方块精彩文章请点击专题:俄罗斯方块游戏集合 进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文