js+ajax实现的A*游戏路径算法整理第2/2页

 更新时间:2007年05月28日 00:00:00   作者:  

在51js上找到了hjjboy朋友的js实现方法,我给增加了注释,以便日后整理封装。
复制代码 代码如下:

<html><head><title>use A* to find path...</title></head>
<body style="margin:0px">
<script>
/*
written by hjjboy
email:tianmashuangyi@163.com
qq:156809986
*/
var closelist=new Array(),openlist=new Array();//closelist保存最终结果。openlist保存临时生成的点;
var gw=10,gh=10,gwh=14;//参数 gh是水平附加参数 gwh是四角的附加参数。
var p_start=new Array(2),p_end=new Array(2);//p_start为起点,p_end为终点
var s_path,n_path="";//s_path为当前点 n_path为障碍物数组样式的字符串.
var num,bg,flag=0;
var w=30,h=20;
function GetRound(pos){//返回原点周围的8个点
    var a=new Array();
    a[0]=(pos[0]+1)+","+(pos[1]-1);
    a[1]=(pos[0]+1)+","+pos[1];
    a[2]=(pos[0]+1)+","+(pos[1]+1);
    a[3]=pos[0]+","+(pos[1]+1);
    a[4]=(pos[0]-1)+","+(pos[1]+1);
    a[5]=(pos[0]-1)+","+pos[1];
    a[6]=(pos[0]-1)+","+(pos[1]-1);
    a[7]=pos[0]+","+(pos[1]-1);
    return a;
}
function GetF(arr){ //参数为原点周围的8个点
    var t,G,H,F;//F,综合的距离值,H,距离值 G,水平\角落附加计算
    for(var i=0;i<arr.length;i++){
        t=arr[i].split(",");
        t[0]=parseInt(t[0]);
        t[1]=parseInt(t[1]);
        if(IsOutScreen([t[0],t[1]])||IsPass(arr[i])||InClose([t[0],t[1]])||IsStart([t[0],t[1]])||!IsInTurn([t[0],t[1]]))
            continue;//如果上面条件有一满足,则跳过本次循环,进行下一次。
        if((t[0]-s_path[3][0])*(t[1]-s_path[3][1])!=0)//判断该点是否处于起点的垂直或横向位置上
            G=s_path[1]+gwh;//如果不在G=14;
        else
            G=s_path[1]+gw;//如果在G=10;
        if(InOpen([t[0],t[1]])){//如果当前点已存在openlist数组中
            if(G<openlist[num][1]){
            maptt.rows[openlist[num][4][1]].cells[openlist[num][4][0]].style.backgroundColor="blue";//调试
                openlist[num][0]=(G+openlist[num][2]);
                openlist[num][1]=G;
                openlist[num][4]=s_path[3];
            }
            else{G=openlist[num][1];}
        }
        else{
            H=(Math.abs(p_end[0]-t[0])+Math.abs(p_end[1]-t[1]))*gw;
            F=G+H;
            arr[i]=new Array();
            arr[i][0]=F;
            arr[i][1]=G;
            arr[i][2]=H;
            arr[i][3]=[t[0],t[1]];
            arr[i][4]=s_path[3];
            openlist[openlist.length]=arr[i];//将F等信息保存到openlist
        }
        if(maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#cccccc"&&maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#0000ff"&&maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#ff0000"&&maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#00ff00")
        {
            maptt.rows[t[1]].cells[t[0]].style.backgroundColor="#FF00FF";
            if(F!=undefined)
            maptt.rows[t[1]].cells[t[0]].innerHTML="<font color='black'>"+F+"</font>";
        }
    }
}
function IsStart(arr){ //判断该点是不是起点
    if(arr[0]==p_start[0]&&arr[1]==p_start[1])
        return true;
    return false;
}
function IsInTurn(arr){ //判断是否是拐角
    if(arr[0]>s_path[3][0]){
        if(arr[1]>s_path[3][1]){
            if(IsPass((arr[0]-1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]-1)))
                return false;
        }
        else if(arr[1]<s_path[3][1]){
            if(IsPass((arr[0]-1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]+1)))
                return false;
        }
    }
    else if(arr[0]<s_path[3][0]){
        if(arr[1]>s_path[3][1]){
            if(IsPass((arr[0]+1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]-1)))
                return false;
        }
        else if(arr[1]<s_path[3][1]){
            if(IsPass((arr[0]+1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]+1)))
                return false;
        }
    }
    return true;
}
function IsOutScreen(arr){ //是否超出场景范围
    if(arr[0]<0||arr[1]<0||arr[0]>(w-1)||arr[1]>(h-1))
        return true;
    return false;
}
function InOpen(arr){//获得传入在openlist数组的位置,如不存在返回false,存在为true,位置索引保存全局变量num中。
    var bool=false;
    for(var i=0;i<openlist.length;i++){
        if(arr[0]==openlist[i][3][0]&&arr[1]==openlist[i][3][1]){
            bool=true;num=i;break;}
    }
    return bool;
}
function InClose(arr){
    var bool=false;
    for(var i=0;i<closelist.length;i++){
        if((arr[0]==closelist[i][3][0])&&(arr[1]==closelist[i][3][1])){
            bool=true;break;}
    }
    return bool;
}
function IsPass(pos){ //pos这个点是否和障碍点重合 
    if((";"+n_path+";").indexOf(";"+pos+";")!=-1)
        return true;
    return false;
}
function Sort(arr){//整理数组,找出最小的F,放在最后的位置。
    var temp;
    for(var i=0;i<arr.length;i++){
        if(arr.length==1)break;
        if(arr[i][0]<=arr[i+1][0]){
            temp=arr[i];
            arr[i]=arr[i+1];
            arr[i+1]=temp;
        }
        if((i+1)==(arr.length-1))
            break;
    }
}
function main(){//主函数
        alert('');
        GetF(//把原点周围8点传入GetF进行处理。算A*核心函数了 :),进行求F,更新openlist数组
            GetRound(s_path[3]) //求原点周围8点
        );
    debugdiv.innerHTML+="A:"+openlist.join('|')+"<br />";//调试
        Sort(openlist);//整理数组,找出最小的F,放在最后的位置。
    debugdiv.innerHTML+="B:"+openlist.join('|')+"<br />";//调试
        s_path=openlist[openlist.length-1];//设置当前原点为F最小的点
        closelist[closelist.length]=s_path;//讲当前原点增加进closelist数组中
        openlist[openlist.length-1]=null;//从openlist中清除F最小的点
    debugdiv.innerHTML+="C:"+openlist.join('|')+"<br />";//调试
        if(openlist.length==0){alert("Can't Find the way");return;}//如果openlist数组中没有数据了,则找不到路径
        openlist.length=openlist.length-1;//上次删除把数据删了,位置还保留了,这里删除
        if((s_path[3][0]==p_end[0])&&(s_path[3][1]==p_end[1])){//如果到到终点了,描绘路径
            getPath();
        }
        else{//否则循环执行,标准原点
            maptt.rows[s_path[3][1]].cells[s_path[3][0]].style.backgroundColor="green";setTimeout("main()",100);
        }
}
function getPath(){//描绘路径
    var str="";
    var t=closelist[closelist.length-1][4];
    while(1){
        str+=t.join(",")+";";
        maptt.rows[t[1]].cells[t[0]].style.backgroundColor="#ffff00";
        for(var i=0;i<closelist.length;i++){
            if(closelist[i][3][0]==t[0]&&closelist[i][3][1]==t[1])
                t=closelist[i][4];
        }
        if(t[0]==p_start[0]&&t[1]==p_start[1])
            break;
    }
    alert(str);
}
function setPos(){//初始原点为起点
    var h=(Math.abs(p_end[0]-p_start[0])+Math.abs(p_end[1]-p_start[1]))*gw;
    s_path=[h,0,h,p_start,p_start];
}
function set(id,arr){//设置点的类型
    switch(id){
        case 1:
            p_start=arr;
            maptt.rows[arr[1]].cells[arr[0]].style.backgroundColor="#ff0000";break;
        case 2:
            p_end=arr;maptt.rows[arr[1]].cells[arr[0]].style.backgroundColor="#0000ff";break;
        case 3:
            n_path+=arr.join(",")+";";maptt.rows[arr[1]].cells[arr[0]].style.backgroundColor="#cccccc";break;
        default:
            break;
    }
}
function setflag(id){flag=id;}
</script>
<table id="maptt" cellspacing="1" cellpadding="0" border="0" bgcolor="#000000">
<script>
for(var i=0;i<h;i++){
    document.write("<tr>");
    for(var j=0;j<w;j++){
        document.write('<td onclick="set(flag,['+j+','+i+']);" bgcolor="#ffffff" width="20" height="20"></td>');
    }
    document.write("</tr>");
}
</script>
</table>
<a href="javascript:setflag(1);">StarPoint</a><br>
<a href='javascript:setflag(2);'>EndPoint</a><br>
<a href='javascript:setflag(3);'>Wall</a><br>
<input type="button" onclick="setPos();main();this.disabled=true;" value="find">
<div id="debugdiv"></div>
</body>
</html>

在发一个.net版本的实现 进入

相关文章

  • js浮点数精确计算(加、减、乘、除)

    js浮点数精确计算(加、减、乘、除)

    本篇文章主要介绍了js浮点数精确计算(加、减、乘、除) 需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • js精美的幻灯片画集特效代码分享

    js精美的幻灯片画集特效代码分享

    这篇文章主要介绍了js制作精美的幻灯片画集特效,视觉上特别有冲击感,推荐给大家,有需要的小伙伴可以参考下。
    2015-08-08
  • JavaScript数据操作_浅谈原始值和引用值的操作本质

    JavaScript数据操作_浅谈原始值和引用值的操作本质

    下面小编就为大家带来一篇JavaScript数据操作_浅谈原始值和引用值的操作本质。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • 类似框架的js代码

    类似框架的js代码

    类似框架的js代码...
    2006-11-11
  • 使用 JavaScript 制作页面效果

    使用 JavaScript 制作页面效果

    这篇文章主要介绍了使用 JavaScript 制作页面效果,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 基于JS实现操作成功之后自动跳转页面

    基于JS实现操作成功之后自动跳转页面

    这篇文章主要介绍了基于JS实现操作成功之后自动跳转页面的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 在 JavaScript 中如何更改字符串字符

    在 JavaScript 中如何更改字符串字符

    在本文中,我们将创建自定义函数,借助不同示例的默认字符串方法,在我们想要的任何位置替换或更改字符串中的字符,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-07-07
  • js时钟翻牌效果实现代码分享

    js时钟翻牌效果实现代码分享

    这篇文章主要介绍了javascript时钟翻牌效果的实现,效果非常酷炫,实现步骤也很简单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-08-08
  • 微信小程序上传图片到别的域名文件下的示例代码

    微信小程序上传图片到别的域名文件下的示例代码

    这篇文章主要介绍了微信小程序上传图片到别的域名文件下的示例代码,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-12-12
  • javascript tabIndex属性

    javascript tabIndex属性

    围绕表单的可访问性与交互性上,各浏览器都下了很大工夫,比如fieldset与legend等用于增强区域感的元素,for,accessKey,defaultValue,maxlength,tabIndex等用于交互或提示的属性。不过,今天只讲tabIndex。
    2009-12-12

最新评论