• 俄罗斯方块源码解析(带下载)[3]


    准备工作都做好了,关键部分“原理”也说了,该干点事了吧

    该主调程序 game类出场的时候了,

    不得不说的是,首先对于编程的人来说 不管你高手也好 菜鸟也好。

    对于你要做的事 目标要明确,你要做什么。

    怎么做 先做什么 后做什么,什么情况为“完成”,什么情况为“失败”

    这才是一个正常的 程序员应该有的思维,作为一个程序员 我们就是要看透事情的本质。

    流程图就免了吧 直接给伪代码得了(其实这是真代码^_^ ,莫打我):

    public void go()//主调方法 表示 1 step 如果游戏没结束则继续 如此往复直到游戏结束
            {
                if (downCheck())//如果有下落空间
                {
                    down();//下落操作
    
                }
                else//如果到底了 或者 跟其他shape接触 
                {
                    merge();//把 “卡住”的方块 “印”到画布(容器gameArea)中去,意思就是把卡住的方块“堆”到游戏区
    
                    if (!isOver)//如果游戏没有结束(判断依据为方块是否已经堆积到容器的顶端) 重新实例化一个shape  让他down下来
                    {
                        shape s = new shape();
                        int pindx = 0;
                        for (int i = 0; i < s.transform.GetLength(0); i++)
                        {
                            for (int j = 0; j < s.transform.GetLength(1); j++)
                            {
                                if (s.transform[i, j] == true)
                                {
                                    sh[pindx++] = new Point(j, i);
                                }
                            }
                        }
                    }
                }
    
                setScore();//在重新实例化之前先检查 gameArea 看是否有可消除的行 并计算得分
            }
    

    下面是一些具体的东西,比如左移操作啊,落下的动作 啊,判断是否有可消除的行啊,具体实现就看你了 也许你实现的方式 或者算法比我更好,希望分享。

    以下是我实现的方式

    开始游戏:

    public void start()//开始一个游戏 包括初始化gameArea 等
            {
                area = new gameArea();
                shape s = new shape();
    
                int pindx = 0;
                for (int i = 0; i < s.transform.GetLength(0); i++)
                {
                    for (int j = 0; j < s.transform.GetLength(1); j++)
                    {
                        if (s.transform[i, j] == true )
                        {
                            sh[pindx++] = new Point(j, i);
                        }
                    }
                }
            }
    

    移动:

     gameArea area;//容器(存放堆积起来的方块)
           
            Point[] sh = new Point[4];//下落中的方块(每个方块最多只能由四个点组成)
    
    enum direction { left, right, down };
    
            void move(direction dir)//移动
            {
                switch (dir)
                {
                    case direction.left:
                        {
                            bool can = true;
                            if (sh != null)
                                foreach (Point p in sh)
                                {
                                    if (p.X <=0)
                                    {
                                        can = false;
                                        break;
                                    }
                                }
                            if (can)
                            {
                                for (int i = 0; i < sh.Length; i++)
                                    sh[i].X--;
                            }
                            break;
                        }
                    case direction.right:
                        {
                            bool can = true;
                            if(sh!=null)
                                foreach (Point p in sh)
                                {
                                    if (p.X >= gameArea.width - 1)
                                    {
                                        can = false;
                                        break;
                                    }
                                }
                            if (can)
                            {
                                for (int i = 0; i < sh.Length; i++)
                                    sh[i].X++;                          
                            }
                            break;
                        }
                    case direction.down:
                        {
                            for (int i = 0; i < sh.Length; i++)
                                sh[i].Y++;                                                
                            break;
                        }
                }
            }
    

    判断方块是否卡住:

     bool downCheck()//进行边界检查  比如到底了 或者跟其他shape接触,跟容器中对应的方块比较 看是否产生“边界接触
            {
                 foreach (Point p in sh)
                 {
                            if (p.Y >= gameArea.height - 1)
                                return false;
                            if (area.gameAreaArray[p.Y + 1, p.X] == true)
                                return false;
                }
                return true;
            }
    

    判断游戏是否结束:

    public bool isOver
            {//通知外部程序 你y挂了(判断是否已经堆积到gameArea的顶端)
                get
                {
                    for (int j = 0; j < area.gameAreaArray.GetLength(1); j++)
                    {
                        if (area.gameAreaArray[0, j] == true)
                            return true;
                    }
                    return false;
                }
            }
    

    把已经卡住的“方块” “堆”到容器中的方法 ,同志们可能想的比较复杂 。实际上超简单 ,就是把容器中跟方块对应的数组元素(也可以说是坐标吧)改成true就OK了

    意为把 卡住方块的像素“写”到容器中去。

    just so so

     void merge()//合并 跟边界产生接触 把shape添加到画布中来
            {
                 foreach (Point p in sh)
                            area.gameAreaArray[p.Y, p.X] = true;            
            }
    

    怎么样超简单吧 ^_^

    终于写了这么多 好累,下一章我将讲一下 查找“图像轮廓”,跟“顺时针旋转”的算法。

    请看第四章

  • 相关阅读:
    如何将JS中object转换为字符串
    验证码的实现
    JSP中解决session超时跳转到登陆页面并跳出iframe框架或局部区域的方法
    java 后台封装json数据学习总结
    ztree复选框
    左偏树详解
    Docker 入门
    linux 多进程
    派生类构造函数顺序
    20210203 7. 分库分表实战及中间件
  • 原文地址:https://www.cnblogs.com/assassinx/p/1833683.html
Copyright © 2020-2023  润新知