| 首页 | 新闻 | 网页 | 设计 | 色彩 | 原创 | 视觉 | 素材 | 动漫 | 酷站 | 策划 | 文案 | 访谈 | 运营 | 编程 | 数据库 | 服务器 | 下载 | 图库 | 
您的位置: 幽幽天空 > 网页 > 网页制作 > Flash教程 > ActionScript教程 > 文章正文 用户登录
Blog站点如何用RS
如何优化Blog来提
如何从博客赚钱。
Web 2.0,如何创造
如何发挥Blog的互
企业如何进行博客
如何建立自己的博
如何从博客赚钱
请问如何利用博客
如何推广你的博客

如何使用AI(人工智能)计算路径           

如何使用AI(人工智能)计算路径

作者:佚名 来源:闪吧 作者: Super-Tomato 更新:2007-1-13 20:49:07 错误报告 我要投稿

因為AI比較複雜, 所以我不一定全部會解釋... 因為在判斷的地方很難說明.. 這就要看看你們平常的學習了... 在這裡都是使用數組來記錄路徑和判斷, 重要的部份我會以紅色的部份註明, 還是看看所謂的AI計算最短的路徑是例子
点击浏览该文件

好啦.... 開始大概就是mapping(中文不會解釋>_<), 在這裡我并不是使用3D Mapping, 而只是普通的2D方法...首先是做3個幀的MC(使用linkage), 如圖

   按此在新窗口浏览图片

然後使用xml來編排地圖部份

<?xml version="1.0"?>
<GRID>
                <ROW>0010000100</ROW>
                <ROW>0000001100</ROW>
                <ROW>0001010100</ROW>
                <ROW>0000010000</ROW>
                <ROW>0101010000</ROW>
                <ROW>0001000111</ROW>
                <ROW>0101010100</ROW>
                <ROW>0111000110</ROW>
                <ROW>0000000000</ROW>
                <ROW>0000000000</ROW>
</GRID>
接下來到AS代碼部份了

取得XML所記錄的地圖編排位置

XML.prototype.ignoreWhite = true;
myXML = new XML();
myXML.load("map.xml");
myXML.onLoad = function(success) {
   if (success) {
      myMap = new Array();
      var x = myXML.firstChild.childNodes;
      for (var i = 0; i<x.length; i++) {
         var myString = x[i].firstChild.nodeValue;
         var temp = new Array();
         for(var j=0; j<myString.length; j++) {
            temp.push(int(myString.charAt(j)));    //把XML文件中的記錄轉換成數字
         }
         myMap.push(temp);
      }
      delete myXML;          //取得所有資料後刪除xml, 以減少記憶體佔用
      mapping();       //開始做地圖
   }
};
   
開始根據數組編排地圖

function mapping() {
   var width = 28.2;          //每格位置的寬度
   var height = 10.2;       //每格位置的高度
   var dx = 0;
   var dy = 0;
   _global.startPosition = new Array(8,5);          //物件的定位
   for(var i=0; i<myMap.length; i++) {
      for(var j=0; j<myMap[i].length; j++) {
         var mc = _root.attachMovie("box", "box"+i+j, i*myMap.length+j);          //使用attachMovie把上面所做的MC排列
         if (myMap[i][j] == 1) {          //如果數組當中的值是1就代表是阻擋物件
            mc.gotoAndStop(2);
         }
         if (myMap[i][j] == 0) {          //可行走的部份
            mc.onRollOver = function() {       //鼠標移到這個可行走的方塊就取得此方塊的位置
               this.x = this._name.substr(3, 1);
               this.y = this._name.substr(4, 1);
            };
            mc.onRelease = function() {
               validate(this.x, this.y);          //當鼠標點下的時候開始做AI方面的計算
            };
         }
         mc._x = 250+dx;
         mc._y = 50+dy;
         dx = dx+width;
         dy = dy+height;
      }
      dx = -((i+1)*(width-7));
      dy = (i+1)*21;
      j = 0;
   }
   myMap[startPosition[0]][startPosition[1]] = 0;
   _root[("box"+startPosition[0])+startPosition[1]].gotoAndStop(3);       //物件
}
   
當鼠標點下時所需要定義的部份

function validate(r, c) {
   newpath = new PathFinder(myMap);    //使用類來定義
   newpath.finalPosition = [r, c];       //最終位置, 就是鼠標點下的座標位置
   newpath.startPosition = startPosition.slice();       //取得物件一開始的座標
   _global.finalPosition = [r, c];          //定義一個全域變量
   if ((newpath.startPosition[0] != newpath.finalPosition[0]) || (newpath.startPosition[1] != newpath.finalPosition[1])) {          //檢察物件開始的位置是不是就是最終的位置, 不是就開始計算
      newpath.init();       //路徑定義
      newpath.findPath();          //**找出最短路徑的計算...
   }
};

function PathFinder(myArray) {             //定義4組數組來記錄路徑的座標位置
   this.myMap = myArray;
   this.finalPosition = new Array();
   this.startPosition = new Array();
   this.openList = new Array();
   this.closedList = new Array();
};

PathFinder.prototype.init = function() {          //使用node來記錄位置,步數和距離等
   var startNode = new structNode(this.startPosition, 0, 0, 0);
   this.openList.push(startNode);       //把node儲存在數組內
};

PathFinder.prototype.findPath = function() {       //**重要部份
   while (this.openList.length>0) {
      var max = 1000;
      var lastOne = -1;
      var a = 0;
      while (a<this.openList.length) {          //取得最後一組openList數組中的node
         if (this.openList[a].f<max) {
            max = this.openList[a].f;       //步數
            lastOne = a;
         }
         a++;
      }
      var node = this.openList.splice(lastOne, 1);
      node = node[0];
      if (node.pos_str == this.finalPosition.toString()) {       //如果數組的最後一組是最終座標就執行
         this.closedList.push(node);
         var cur = this.closedList[this.closedList.length-1];
         startPosition = cur.pos;
         _root[("box"+this.startPosition[0])+this.startPosition[1]].gotoAndStop(1);    //把原本起點的物件換成普通的地圖
         _root[("box"+this.finalPosition[0])+this.finalPosition[1]].gotoAndStop(3);
         while (cur.parent != undefined) {
            _root[("box"+cur.pos[0])+cur.pos[1]].mask.gotoAndPlay(2);       //我例子中小球
            cur = cur.parent;
         }
         return (undefined);
      }
      var successors = this.getDirection(node.pos);       //取得目前位置可供行走的座標位置
      var a = 0;
      while (a<successors.length) {       //返回的長度最大為4, 即上下左右都沒有阻擋物
         var _skip = false;
         var struct = new structNode(successors[a]);    //同上...   
         struct.parent = node;

       //這裡會依照返回的數組座標判斷出最短的距離(根據步數)
         struct.g = node.g+this.getDistance(struct.pos, node.pos);
         struct.h = this.getDistance(struct.pos, this.finalPosition);
         struct.f = struct.g+struct.h;


         for (var b in this.openList) {         檢察下一步數組的座標是不是和目前相同
            if ((this.openList[b].pos_str == struct.pos_str) && (this.openList[b].f<struct.f)) {
               _skip = true;
               break;
            }
         }
         
         for (var b in this.closedList) {
            if ((this.closedList[b].pos_str == struct.pos_str) && (this.closedList[b].f<struct.f)) {
               _skip = true;
               break;
            }
         }
         
         if (_skip == false) {            
            for (var c in this.openList) {
               if (this.openList[c].pos_str == struct.pos_str) {
                  this.openList.splice(c, 1);
               }
            }
            for (var c in this.closedList) {
               if (this.closedList[c].pos_str == struct.pos_str) {
                  this.closedList.splice(c, 1);
               }
            }
            this.openList.push(struct);       //把下一步最接近終點的座標儲存在openList數組
         }
         a++;
      }
      this.closedList.push(node);
   }
};

判斷可行走的方向

PathFinder.prototype.getDirection = function(pos) {
   var r = Number(pos[0]);       //pos是目前座標
   var c = Number(pos[1]);
   var ret = new Array();

    //判斷上下左右方向
   if (this.myMap[r-1][c] == 0) {            
      ret.push([r-1, c]);
   }
   if (this.myMap[r][c+1] == 0) {
      ret.push([r, c+1]);
   }
   if (this.myMap[r+1][c] == 0) {
      ret.push([r+1, c]);
   }
   if (this.myMap[r][c-1] == 0) {
      ret.push([r, c-1]);
   }
   return (ret);
};

距離計算

PathFinder.prototype.getDistance = function(pos1, pos2) {      
   var d1 = Math.abs(pos2[0]-pos1[0]);
   var d2 = Math.abs(pos2[1]-pos1[1]);
   return (d1+d2);
};

   

好啦.... 就到這裡就完成了... 這是一般的計算方法...希望有高手補充說明或提供更有效的算法...^^

再來你們也可以把部份代碼編寫成2.0的類方式 :)

   

有興趣的朋友可以參考這個網址:http://www.policyalmanac.org/games/aStarTutorial.htm



抱歉....因為一直思考怎麼解釋所以忘記貼了一段類...^^", 在這裡補上 :p

          function structNode(pos, f, g, h, parent) {
                      this.pos = pos.slice();
                      this.f = f;
                      this.g = g;
                      this.h = h;
                      this.parent = parent;
                      this.pos_str = this.pos.toString();
          }


   

                structNode.prototype.toString = function () {
                      return ((((((("[" + this.pos_str) + "], f=") + this.f) + ", g=") + this.g) + ", h=") + this.h);
          };
   

記得重點是在 f = g + h

g 是開始到目前的移動距離

h 是估計目前點到目標的距離

文章录入:skyuu    责任编辑:skyuu 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    发表评论:
    姓名:  评 分: 1分 2分 3分 4分 5分
     
  • 严禁发表危害国家安全、政治、黄色淫秽等内容的评论。
  • 用户需对自己在使用幽幽天空服务过程中的行为承担法律责任。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表机友个人观点,与本网站立场无关。