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;
}
}
}
}
很短点的一段代码,实现了俄罗斯方块的基本功能,可以很方便的修改和扩展。
更多俄罗斯方块精彩文章请点击专题:俄罗斯方块游戏集合 进行学习。
以上是 C#实现俄罗斯方块基本功能 的全部内容, 来源链接: utcz.com/z/336016.html