zoukankan      html  css  js  c++  java
  • 蜂窝网格的坐标以及寻路

    蜂窝网格就是这样的六边形格子

    总结一下前段时间做的rpg游戏demo
    仔细观察的话,可以发现,蜂窝网格和四边形网格的区别就在于,蜂窝网格把偶数行的格子都错开了。
    假设一个格子在四边形网格中的坐标是(x,y),那么它在蜂窝网格的坐标应该是:
    (sqrt3 * (x + (y % 2) / 2) , y * 3 / 2)
    这样就能把蜂窝网格用一个二维数组保存起来了。
    接下去是一个寻路算法,我们需要找出以一个格子为起点,一定移动力下所有可以到达的格子,就像上面那张图里展示的那样:
    public class hextile{
    public static float sqrt3=1.7320508075689f;
    public int x, y,m;//格子的坐标,以及移动到这个格子上的剩余行动力
    public hextile pre;//表示是从哪个格子移动到这个格子上的,为Null的话表示没有
    int max=20;//二维数组的上界,暂时定为了20*20的矩形蜂窝方阵
    ///构造函数
    public hextile(int x,int y,hextile pre,int m){
    this.x = x;
    this.y = y;
    this.pre = pre;
    this.m = m;
    }
    //返回蜂窝一周的六个蜂窝,理论上要另写一个函数判断是否越界了的,这里直接在方法里判断了
    public List around(int i){
    List list = new List ();
    if (this.x > 0)
    list.Add (new hextile (this.x - 1, this.y, this,this.m-i));
    if (this.x < max-1)
    list.Add (new hextile (this.x + 1, this.y, this,this.m-i));
    if ((this.y < max-1) && (this.x - 1 + this.y % 2 >= 0))
    list.Add (new hextile (this.x - 1 + this.y % 2, this.y + 1, this,this.m-i));
    if ((this.y < max-1) && (this.x + this.y % 2 < max))
    list.Add (new hextile (this.x + this.y % 2, this.y + 1, this,this.m-i));
    if ((this.y > 0) && (this.x - 1 + this.y % 2 >= 0))
    list.Add (new hextile (this.x - 1 + this.y % 2, this.y - 1, this,this.m-i));
    if ((this.y > 0) && (this.x + this.y % 2 < max))
    list.Add (new hextile (this.x + this.y % 2, this.y - 1, this,this.m-i));
    return(list);
    }
    //返回以此对象为起点,移动力为m的蜂窝,arr为移动力阻碍数组
    public List findarea(int[,] arr){
    List list = new List ();//输出用的链表
    List a = new List ();//a记录每个需要寻路的节点
    a.Add(this);
    list.Add (this);
    //枚举移动力,一定要倒过来枚举,因为涉及到了链表元素的删除
    for (int i = this.m; i > 0; i--) 
    {
    //对移动力等于当前枚举数的格子进行操作
    for (int j = a.Count - 1; j >= 0; j--)
    //对应移动力才能进行操作
    if (a[j].m==i)
    //有多余移动力则获取该格子周围一圈的格子
    if (a[j].m>=arr[a[j].x,a[j].y]){
    //获取该格子周围一圈的格子
    List l = a [j].around(arr[a[j].x,a[j].y]);
    for (int u = 0; u < l.Count; u++) {
    bool bo = true;
    //判断该格子是否能加入输出list
    for (int o = 0; o < list.Count; o++) {
    if ((list[o].x==l[u].x)&&(list[o].y==l[u].y)){
    bo = false;
    //如果是更优路线
    if (list [o].m < l [u].m) {
    list.RemoveAt (o);
    list.Add (l [u]);
    a.Add (l [u]);
    break;
    }
    }
    }
    if (bo) {
    list.Add (l [u]);
    a.Add (l[u]);
    }
    }
    //操作完毕,将该格子从待操作列表中删除
    a.RemoveAt (j);
    }
    }
    return(list);
    }
    }
  • 相关阅读:
    seata 1.3.0 seata Global lock wait timeout
    Tika解析word文件
    我的第一款微信小程序:iteye附件下载器,希望大家好好爱惜
    读书《尸检报告》 [英]卡拉·瓦伦丁 / 中信出版集团2019-08
    读书《另一种选择》 [美] 谢丽尔·桑德伯格 / 中信出版集团2017-08
    读书《不朽的失眠》 张晓风 / 四川人民出版社2018-09
    Uniapp 修改内置组件样式无效解决方法
    Android studio中.9图片的含义及制作教程
    Diff算法
    js new一个对象的过程,实现一个简单的new方法
  • 原文地址:https://www.cnblogs.com/Swallowtail/p/6181469.html
Copyright © 2011-2022 走看看