一个简单的俄罗斯方块实现

最近在看《.NET游戏编程入门经典 C#篇》 第一章介绍了如何制作俄罗斯方块,自己试了试按照书上的步骤,可算是完成了。

于是写下这篇文章留作纪念。

1.类的设计

在充分分析游戏的特点后,游戏大概可以分为3个类:Square 小正方形,Block 由4个小正方形组合成的一个图形, GameField 游戏的驱动引擎

2.代码的编写

按照从小到大,从简单到复杂的顺序,先完成Square类,Square很简单,只需要提供Show,Hide方法以及Size,Location属性。

接下来是Block,Block相对比较复杂,分为以下几种:


它应该有4个Square 编号可以按照个人习惯,当然之后计算坐标的时候也要根据个人的编号来进行。

Block应该有Hide,Show,Left,Right,Rotate一些方法,属性的话为了计算坐标 应该有Square的大小,还有Color

要注意的是Rotate方法将Block顺时针旋转90°,图上已经标出旋转的中心。

最后剩下的就是GameField了,他应该有一个数组,保存背景中所有的Square,以及哪些位置有Square的 位标志数组,对每一行的检查(是否消去得分)以及消去所有方块下移操作。

这些类完成后就可以简单的写游戏逻辑了,因为太简单就不说了,简单的贴一下代码

        private Block currentBlock;
        private Block nextBlock;
        private int score;
        private bool blockFalling;

        private void button1_Click(object sender, EventArgs e)
        {
            pictureBox1.Refresh();
            currentBlock = new Block(new Point(GameField.Width / 2 * GameField.SquareSize, 0), Block.BlockTypes.Undefined);
            currentBlock.Show(GameField.WinHandle);
            nextBlock = new Block(new Point(15, 15), Block.BlockTypes.Undefined);
            nextBlock.Show(pictureBox2.Handle);
            timer1.Enabled = true;
            button1.Enabled = false;
            Focus();
            score = 0;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            GameField.WinHandle = pictureBox1.Handle;
            GameField.BackColor = pictureBox1.BackColor;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (currentBlock == null)
            {
                return;
            }
            switch (e.KeyCode)
            {
                case Keys.W:
                    currentBlock.Rotate();
                    break;
                case Keys.S:
                    currentBlock.Down();
                    break;
                case Keys.A:
                    currentBlock.Left();
                    break;
                case Keys.D:
                    currentBlock.Right();
                    break;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!currentBlock.Down())
            {
                blockFalling = false;
                //塞满了 游戏结束  0 0
                if (currentBlock.Top() == 0)
                {
                    timer1.Enabled = false;
                    button1.Enabled = true;
                    GameField.Reset();
                    MessageBox.Show("恭喜你跪了");
                    return;
                }
                
            }
            else
            {
                blockFalling = true;
            }
            if (!blockFalling)
            {
                //检查得分
                int earseCount = GameField.CheckLines();
                if (earseCount > 0)
                {
                    score += earseCount * 20;
                    label1.Text = score.ToString();
                    //使图片框重绘 清楚Block
                    pictureBox1.Invalidate();
                    Application.DoEvents();
                    GameField.Redraw();
                }
                pictureBox2.Invalidate();
                Application.DoEvents();
                currentBlock = new Block(new Point(GameField.Width / 2 * GameField.SquareSize, 0), nextBlock.BlockType);
                currentBlock.Show(GameField.WinHandle);


                nextBlock = new Block(new Point(15, 15), Block.BlockTypes.Undefined);
                nextBlock.Show(pictureBox2.Handle);
                blockFalling = true;
            }
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            GameField.Redraw();
            if (nextBlock !=null)nextBlock.Show(pictureBox2.Handle);
        }

3.总结

这个简单的游戏,可谓是刚好适合新手。可以学到冲突检测(CheckLines),游戏中基本元素与游戏驱动的理解。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值