俄罗斯方块C#代码实现

本文介绍了一个使用C#编写的俄罗斯方块游戏。游戏包括预览、旋转、移动、消除等功能,通过WinForm实现图形界面,并且详细展示了关键代码,包括方块类定义、方块形状定义及游戏逻辑。此外,还提供了键盘控制和暂停/重新开始的选项。
摘要由CSDN通过智能技术生成


前言

学习C#之初,主要感兴趣的还是WinForm 软件的开发,后来随着工作的需要一直在进行Web开发。曾经在学校写过的代码,多年之后看看仍然感觉很有意思

代码地址:https://gitee.com/john273766764/tetris


一、先看看效果

二、核心代码

1.代码结构


2.资源文件

3.定义面板控件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace 方块2
{
    class GamePanel:Panel 
    {
        public GamePanel()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);            
        }
    }
}

4.方块类定义

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using 方块2.Properties;

namespace 方块2
{
    public class Block
    {
        #region 申明变量和属性
        private static Image[] imgBlocks = new Image[]
        {
            Resources .block0 ,
            Resources .block1 ,
            Resources .block2 ,
            Resources .block3 ,
            Resources .block4 ,
            Resources .block5 ,
            Resources .block6 ,
            Resources .block7 ,
            Resources .block8

        };
        public static int speed;
        public int colorNum = 0;
        public int xPos { get; set; }
        public int yPos { get; set; }
        public bool[,] blockCode = new bool[4, 4];
        public static bool Islive = true;//判断是否结束
        public static bool IsSuspend = true;//判断是否暂停
        Random rad = new Random();
        private bool[,] P_blockCode;
        private int P_colorNum;

        #endregion
        /// <summary>
        /// 构造函数,初始化
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public Block()
        {
            this.xPos = 4;
            this.yPos = -2;
            this.blockCode = Blocks.getcode();
            colorNum = rad.Next(0, 8);
            P_blockCode = Blocks.getcode();
            P_colorNum = rad.Next(0, 8);
        }

        #region 方法
        public void Preview()//预先找出下一个图形
        {
            P_blockCode = Blocks.getcode();
            P_colorNum = rad.Next(0, imgBlocks .Length );
        }
        public void CreateNew()//创建一个新的block;
        {
            if (Islive == true)
            {
                IsSuspend = false;
                blockCode = P_blockCode;
                colorNum = P_colorNum;
                Preview();
                this.xPos = 4;
                this.yPos = -2;
            }
            else
            {
                GameOver();
            }
        }   
        public void MoveLeft()
        {
            if (TestFill(-1, 0, blockCode) == false)// BlockGroup 中没有方块
            {
                this.xPos--;
            }
            else
            {
                return;
            }
            
        }
        public void MoveRight()
        {
            if (TestFill(1, 0, blockCode) == false)
            {
                this.xPos++;
            }
            else
            {
                return;
            }
        }
        public void TurnRight()
        {            
            bool[,] temp = new bool[4, 4];
            for (int line = 0; line < 4; line++)
            {
                for (int colum = 0; colum < 4; colum++)
                {
                    temp[line, colum] = blockCode[3 - colum, line];
                }
            }
            if (TestFill(0, 0, temp) == false)
            {
                blockCode = temp;
            }
        }
        public void TurnLeft()
        {
            bool[,] temp = new bool[4, 4];
            for (int line = 0; line < 4; line++)
            {
                for (int colum = 0; colum < 4; colum++)
                {
                    temp[line, colum] = blockCode[colum, 3 - line];
                }
            }
            if (TestFill(0, 0, temp) == false)
            {
                blockCode = temp;
            }
        }
        public void Down()
        {
            if (IsSuspend == true)
            {
                return;
            }
            if (TestFill(0, 1,blockCode ) == false )// BlockGroup 中没有方块
            {
                this.yPos++;
            }
            else
            {
                SendBlock();
                BlockGroup.CheckBlock();
                CreateNew();
            }
        }
        public void Draw(Graphics g)
        {
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (blockCode[i, j] == true)
                    {
                        g.DrawImage(imgBlocks[colorNum], (xPos + j) * 35, (yPos + i) * 35);
                    }
                }
            }
        }
        public void KeyDown(KeyEventArgs e)
        {
            if (IsSuspend == true)
            {
                return;
            }
            if (e.KeyCode == Keys.S)
            {
                Down();
            }
            if (e.KeyCode == Keys.A)
            {
                MoveLeft();
            }
            if (e.KeyCode == Keys.D)
            {
                MoveRight();
            }
            if (e.KeyCode == Keys.W)
            {
                TurnLeft();
            }
            if (e.KeyCode == Keys.R)
            {
                TurnRight();
            }
        }
        public void DrawPreview(Graphics g)
        {
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (P_blockCode[i, j] == true)
                    {
                        g.DrawImage(imgBlocks[P_colorNum],j * 35+10,i* 35+30);
                    }
                }
            }
        }
        public bool TestFill(int right, int down,bool [,] Code)//x,y表示移动方向
        {            
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (Code [i,j]==true)
                    {
                        if (BlockGroup.IsFill(yPos + i + down, xPos + j + right) == true)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        public void SendBlock()
        {
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (blockCode[i, j] == true)
                    {
                        BlockGroup.AddBlock(yPos + i, xPos + j, colorNum);
                    }
                }
            }
        }
        public void GameOver()
        {
            IsSuspend = true;
            if (MessageBox.Show("您的分数是:" + BlockGroup.credit*100 + "。\n想重新开始游戏,再次突破自己的分数吗?", "重新开始游戏", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                BlockGroup.NewGame();
                Islive = true;
                CreateNew();
            }
            else
            {
                Application.Exit();
            }
        }
        #endregion
    }
}

5.方块形状定义

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

namespace 方块2
{
    /// <summary>
    /// 存储block的形状信息
    /// </summary>
    public class Blocks
    {
        #region block的形状信息
        public static bool[][,] blockCodes = new bool[][,]
            {
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,true,true,false},
                    {false,true,true,false},
                    {false,false,false,false}
                },
                 new bool [4,4]
                {
                    {false,true,false,false},
                    {false,true,false,false},
                    {false,true,false,false},
                    {false,true,false,false}
                },
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,true,false,false},
                    {false,true,true,false},
                    {false,true,false,false}
                },
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,false,true,false},
                    {false,true,true,false},
                    {false,false,true,false}
                },
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,true,false,false},
                    {false,true,false,false},
                    {false,true,true,false}
                },
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,true,false,false},
                    {false,true,true,false},
                    {false,false,true,false}
                },
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,false,true,false},
                    {false,true,true,false},
                    {false,true,false,false}
                },
                new bool [4,4]
                {
                    {false,false,false,false},
                    {false,true,true,false},
                    {false,true,false,false},
                    {false,true,false,false}
                }
            };

        #endregion

        public static bool[,] getcode()// 随机取得Block信息
        {
            Random rad = new Random();
            return blockCodes[rad.Next(0, blockCodes.Length)];
        }
    }
}

6.方块面板展示逻辑

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using 方块2.Properties;
using System.Windows.Forms;
using System.Media;

namespace 方块2
{
    public class BlockGroup  //控制panel中的block的动作
    {
        public static SoundPlayer soundMoveDown = new SoundPlayer(Resources.GotCreit);
        public static int credit = 0;
        private static int lines = 18, columns = 11;
        private static int[,] blocks = new int[lines, columns];
        private static Image[] imgBlock = new Image[]
        {
            Resources .block0 ,
            Resources .block1 ,
            Resources .block2 ,
            Resources .block3 ,
            Resources .block4 ,
            Resources .block5 ,
            Resources .block6 ,
            Resources .block7 ,
            Resources .block8

        };
        public BlockGroup()
        {
            soundMoveDown.Load();
            InitGroup();
        }
        private static void InitGroup()//初始化面板18x11
        {
            for (int line = 0; line < lines; line++)
            {
                for (int column = 0; column < columns; column++)
                {
                    blocks[line, column] = 0;
                }
            }
        }
        public void Draw(Graphics g)
        {
            for (int line = 0; line < lines; line++)
            {
                for (int column = 0; column < columns; column++)
                {
                    if (blocks[line, column] == 0)
                    {
                        continue;
                    }
                    else
                    {
                        g.DrawImage(imgBlock[blocks[line, column]-1], column * 35, line * 35);
                    }
                }
            }
        }
        public static bool IsFill(int lin,int col)
        {
            if (lin <0)
            {
                return false;
            }
            if (col <0)
            {
                return true;
            }
            if (lin > 17)
            {
                return true;
            }
            if (col > 10)
            {
                return true;
            }
            if (blocks[lin, col] > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static void AddBlock(int x,int y,int colorNum)
        {
            if (x > 0)
            {
                blocks[x, y] = colorNum + 1;
            }
            else
            {
                Block.Islive = false;
            }
            return;
        }
        public static void CheckBlock()//检查一行是否已满
        {
            for (int line = 1; line < lines; line++)
            {
                for (int colum = 0; colum < columns; colum++)
                {
                    if (blocks[line, colum] < 1)
                    {
                        break;
                    }
                    if (colum == columns - 1)
                    {
                        MoveDown(line);
                    }
                }
            }
        }
        public static void NewGame()
        {
            InitGroup();
            credit = 0;            
        }
        public static void MoveDown(int lineNum)//向下移动
        {
            soundMoveDown.Play();
            for (int line = lineNum; line > 0; line--)
            {
                for (int colum = 0; colum < columns; colum++)
                {
                    blocks[line, colum] = blocks[line - 1, colum];
                }
            }
            credit += 1;
        }

    }
}

7.主窗口代码

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;
using 方块2.Properties;
using System.Media;

namespace 方块2
{
    public partial class MainForm : Form
    {
        //拖动窗口
        Point offset = new Point();
        bool isMove = false;

        BlockGroup BG = new BlockGroup();
        Block Bl = new Block();
        SoundPlayer sound = new SoundPlayer(Resources.PressKey);

        public MainForm()
        {
            InitializeComponent();
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
            this.BackgroundImage = Resources.backgrand;
            this.timer1.Interval = 1000 - BlockGroup.credit * 100;
            this.timer1.Enabled = true;
            sound.Load();
        }
        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            Bl.KeyDown(e);
            this.gamePanel.Invalidate();
        }
        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.offset = new Point(MousePosition.X - this.Location.X, MousePosition.Y - this.Location.Y);
                isMove = true;
            }
        }
        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && isMove == true)
            {
                this.Location = new Point(MousePosition.X - offset.X, MousePosition.Y - offset.Y);
            }
        }
        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            isMove = false;
        }
        private void gamePanel_Paint(object sender, PaintEventArgs e)
        {
            BG.Draw(e.Graphics);
            Bl.Draw(e.Graphics);
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            Block.speed = (BlockGroup.credit/10)*10+10;
            if (this.timer1.Interval > 300)
            {
                this.timer1.Interval = 1000 - (Block.speed-10) * 10;
            }
            Bl.Down();
            this.gamePanel.Invalidate();
            this.Preview_panel.Invalidate();
            this.labCredit.Text = "分数:" + BlockGroup.credit*100;
            this.labSpeed.Text = "速度:" + Block.speed;
            
        }
        private void Preview_panel_Paint(object sender, PaintEventArgs e)
        {
            Bl.DrawPreview(e.Graphics);
        }
        private void btnSuspend_Click(object sender, EventArgs e)
        {
            Block.IsSuspend = true;
        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            Block.IsSuspend = false;
        }
        private void 开始ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Block.IsSuspend = false;
        }
        private void 暂停ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Block.IsSuspend = true;
        }
        private void 帮助ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Block.IsSuspend = true;
            MessageBox.Show("按键信息:\n\n下:S\n左:A\n右:D\n左转:W\n右转:R", "按键信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            Block.IsSuspend = false;
        }
        private void MainForm_KeyUp(object sender, KeyEventArgs e)
        {
            sound.Play ();
        }
    }
}

总结

有机会多写写自己想写的代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值