游戏开发中常用的算法(持续更新)

一、快速排序算法

步骤1:选取一串数字中的中心轴

步骤2:将大于中心轴的数字放在右边

步骤3:将小于中心轴的数字放在左边

步骤4:分别对左右两个序列重复前三步操作

public class QuickSort : MonoBehaviour
{
    private void Start()
    {
        int[] Nums = { 4, 3, 6, 1, 8, 0, 3, 2, 5, 7};
        Sort(Nums, 0, 9);
        for (int i = 0; i < 10; i++)
        {
            Debug.Log(Nums[i]);
        }
    }
    void Sort(int[] nums,int left,int right)
    {
        //退出条件
        if (left  >= right)
            return;
        int i = left;
        int j = right;

        //中心元素取为第一个元素
        int temp = nums[left];

        while(i != j)
        {
            //从最右边的元素开始比较中心元素
            while(i < j && nums[j] >= temp)
            {
                j--;
            }
            if(i < j )
            {
                nums[i] = nums[j];
            }
           while(i < j && nums[i] <= temp)
            {
                i++;
            }
           if(i < j)
            {
                nums[j] = nums[i];
            }
        }
        nums[i] = temp;
        Sort(nums, left, i - 1);
        Sort(nums, i+1, right);
    }
}

二、冒泡排序算法

步骤一、从数组的最左侧两个元素进行比较

步骤二、将较大的数向右移动,再进行比较

步骤三、直到将最大的数字放在最右边

步骤四、重复上述操作,不过这次比较数组的数量-1

public class BubbleSort : MonoBehaviour
{
    private void Start()
    {
        int[] array = { 6, 5, 8, 7, 1, 2, 3, 5 };
        Sort(array);
        for (int i = 0; i < array.Length; i++)
        {
            Debug.Log(array[i]);
        }
    }

    private void Sort(int[] array)
    {
        //进行i次排序,对数组内所有元素都进行比较
        for (int i = 0; i < array.Length - 1; i++) 
        {
            //对某一元素进行的相邻元素的比较,比较次数差i次
            for(int j = 0; j < array.Length-1-i; j++)
            {
                if(array[j] > array[j+1])
                {
                    int temp = array[j];
                    //如果左边的数字比右边的大,就把大的数字向右平移一位
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
}

三、二分查找(要求数组顺序排列)

一、初始化三个序号,分别代表第一个,最后一个和中间序号

二、用中间序号的值和目标值进行对比,如果相等就返回

三、如果中间序号的值大于目标值,就向左缩小范围

四、如果中间序号的值小于目标值,就向右缩小范围

第一种实现:常规实现

public class BinarySearch : MonoBehaviour
{
    private void Start()
    {
        int[] array = { 8, 11, 21, 28, 32, 43, 48, 56, 69, 72, 80, 94 };
        Debug.Log(Search(array, 80)); 
    }
    private int Search(int[] array,int key)
    {
        var min = 0;
        var max = array.Length - 1;
        var mid = 0;
        while(min <= max)
        {
            mid = (min + max) / 2;
            if(array[mid] > key)
            {
                max = mid - 1;
            }
            else if(array[mid] < key)
            {
                min = mid + 1;
            }
            else if(array[mid] == key)
            {
                return mid;
            }
        }
        return 0;
    }
}

第二种实现:递归实现

Debug.Log(SearchTwo(array, 80,0,12));
 
private int SearchTwo(int[] array,int key,int low,int high)
    {
        if (low > high)
            return -1;
        var mid = (low + high) >> 1;
        if (array[mid] > key)
        {
            return SearchTwo(array, key, low, mid - 1);
        }
        else if (array[mid] < key)
        {
            return SearchTwo(array, key, mid + 1, high);
        }
        else
            return mid;
    }
}

四、基于四叉树/八叉树的碰撞检测

五、随机寻路算法、跟踪算法、闪避算法(与跟踪算法相反)

DFS(Deep First Search)、BFS(Breadth Fitst Search)

六:A*寻路算法

A*主要是利用三个数值来计算最佳路径,分别是G代价、H代价、F代价

G:从某节点到开始节点的移动距离

H:从某节点到目标节点的估计移动距离,从任何节点迭代实际所需的距离大于或者等于H代价。

F:F代价等于G+H,F值越低,作为寻径选择就越有吸引力

我们的目标是简单的选择最低的F代价,不断的重复,直到我们的目标节点

代码部分可以见:

(1条消息) Unity A星(A Star/A*)寻路算法_unity寻路算法_九本才的博客-CSDN博客

现在有A*的寻路插件

七:B*寻路算法

理解B*可以把它想象成一个朝着目标前进的贪吃蛇,如果遇到障碍就会分裂成两条蛇,一左一右绕开障碍,只要有一条蛇碰到目标就结束寻路

优点:目标点在封闭空间内时,BStar效率优势明显

缺点:喜欢贴着墙走

八、Nav Mesh导航系统

NacigationMesh是一种数据结构,用于描述游戏世界的可行走表面

Navigation是Unity自带的导航,具备基本的Bake,NavMesh和NavMeshAgent等基本导航功能

新版中有NavMeshComponent,能够实现动态烘焙

步骤:

打开Navgation面板、

设置烘焙参数(Bake Agent)、

设置行走区域(设置为Navigation Static)、烘焙

角色添加寻路控制器(Nav Mesh Agent)、

挂在一个脚本到Player身上,告诉目标点即可

using UnityEngine;
using UnityEngine.AI;

public class Player : MonoBehaviour
{
	private NavMeshAgent agent;
	public Transform target;

	void Start()
	{
		agent = GetComponent<NavMeshAgent>();
		agent.destination = target.position;
	}
}

猜你喜欢

转载自blog.csdn.net/leikang111/article/details/129695344