逐步讲解用C#实现俄罗斯方块之核心代码[完结篇]

来源:互联网 发布:matlab用数据拟合函数 编辑:程序博客网 时间:2024/05/17 04:14
这里先给出shape类的所有代码
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Text;

namespace Fang
{
    
public class sharp
    
{
        
//用于记录分数
        
//用于记录已经触底的图像
        protected PictureBox[] oldpb=new PictureBox[1000];
        
//用于控制移动中的图像
        public PictureBox[] pb = new PictureBox[4];
        
//图像的初始化位置
        private int initX = 100;
        
private int initY = 10;

        
//构造函数[参数用于制定控件添加到什么窗口]
        public sharp(Form f)
        
{
            newObj(f);
        }


        
//用于给定时器调用 向下移动
        public void moveDown(Form f)
        
{
            
for (int i = 0; i < 4; i++)
            
{
                
//向下移动
                pb[i].Location = new Point(pb[i].Location.X, pb[i].Location.Y + 10);
            }

            
//调用check来判断是否到底 
            if (check(f))
            
{
                
//到底着构建新图像
                makeNew();
            }

        }


        
//用于旋转图形
        public void Roll()
        
{
           
            
int Sx = pb[2].Location.X - pb[0].Location.X;
            
int Sy = pb[2].Location.Y - pb[0].Location.Y;
            
//根据计算
            if         (Sx >= 0 && Sy < 0) Rollx(-1,-1);
            
else if (Sx < 0 && Sy <= 0) Rollx(-1,1); 
            
else if (Sx <= 0 && Sy > 0) Rollx(1,1);
            
else if (Sx > 0 && Sy >= 0) Rollx(1,-1);
        }


        
//ROllX()由下面的4个方法综合而成

        
////四个象限的旋转方法
        //private void Roll1()//在第一象限转第二象限
        
// {
        
//     for (int i = 1; i < 4; i++)
        
//     {
        
//         int x = System.Math.Abs(pb[0].Location.X - pb[i].Location.X);
        
//         int y = System.Math.Abs(pb[0].Location.Y - pb[i].Location.Y);
        
//         pb[i].Location = new Point(pb[0].Location.X - y, pb[0].Location.Y - x);
        
//     }
        
//     //如果坐标越界就进行反旋转
        
//     if (pb[0].Location.X > 200 || pb[1].Location.X > 200 || pb[2].Location.X > 200 || pb[3].Location.X > 200) Roll4();
        
//     if (pb[0].Location.X < 0 || pb[1].Location.X < 0 || pb[2].Location.X < 0 || pb[3].Location.X < 0) Roll4();
        
// }
        
// private void Roll2()//在2转3
        
// {
        
//     for (int i = 1; i < 4; i++)
        
//     {
        
//         int x = System.Math.Abs(pb[0].Location.X - pb[i].Location.X);
        
//         int y = System.Math.Abs(pb[0].Location.Y - pb[i].Location.Y);
        
//         pb[i].Location = new Point(pb[0].Location.X - y, pb[0].Location.Y + x);
        
//     }
        
//     //如果坐标越界就进行反旋转
        
//     if (pb[0].Location.X < 0 || pb[1].Location.X < 0 || pb[2].Location.X < 0 || pb[3].Location.X < 0) Roll1();
        
//     if (pb[0].Location.X > 200 || pb[1].Location.X > 200 || pb[2].Location.X > 200 || pb[3].Location.X > 200) Roll1();
        
// }
        
// private void Roll3()//在3转4
        
// {
        
//     for (int i = 1; i < 4; i++)
        
//     {
        
//         int x = System.Math.Abs(pb[0].Location.X - pb[i].Location.X);
        
//         int y = System.Math.Abs(pb[0].Location.Y - pb[i].Location.Y);
        
//         pb[i].Location = new Point(pb[0].Location.X + y, pb[0].Location.Y + x);
        
//     }
        
//     //如果坐标越界就进行反旋转
        
//     if (pb[0].Location.X < 0 || pb[1].Location.X < 0 || pb[2].Location.X < 0 || pb[3].Location.X < 0) Roll2();
        
//     if (pb[0].Location.X > 200 || pb[1].Location.X > 200 || pb[2].Location.X > 200 || pb[3].Location.X > 200) Roll2();
        
// }
        
// private void Roll4()//在4转1
        
// {
        
//     for (int i = 1; i < 4; i++)
        
//     {
        
//         int x = System.Math.Abs(pb[0].Location.X - pb[i].Location.X);
        
//         int y = System.Math.Abs(pb[0].Location.Y - pb[i].Location.Y);
        
//         pb[i].Location = new Point(pb[0].Location.X + y, pb[0].Location.Y - x);
        
//     }
        
//     //如果坐标越界就进行反旋转
        
//     if (pb[0].Location.X > 200 || pb[1].Location.X > 200 || pb[2].Location.X > 200 || pb[3].Location.X > 200) Roll3();
        
//     if (pb[0].Location.X < 0 || pb[1].Location.X < 0 || pb[2].Location.X < 0 || pb[3].Location.X < 0) Roll3();
        
// }

        
//检查是否到底 到底则进行转换
        private void Rollx(int a,int b)
        
{
            
bool flag=true;
            PictureBox[] tmpPB
=new PictureBox[4];
            
for(int i=0;i<4;i++)
            
{
                tmpPB[i]
=new PictureBox();
                
int x = System.Math.Abs(pb[0].Location.X - pb[i].Location.X);
                
int y = System.Math.Abs(pb[0].Location.Y - pb[i].Location.Y);
                tmpPB[i].Location 
= new Point(pb[0].Location.X +a* y, pb[0].Location.Y +b*x);
                
if (!checkPes(tmpPB[i].Location)) flag = false;
            }

            
if (flag)
            
{
                
for (int i = 0; i < 4; i++)
                
{
                    
int x = System.Math.Abs(pb[0].Location.X - pb[i].Location.X);
                    
int y = System.Math.Abs(pb[0].Location.Y - pb[i].Location.Y);
                    pb[i].Location 
= new Point(pb[0].Location.X + a * y, pb[0].Location.Y + b * x);
                }

            }

        }


        
public bool check(Form f)
        
{
            
for(int i=0;i<4;i++)
            
{
                
if (pb[i].Location.Y > 500)
                
{
                    
//任一一个图像到底则整个图像进行转换
                    changToOld(f);
                    
return true;
                }

                
//判断该图像所对应的位置的下方是否有已经触底的图形
                int x = pb[i].Location.X;
                
int y = pb[i].Location.Y;
                
if ((y - 20* 20 + x - 10 > 0 && oldpb[(y - 20/ 10 * 20 + (x - 10/ 10 + 20!= null)
                
{
                    
//任一一个图像到底则整个图像进行转换
                    changToOld(f);
                    
return true;
                }

            }

            
return false;
        }


        
//此方法用于将图形转换为触底图形
        private void changToOld(Form f)
        
{
            
for (int i = 0; i < 4; i++)
            
{
                
int x = pb[i].Location.X;
                
int y = pb[i].Location.Y;
                
if (pb[0].Location.Y > 10 && pb[1].Location.Y > 10 && pb[2].Location.Y > 10 && pb[3].Location.Y > 10)
                
{
                    
//将图形"copy"到触底图形组
                    oldpb[(y - 20/ 10 * 20 + (x - 10/ 10= pb[i];
                }

            }

            
//检查finish-用于检查一排是否已经排满
            finish();
            
//生成新移动图形组
            newObj(f);
        }


        
public void sharp_0()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
1].Location = new Point(initX, initY - 10);
            pb[
2].Location = new Point(initX + 10, initY - 10);
            pb[
3].Location = new Point(initX + 10, initY );
        }

        
public void sharp_1()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
1].Location = new Point(initX, initY - 10);
            pb[
2].Location = new Point(initX, initY - 20);
            pb[
3].Location = new Point(initX, initY - 30);
        }

        
public void sharp_2()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
1].Location = new Point(initX, initY - 10);
            pb[
2].Location = new Point(initX-10, initY - 10);
            pb[
3].Location = new Point(initX-20, initY - 10);
        }

        
public void sharp_3()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
1].Location = new Point(initX, initY - 10);
            pb[
2].Location = new Point(initX + 10, initY - 10);
            pb[
3].Location = new Point(initX + 20, initY - 10);
        }

        
public void sharp_4()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
1].Location = new Point(initX+10, initY - 10);
            pb[
2].Location = new Point(initX + 10, initY );
            pb[
3].Location = new Point(initX + 20, initY);
        }

        
public void sharp_5()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
2].Location = new Point(initX + 10, initY);
            pb[
1].Location = new Point(initX+10, initY + 10);
            pb[
3].Location = new Point(initX +20, initY + 10);
        }

        
public void sharp_6()
        
{
            pb[
0].Location = new Point(initX, initY);
            pb[
1].Location = new Point(initX+10, initY );
            pb[
2].Location = new Point(initX + 10, initY - 10);
            pb[
3].Location = new Point(initX + 20, initY - 10);
        }


        
//生成新图形样式
        public void makeNew()
        
{
            Random r 
= new Random();
            
int ran = r.Next(6);
            
switch (ran)
            
{
                
case 0:
                    sharp_0();
                    
break;
                
case 1:
                    sharp_1();
                    
break;
                
case 2:
                    sharp_2();
                    
break;
                
case 3:
                    sharp_3();
                    
break;
                
case 4:
                    sharp_4();
                    
break;
                
case 5:
                    sharp_5();
                    
break;
                
case 6:
                    sharp_6();
                    
break;
            }

        }


        
//用于新实例化移动图形组
        public void newObj(Form f)
        
{
            
for (int i = 0; i < 4; i++)
            
{
                
//重新实例化模型
                
//实例化
                this.pb[i] = new System.Windows.Forms.PictureBox();
                
//设置大小
                this.pb[i].Size = new System.Drawing.Size(1010);
                
//设置图片
                this.pb[i].Image = global::Fang.Properties.Resources.fang;
                
//添加到窗口
                f.Controls.Add(pb[i]);
            }

        }


        
//检查一行是否排满
        public void finish()
        
{
            
//对4个移动图形组的成员进行遍历判断
            for (int i = 0; i < 4; i++)
            
{
                
//求出当前组件所在的行(游戏里面的行)
                int y = (pb[i].Location.Y - 20/ 10;
                
if(y>1)
                
{
                    
if (CheckLine(y))
                    
{
                        
//消除y所在的行
                        ClareLine(y);
                    }

                }

            }

        }

        
//检查是否排满 是则返回true
        private bool CheckLine(int y)
        
{
           
// MessageBox.Show(y + "," + (y - 1));
            for (int i = 0; i < 20; i++)
            
{
                
if(oldpb[20*y+i]==null)
                    
return false;
            }

            
return true;
        }


        
//消除制定行并将上面的都向下移动
        public void ClareLine(int y)
        
{
            flash(y);
            
//消除模型
            for (int i = 0; i < 20; i++)
            
{
                oldpb[
20 * y + i].Dispose();
            }


            
//消除数组记录
            for(int i=y*20+19;i>=20;i--)
            
{
                oldpb[i]
=oldpb[i-20];
                
if (oldpb[i] != null
                    oldpb[i].Location 
= new Point(oldpb[i].Location.X, oldpb[i].Location.Y + 10);
            }

            
//最上面一行置为空
            for (int i = 0; i < 20; i++)
            
{
                oldpb[i]
=null;
            }

        }


        
// 向左移动的方法
        public void movLeft()
        
{
            
bool flag=true;
            
//执行向左移动
            PictureBox[] tmpPB = new PictureBox[4];
            
//生成移动后的状态为tmpPB用于检测
            for (int i = 0; i < 4; i++)
            
{
                
                tmpPB[i] 
= new PictureBox();
                tmpPB[i].Location 
= new Point(pb[i].Location.X - 10, pb[i].Location.Y);
                
if (!checkPes(tmpPB[i].Location)) flag = false;
            }

            
//先检查后移动
            if (flag)
            
{
                
for (int i = 0; i < 4; i++)
                
{
                    pb[i].Location 
= new Point(pb[i].Location.X - 10,pb[i].Location.Y);
                }

            }

        }

        
//向右移动的方法
        public void movRigth()
        
{
            
bool flag = true;
            
//执行向左]右移动
            PictureBox[] tmpPB = new PictureBox[4];
            
//生成移动后的状态为tmpPB用于检测
            for (int i = 0; i < 4; i++)
            
{

                tmpPB[i] 
= new PictureBox();
                tmpPB[i].Location 
= new Point(pb[i].Location.X + 10, pb[i].Location.Y);
                
if (!checkPes(tmpPB[i].Location)) flag = false;
            }

            
//先检查后移动
            if (flag)
            
{
                
for (int i = 0; i < 4; i++)
                
{
                    pb[i].Location 
= new Point(pb[i].Location.X + 10, pb[i].Location.Y);
                }

            }

        }


        
//用于检查方块单元的位置是否合法
        private bool checkPes(Point p)
        
{
            
int x=p.X;
            
int y=p.Y;
            
//检查坐标是否越界
            if (p.X < 10 || p.X > 200return false;
            
//检查是否重叠
            if (pb[0].Location.Y > 10 && pb[1].Location.Y > 10 && pb[2].Location.Y > 10 && pb[3].Location.Y > 10&&y>20)
            
{
                
if (oldpb[(y - 20/ 10 * 20 + (x - 10/ 10!= nullreturn false;
            }

            
return true;
        }


        
public void flash(int y)
        
{
            
//闪烁
            int tmpy = y - 1;
            
for (int j = 0; j < 2; j++)
            
{
                
for (int i = 0; i < 20; i++)
                
{
                    oldpb[
20 * y + i].Hide();
                }

                System.Threading.Thread.Sleep(
100);
                
for (int i = 0; i < 20; i++)
                
{
                    oldpb[
20 * y + i].Show();
                }

                System.Threading.Thread.Sleep(
200);
                
for (int i = 0; i < 20; i++)
                
{
                    oldpb[
20 * y + i].Hide();
                }

                System.Threading.Thread.Sleep(
100);
                
for (int i = 0; i < 20; i++)
                
{
                    oldpb[
20 * y + i].Show();
                }

                System.Threading.Thread.Sleep(
200);
            }

        }


        
//--在上面追加方法
        
//------------------------------------
    }

}

 下面我们来在c#中使用这个类,在原理的新建的窗口中拖放一个Timer来控制方块移动窗口类的代码-
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Fang
{
    
public partial class Form1 : Form
    
{
        
private sharp obj;
        
public Form1()
        
{
            InitializeComponent();
        }

        
private void Form1_Load(object sender, EventArgs e)
        
{
            obj 
=new sharp(this);
            obj.makeNew();
            
//obj.sharp_show(this);
        }


        
private void Form1_KeyDown(object sender, KeyEventArgs e)
        
{
            
switch (Convert.ToInt32(e.KeyValue))
            
{
                
case 38://上-旋转
                    obj.Roll();
                    
break;
                
case 39://向右
                    obj.movRigth();
                    
break;
                
case 37://向左
                    obj.movLeft();
                    
break;
                
case 40://下-加速
                    obj.moveDown(this);
                    
break;
            }

        }


        
private void timMove_Tick(object sender, EventArgs e)
        
{
            obj.moveDown(
this);
        }

    }

}

对的你没有看错就是这么少,一共三个方法,一共是form_load()在加载窗口时实例化shape类 key_down()响键盘事件timMove_Tick是控件Timer[timMove]的事件触发事件
至此程序全部完成 ...如果要索要项目完全文件联系zmoxga@sina.com

原创粉丝点击