俄罗斯方块

大学时候做绘图和键盘练习的例子,俄罗斯方块游戏,分享出来给winform学习。

下载链接:
https://download.csdn.net/download/zhanglianzhu_91/11055683
在这里插入图片描述

示例代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Text;

namespace RussianGrid
{
    /// <summary>
    /// 格子类
    /// </summary>
    public class Gride
    {
        public int		rowCount;						//行数
	    public int		colCount;						//列数
	    public int		cellWidth;						//单元格宽度
	    public int		cellHeight;						//单元格高度
	    Rectangle	    gridRect;					    //表格区域
	    Image	        bmp;							//单元格位图
	    Image           bkBmp;							//表格背景位图
        Bitmap          bit;                            //内存画布
	    public Cell [,] cellGrid;	                    //单元格几集合

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="rc"></param>
        public Gride(Rectangle rc,int row,int col)
        {
            gridRect = rc;
		    rowCount = row;
		    colCount = col;
		    cellHeight = gridRect.Height / rowCount;		//单元格高度
		    cellWidth	= gridRect.Width  / colCount;		//单元格宽度
		    bmp=Bitmap.FromFile("1.bmp");
		    bkBmp=Bitmap.FromFile("bk.bmp");
            bit = new Bitmap(rc.Width-4,rc.Height-16);
            cellGrid = new Cell[rowCount, colCount];
		    InitCellGrid();
        }

        /// <summary>
        /// 初始化表格
        /// </summary>
        private void InitCellGrid()
        {
            
            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < colCount; j++)
                {
                    cellGrid[i, j] = new Cell();
                    cellGrid[i,j].rowIndex = i;
                    cellGrid[i,j].colIndex = j;
                    cellGrid[i,j].bUsed = false;
                    cellGrid[i,j].bFixed = false;

                }
            }
        }

        //绘制表格
        public void DrawGrid(Graphics pDC)
        {
            Graphics graphi = Graphics.FromImage(bit);
            graphi.Clear(Color.Gray);
            //绘制单元格
            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < colCount; j++)
                {
                    //计算单元格区域
                    Rectangle rect = new Rectangle(gridRect.Left + j * cellWidth, gridRect.Top + i * cellHeight, cellWidth, cellHeight);
                    if (cellGrid[i, j].bUsed == true || cellGrid[i, j].bFixed == true)
                    {
                        graphi.DrawImage(bmp, rect);
                    }
                    else
                    {
                        graphi.DrawImage(bkBmp, rect);
                    }
                    Pen pen=new Pen(Color.Black);
                    graphi.DrawRectangle(pen, rect);
                }
            }
            pDC.DrawImage(bit, 0, 0);
        }


    }
}

主要逻辑

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace RussianGrid
{
    public enum Drection {up,low,left,right };
    
    public partial class Main : Form
    {
        public const int ROW_NUM=22;//格子行数
        public const int COL_NUM=15;//格子列数
        Gride gride;                //格子对象
        Drection drection;          //方向
        Piece piece;                //方块
        Random random;              //产生随机数
        int grade = 0;              //记录分数
        bool isEnd = false;         //是否结束
        bool stopping = false;      //是否暂停
        int Next;                   // 下一个方块
        bool isFirst = true;        //是否刚运行
        bool isRuning = false;

        public Main()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            random = new Random();
            gride = new Gride(new Rectangle(0, 0, DrawPanel.Width, DrawPanel.Height),ROW_NUM,COL_NUM);
            gride.DrawGrid(DrawPanel.CreateGraphics());
        }

        /// <summary>
        /// 开始
        /// </summary>
        private void Start()
        {
            isRuning = true;
            gride =new Gride(new Rectangle(0,0,DrawPanel.Width,DrawPanel.Height),ROW_NUM,COL_NUM);
            piece = new Piece();
            piece.SetPieceType(1);
            for (int i = 0; i < 4; i++)
            {
                if (piece.imagesPoint[i].Y < 0)
                {
                    continue;
                }
                gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = true;
            }
            timer1.Enabled = true;
            Next = random.Next(7) + 1;
            Draw();
        }

        /// <summary>
        /// Paint函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DrawPanel_Paint(object sender, PaintEventArgs e)
        {
            Draw();
        }

        /// <summary>
        /// 判断能否下落
        /// </summary>
        /// <param name="piece"></param>
        /// <returns></returns>
        public bool CanPieceMove(Piece piece,Drection drection)
        {
            for (int i = 0; i < 4; i++)
            {
                if (piece.imagesPoint[i].Y < 0)
                {
                    continue;
                }
                gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
            }

            #region 下移
            if (drection == Drection.low)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].Y + 1 >= ROW_NUM)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
                        }
                        return false;
                    }
                    if (piece.imagesPoint[i].Y +1< 0)
                    {
                        continue;
                    }
                    if (gride.cellGrid[piece.imagesPoint[i].Y + 1, piece.imagesPoint[i].X].bUsed || gride.cellGrid[piece.imagesPoint[i].Y + 1, piece.imagesPoint[i].X].bFixed)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            if (piece.imagesPoint[j].Y < 0)
                            {
                                continue;
                            }
                            gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
                        }
                        return false;
                    }
                }
            }
            #endregion

            #region 左移
            if (drection == Drection.left)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].X<= 0)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
                        }
                        return false;
                    }
                    if (piece.imagesPoint[i].Y < 0)
                    {
                        continue;
                    }
                    if (gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X-1].bUsed || gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X-1].bFixed)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
                        }
                        return false;
                    }
                }
            }
            #endregion

            #region 右移
            if (drection == Drection.right)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].X+1 >= 15)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
                        }
                        return false;
                    }
                    if (piece.imagesPoint[i].Y < 0)
                    {
                        continue;
                    }
                    if (gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X + 1].bUsed || gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X + 1].bFixed)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
                        }
                        return false;
                    }
                }
            }
            #endregion 

            #region 旋转
            if (drection == Drection.up)
            {
                for(int n=0;n<4;n++)
                {
                    if (piece.imagesPoint[n].Y < 0)
                    {
                        return false;
                    }
                }
                //图像以左顶点为转点
                if (piece.type == 33 || piece.type == 35 ||
                    piece.type == 44 || piece.type == 46 ||
                    piece.type == 11 || piece.type == 55 ||
                    piece.type == 57 || piece.type == 66 ||
                    piece.type == 77)
                {
                    if (piece.leftIndex == 0)
                    {
                        return false;
                    }

                    else if (piece.leftIndex >= 13 &&
                    (piece.type == 11 || piece.type == 55 ||
                    piece.type == 57 || piece.type == 66 ||
                    piece.type == 77))//如果图像处于右边和右表弟二行,这些图形不能旋转
                    {
                        return false;
                    }

                }


                //定义一个临时的piece1,进行图像转换,判断转换后的图像是否合法,以决定当前图像是否允许变形
                //图像是否合法的检测是通过该图像是否在表格中已被占用来决定的
                Piece piece1 = new Piece ();
                piece1.leftIndex = piece.leftIndex;
                piece1.topIndex = piece.topIndex;
                piece1.type = piece.type;
                piece1.imagesPoint = new Point[4];
                for (int i = 0; i < 4; i++)
                {
                    piece1.imagesPoint[i] = piece.imagesPoint[i];
                }

                piece1.type = GetChangedType(piece.type);
                piece1.SetPieceType(piece1.type); 


                for (int i = 0; i < 4; i++)
                {
                    int nColIndex = piece.imagesPoint[i].X;
                    int nRowIndex = piece.imagesPoint[i].Y;
                    if (nColIndex <= 0 || nColIndex >= ROW_NUM || nRowIndex <= 0 || nRowIndex >= 15)
                    {
                        return false;
                    }

                    if (gride.cellGrid[nColIndex,nRowIndex].bFixed)//如果旋转后的图形有被填充的,则不能旋转
                        return false;
                }

            }
            #endregion
            for (int j = 0; j < 4; j++)
            {
                if (piece.imagesPoint[j].Y < 0)
                {
                    continue;
                }
                gride.cellGrid[piece.imagesPoint[j].Y, piece.imagesPoint[j].X].bUsed = true;
            }
            return true;
        }

        /// <summary>
        /// 移动块
        /// </summary>
        /// <param name="drect"></param>
        /// <param name="piece"></param>
        public void MovePiece(Drection drect, Piece piece)
        {
            
            if (drect == Drection.left)
            {
                if (!CanPieceMove(piece, drect))
                {
                    return;
                }
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].Y < 0)
                    {
                        continue;
                    }
                    gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
                }
                for(int i=0;i<4;i++)
                {
                    
                    piece.imagesPoint[i].X--;
                    

                }
                piece.leftIndex--;
            }
            if (drect == Drection.right)
            {
                if (!CanPieceMove(piece, drect))
                {
                    return;
                }
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].Y < 0)
                    {
                        continue;
                    }
                    gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
                }
                    for (int i = 0; i < 4; i++)
                    {
                        piece.imagesPoint[i].X++;
                        
                    }
                piece.leftIndex++;
            }
            if (drect == Drection.low)
            {
                if (!CanPieceMove(piece, drect))
                {
                    return;
                }
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].Y < 0)
                    {
                        continue;
                    }
                    gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
                }
                for (int i = 0; i < 4; i++)
                {
                    piece.imagesPoint[i].Y++;
                    
                }
                piece.topIndex++;

            }
            if (drect == Drection.up)
            {
                if (CanPieceMove(piece, drect))
                {

                    for (int i = 0; i < 4; i++)
                    {
                        gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = false;
                    }
                    piece.type = GetChangedType(piece.type);
                    piece.SetPieceType(piece.type);
                }
            }
            for (int i = 0; i < 4; i++)
            {
                if (piece.imagesPoint[i].Y < 0)
                {
                    continue;
                }
                gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bUsed = true;
            }
        }


        /// <summary>
        /// 更改类型
        /// </summary>
        /// <param name="nSrcType"></param>
        /// <returns></returns>
        public int GetChangedType(int nSrcType)//获得改变后的图像类型,图像顺时针旋转
        {
            if (nSrcType == 1)
            {
                return 11;
            }
            else if (nSrcType == 11)
            {
                return 1;
            }
            else if (nSrcType == 3)
            {
                return 33;
            }
            else if (nSrcType == 33)
            {
                return 34;
            }
            else if (nSrcType == 34)
            {
                return 35;
            }
            else if (nSrcType == 35)
            {
                return 3;
            }
            else if (nSrcType == 4)
            {
                return 44;

            }
            else if (nSrcType == 44)
            {
                return 45;

            }
            else if (nSrcType == 45)
            {
                return 46;

            }
            else if (nSrcType == 46)
            {
                return 4;
            }
            else if (nSrcType == 5)
            {
                return 55;
            }
            else if (nSrcType >= 55 && nSrcType <= 57)
            {
                if (nSrcType == 57)
                    return 5;
                else
                    return ++nSrcType;
            }
            else if (nSrcType == 6)
            {
                return 66;
            }
            else if (nSrcType == 66)
            {
                return 6;
            }
            else if (nSrcType == 7)
            {
                return 77;
            }
            else if (nSrcType == 77)
            {
                return 7;
            }
            else if (nSrcType == 2)
            {
                return 2;
            }
            else return 1;
        }

        /// <summary>
        /// 按键事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Main_KeyDown(object sender, KeyEventArgs e)
        {
            if (!isRuning)
            {
                return;
            }
            if (e.KeyCode == Keys.Left)
            {
                MovePiece(Drection.left,piece);
            }
            if (e.KeyCode == Keys.Right)
            {
                MovePiece(Drection.right, piece);
            }
            if (e.KeyCode == Keys.Up)
            {
                MovePiece(Drection.up, piece);
            }
            if (e.KeyCode == Keys.Down)
            {
                timer1.Interval = 1;
                MovePiece(Drection.low, piece);
            }
            Draw();
        }

        /// <summary>
        /// 绘图
        /// </summary>
        public void Draw()
        {
            gride.DrawGrid(DrawPanel.CreateGraphics());
        }

        /// <summary>
        /// 产生新块
        /// </summary>
        /// <returns></returns>
        public Piece CreateNewPiece()
        { 
            Piece p = new Piece();
            p.SetPieceType(Next);
            Next = random.Next(7) + 1;
            return p;

        }

        /// <summary>
        /// 时间事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            Running();
        }

        /// <summary>
        /// 运行
        /// </summary>
        private void Running()
        {
            pictureBox1.ImageLocation = "type"+Next + ".bmp";
            if (!CanPieceMove(piece, Drection.low))
            {
                #region 锁定
                for (int i = 0; i < 4; i++)
                {
                    if (piece.imagesPoint[i].Y < 0)
                    {
                        continue;
                    }
                    gride.cellGrid[piece.imagesPoint[i].Y, piece.imagesPoint[i].X].bFixed = true;

                }
                #endregion

                #region 判断消失与计分
                for (int i = ROW_NUM-1; i >= 0; i--)
                {
                    
                    int j = 0;
                    for (; j < COL_NUM; j++)
                    {

                        if (gride.cellGrid[i, j].bFixed == false)
                        {
                            break;
                        }
                    }
                    if (j == COL_NUM)
                    {
                        for (int n = 0; n < COL_NUM; n++)
                        {
                            for (int m =i; m>=1; m--)
                            {
                               
                                gride.cellGrid[m, n].bFixed = gride.cellGrid[m - 1, n].bFixed;
                                gride.cellGrid[m, n].bUsed = gride.cellGrid[m - 1, n].bUsed;


                              
                            }

                        }
                        i++;
                        grade += 10;
                        label1.Text = "分数:" + grade;
                    }
                }
                #endregion

                #region 判断结束
                    for (int n = 0; n < COL_NUM; n++)
                    {
                        if (gride.cellGrid[0, n].bFixed == true)
                        {
                            if (isEnd == false)
                            {
                                isEnd = true;
                                isRuning = false;
                                Draw();
                                MessageBox.Show("游戏结束","结束提示");
                            }
                            timer1.Enabled = false; 
                            return;
                        }

                    }
                    #endregion

                    //产生新块
                    piece = CreateNewPiece();
                    timer1.Interval = 500;
                    return;

                
            }
            MovePiece(Drection.low, piece);
            Draw();
        }


        /// <summary>
        /// 开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labStart_Click(object sender, EventArgs e)
        {
            Start();

        }

        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labstop_Click(object sender, EventArgs e)
        {
            if (isRuning)
            {
                timer1.Enabled = false;
                stopping = true;
            }
        }

        /// <summary>
        /// 继续
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labContinue_Click(object sender, EventArgs e)
        {
            if (isRuning)
            {
                if (stopping == true)
                {
                    timer1.Enabled = true;
                    stopping = false;
                }
            }
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小乌鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值