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

回到顶部