C#实现俄罗斯方块基本功能
更新时间:2020年6月25日 10:35 点击:2119
本文实例为大家分享了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#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25