• 团队项目:核心算法实现


    本游戏中最为核心的算法在于绘制轨道曲线的算法,实现如下:

    每帧获取屏幕上的鼠标的位置设置为终点vt,之前上一帧设置的起点为v0,则这一帧所生成的轨道就是从v0到vt。在轨道生成完成后,将v0设置为vt,以便于下一帧继续进行轨道的生成。

    流程图:

             图1 核心算法流程图

    伪代码:

             1.检测是否按住鼠标左键,是则进入2,否则进入8。

             2.获取鼠标在屏幕上的当前位置并转换为世界坐标temp_pos。

             3.如果是第一次按下(first为true),将当前temp_pos赋给begin_pos,将first设为false。

             4.如果当前的temp_pos到begin_pos的距离在最小限度以外,且线条总长totalLength在总长限制maxLength内则进入5,否则进入8。

             5.将temp_pos赋给end_pos,若当前totalLength加上begin_pos和end_pos之间的距离tempLength超过了maxLength则对线段[begin_pos,end_pos]截取,改变end_pos的位置,使totalLength加上tempLength等于maxLength。将totalLength+tempLength赋给totalLength。

             6.在线段[begin_pos,end_pos]的终点new_pos的位置创建一个轨道元素,并调整其角度和缩放值,使其从begin_pos连接到end_pos。

             7.将end_pos赋给begin_pos。

             8.检测是否放开鼠标左键,是则进入9,否则进入10。

             9.将first设置为true,将totalLength设置为maxLength(即松开左键后不得继续创建轨道元素;clear()函数可将totalLength清零,之后可以继续画线)。

             10.回到1。

    详细代码:

    if (Input.GetMouseButton(0)){//如果按住左键
                temp_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//屏幕坐标转世界坐标
                temp_pos.z = 0;//调整世界坐标z轴
                if (first == true){//如果是第一次按左键
                    begin_pos = temp_pos;//当前位置作为开始位置
                    first = false;//设置第一次标志为假
                }
               //当前位置和开始位置有一定间隔&&未超出长度限制
                else if ((Vector3.Magnitude(temp_pos - begin_pos) >= 0.1) && (totalLength < maxLength)){
                    end_pos = temp_pos;//当前位置作为结束为止
                    float tempLength = Vector3.Magnitude(end_pos - begin_pos);//记录当前长度
                    if (totalLength + tempLength > maxLength) {//若在本次超出长度限制
                     //调整end_pos并且进行截取
                        end_pos = begin_pos + (end_pos - begin_pos) * (maxLength - totalLength) / tempLength;
                        totalLength = maxLength;//总长度等于最大长度
                    }
                    else{//本次未超出长度限制
                        totalLength += tempLength;//总长度加上当前长度
                    }
                  //新的轨道物体的位置为开始位置和结束位置连线的中点
                    Vector3 new_pos = (begin_pos + end_pos) / 2;
                  //新的轨道物体的x方向的缩放因子为开始位置和结束位置之间的线段长度
                  //(因为轨道物体的x方向长度为1)
                    Vector3 new_scale = new Vector3(Vector3.Magnitude(end_pos - begin_pos), 1, 1);
                    //新的轨道物体的旋转角度
                  float new_degree = 0;
                    if (begin_pos.y > end_pos.y){//终点在起点下方
                     //旋转角度为向量Vector3.right和end_pos-begin_pos的夹角的相反数
                        new_degree = -Vector3.Angle(Vector3.right, end_pos - begin_pos);
                     //因为Angle方法只能返回0到180度的角
                    }
                    else{//终点在起点上方
                     //旋转角度为向量Vector3.right和end_pos-begin_pos的夹角
                        new_degree = Vector3.Angle(Vector3.right, end_pos - begin_pos);
                     //因为Angle方法只能返回0到180度的角
                    }
                  //实例化track_element物体
                    track_element_new=(GameObject)Instantiate(track_element, new_pos, Quaternion.identity); 
                  //更改其缩放因子
                    track_element_new.transform.localScale = new_scale;
                  //更改其旋转角度(绕z轴正方向旋转new_degree度)
                    track_element_new.transform.Rotate(Vector3.forward, new_degree);
                  //更新下一次的开始位置为这一次的结束位置
                    begin_pos = end_pos;
                }
            }
            if (Input.GetMouseButtonUp(0)){//如果放开鼠标左键
                totalLength = maxLength;//将当前总长度设为最大,即松开左键就不可再画(一笔画)
                first = true;//设置first标志为真
            }
  • 相关阅读:
    笔记二
    笔记一:高效的可维护的,组件化的CSS
    移动端调自适应的方法
    前端世界的憧憬
    JAVA继承、多态与接口
    JAVA第一周
    常用CSS标签1——属性
    回头再看N层架构(图解)
    .net 配置加密
    小小商城的一次前端架构演变
  • 原文地址:https://www.cnblogs.com/GingerAle/p/5601645.html
Copyright © 2020-2023  润新知