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

Cytheria ·
更新时间:2024-09-21
· 807 次阅读

本文实例为大家分享了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#实现简单俄罗斯方块基于C#实现俄罗斯方块游戏



C# 俄罗斯方块

需要 登录 后方可回复, 如果你还没有账号请 注册新账号