• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            屏幕坐標位置的確定用公式計算:
            屏幕的x坐標=地圖格子邏輯數組中的位置X * 格子寬度
            屏幕的y坐標=地圖格子邏輯數組中的位置Y * 格子高度/2

            得到的圖應該是這樣的:

            那么這個公式是怎樣得到呢?




            這個地圖有5行,看著這個地圖你會想,怎么拼圖才能將地圖拼出來。再畫張圖來演示:






            從這張圖可以看出,拼圖時從左到右,從上到下,跟正規的矩形拼圖一樣,唯一同的是,地圖元素與元素之間有重疊,看看第一行和第二行之間,第二行的地圖元素會壓在第一行的元素上,而第三行的的地圖元素則壓在第二行的元素上。所以,只要找到正確的公式,你就能正確地設計程序,再來一張圖:





            圖上綠點(是高亮度綠色,不是暗綠色)是每塊地圖元素的起點,第一行的行坐標是0,第二行的行坐標是1,第三行的行坐標是2,......由這些行坐標決定你的地圖元素的起點,從這個規律中看出行坐標0,和行坐標2的橫向坐標X的起點是一樣的是0,行坐標為1的起點是向右移半塊地圖元素。
            再從縱向坐標找規律,看行坐標0和行坐標2,兩塊地圖元素之間的距離剛好是一塊地圖元素的高。再看看行坐標0和行坐標1,兩塊地圖元素之間的距離剛好是半塊地圖元素的高。所以,計算每塊地圖元素的位置,你的轉換屏幕坐標和邏輯公式剛好是:
            logic.y = ( 2 * stage.y ) / TileHeigth;
            logic.x = ( stage.x / TileWidth ) - ( logic.y & 1 ) * ( TileWidth / 2 );
            stage.x = logic.x * TileWidth + ( logic.y & 1) * ( TileWidth / 2 );
            stage.y = logic.y * TileHeigth / 2;
            其中TileHeigth和TileWidth是菱形的高和寬,這樣你可以再嘗試著定義(0,1),(0,2),(0,3)等點,和得到的結果完全一樣···

            重要:
            首先以上的公式只適用于Staggered斜45度角地圖,而slide,和Diamond形地圖,這個公式要稍加修改才能用。
            Staggered:



            Slide:



            Diamond:




            而得到的邏輯坐標就是把了斜45度得到的實際坐標么?當然不是···
            仔細觀察,如果我們想用一個直角的坐標來表示這個地圖,那么大家可能開發起來也更加直觀一些,看這個坐標表示出來的y軸都是扭曲的用起來實在不爽,那么我們來將它轉換到直角坐標,那么再來加上尋路等算法都沒有任何難度了

            首先我們將地圖的高進行轉換,這個轉換主要是將菱形還原成正方形,例如菱形的高寬比是2:1,那么在地圖上則需要將地圖高度擴大一倍,然后旋轉-45度,那么得到對應坐標如下




            我們更加仔細的對這個圖的坐標進行

             1 /*
             2  
             3 * @author myth815 
             4 */ 
             5 package ContainerObjectManager 
             6 
             7 import flash.geom.Point; 
             8 import Math; 
             9 public class PointExchange 
            10 
            11 private static var TileWidth : int = 60
            12 private static var TileHeigth : int = 30
            13 public function PointExchange() 
            14 
            15 //this Class not allow init! 
            16 
            17 
            18 public static function StageToLogic(stage:Point):Point 
            19 
            20 var logic : Point = new Point; 
            21 logic.y = ( 2 * stage.y ) / TileHeigth; 
            22 logic.x = ( stage.x / TileWidth ) - ( logic.y & 1 ) * ( TileWidth / 2 ); 
            23 return logic; 
            24 
            25 
            26 public static function LogicToStage(logic:Point):Point 
            27 
            28 var stage : Point = new Point; 
            29 stage.x = logic.x * TileWidth + ( logic.y & 1* ( TileWidth / 2 ); 
            30 stage.y = logic.y * TileHeigth / 2
            31 return stage; 
            32 
            33 
            34 

            標注:

             

              1 比方說定義格子的長度(W=80像素),高度(H=40像素)    
              2 Constants.TILE_WIDTH = 80;    
              3 Constants.TILE_HEIGHT= 40;    
              4 1:格子坐標與像素坐標的互相轉換公式    
              5 1.1:格子坐標轉像素坐標   
              6    /**  
              7      * 像素坐標轉換成斜45度的格子坐標  
              8      * @param px  像素X坐標  
              9      * @param py  像素Y坐標  
             10      * @return  
             11      */  
             12     public static short[] pixToTile(int px,int py){   
             13         int ty= 2*py/Constants.TILE_HEIGHT-1;   
             14         if(ty<0){   
             15             log.error("ty:"+py);   
             16             ty = 0;   
             17         }   
             18         int tx= (px-(ty&1)*(Constants.TILE_WIDTH/2))/Constants.TILE_WIDTH;   
             19         if(tx<0){   
             20             log.error("tx:"+px);   
             21             tx = 0;   
             22         }   
             23         return new short[]{(short)tx,(short)ty};   
             24     }   
             25 1.2:像素坐標轉格子坐標   
             26 /**  
             27      * 斜45度的格子坐標轉換成像素坐標  
             28      * @param tx 斜45度的格子X坐標  
             29      * @param ty 斜45度的格子Y坐標  
             30      * @return  
             31      */  
             32     public static short[] tileToPix(int tx,int ty){   
             33         int px=(tx*Constants.TILE_WIDTH+((ty&1)+1)*(Constants.TILE_WIDTH/2));   
             34         int py=(ty+1)*(Constants.TILE_HEIGHT/2);   
             35         return new short[]{(short)px,(short)py};   
             36     }   
             37   
             38   
             39   
             40 2:兩格子坐標四方向相差的格子數計算    
             41   
             42 /**  
             43      * 忽略地圖地形(計算兩個格子之間經過的格子數)  
             44      * @param bx 開始格子X坐標  
             45      * @param by 開始格子Y坐標  
             46      * @param ex 目標格子X坐標  
             47      * @param ey 目標格子Y坐標  
             48      * @return  
             49      */  
             50     public static int getTileNumFromTile(short bx,short by,short ex,short ey){   
             51         short[] beginPix =  tileToPix(bx,by);   
             52         short[] endPix =  tileToPix(ex,ey);   
             53         int subX = Math.abs(endPix[0]-beginPix[0])/(Constants.TILE_WIDTH/2);   
             54         int subY = Math.abs(endPix[1]-beginPix[1])/(Constants.TILE_HEIGHT/2);   
             55         return Math.max(subX, subY);   
             56     }   
             57   
             58 3:靠近某目標格子的相關計算    
             59   
             60 /**  
             61      * 獲取以此格子坐標(x,y)為中心的四個方向的其他格子坐標  
             62      * @param x  
             63      * @param y  
             64      * @return  
             65      */  
             66     public static short[][] getNext4(short x,short y){   
             67         short[][] nextXy= new short[4][2];   
             68         //Y坐標偶數時 X坐標減1   
             69         if(y%2==0){   
             70             short preX = (short)(x-1);   
             71             short preY = (short)(y-1);   
             72             short nexY = (short)(y+1);   
             73             nextXy[0]=new short[]{preX,preY};   
             74             nextXy[1]=new short[]{preX,nexY};   
             75             nextXy[2]=new short[]{x,preY};   
             76             nextXy[3]=new short[]{x,nexY};   
             77         }else{   
             78             short preY = (short)(y-1);   
             79             short nexY = (short)(y+1);   
             80             short nextX = (short)(x+1);   
             81             nextXy[0]=new short[]{x,preY};   
             82             nextXy[1]=new short[]{x,nexY};   
             83             nextXy[2]=new short[]{nextX,preY};   
             84             nextXy[3]=new short[]{nextX,nexY};   
             85         }   
             86         return nextXy;   
             87     }   
             88   
             89   
             90 /**  
             91      * 找出最短格子路線  
             92      * @param map 地圖數據  
             93      * @param begin 起點位置數據  
             94      * @param end 目標位置格子坐標  
             95      * @param moveAbility 可移動的格子數  
             96      * @param areaNum 所占格子數  
             97      * @param isOmit 忽略地形  
             98      * @return  
             99      */ public static Object[] findMinTileLine(byte[][]map,SlgNode begin,short[] end,byte moveAbility,byte areaNum,boolean isOmit){   
            100         //最小格子數   
            101         int minNums = getTileNumFromTile(begin.getTx(),begin.getTy(),end[0],end[1]);   
            102         if(minNums<2)return null;   
            103         if(areaNum>1){   
            104             short[][] infos = getTopArea(begin.getTx(),begin.getTy(),areaNum);   
            105             for(int i=1;i<infos.length;i++){   
            106                 int tmpNums = getTileNumFromTile(infos[i][0],infos[i][1],end[0],end[1]);   
            107                 if(tmpNums<minNums){   
            108                     minNums = tmpNums;   
            109                     if(minNums < 2return null;   
            110                 }   
            111             }   
            112         }   
            113         int curr=0;   
            114         SlgNode node = begin;   
            115         while(curr<moveAbility){   
            116             //找出周圍四個格子離目標的位置   
            117             short[][] data = getNext4(node.getTx(),node.getTy());   
            118             SlgNode minNode = null;   
            119                             int   omit = (isOmit?2:1);   
            120   
            121             for(int i=0;i<data.length;i++){   
            122                 short tx =data[i][0],ty =data[i][1];   
            123                                 //格子位置是否合法(沒有被障礙物阻止)   
            124                 if(ty>=0&&ty<map.length&&tx>=0&&tx<map[0].length&&map[ty][tx]<omit){   
            125                     int tmpNums = getTileNumFromTile(tx,ty,end[0],end[1]);   
            126                     boolean isFlag = true;   
            127                     //如果是占用多格子的檢測其他的格子是否合法   
            128                     if(areaNum>1){   
            129                         short[][] infos = getTopArea(tx,ty,areaNum);   
            130                         for(int j=1;j<infos.length;j++){   
            131                             short tx0 = infos[j][0],ty0=infos[j][1];   
            132                             if(ty0<map.length&&tx0 <map[0].length && ty0>=0&&tx0>=0&&map[ty0][tx0]<omit){   
            133                                 if(tmpNums>1){   
            134                                     int tmpNums0 = getTileNumFromTile(tx0,ty0,end[0],end[1]);   
            135                                     if(tmpNums0<tmpNums)tmpNums = tmpNums0;   
            136                                 }   
            137                             }else{   
            138                                 isFlag = false;break;   
            139                             }   
            140                         }   
            141                     }   
            142                     if(tmpNums<minNums && isFlag){   
            143                         minNode= new SlgNode(tx,ty,(byte)(node.getLen()+1));   
            144                         minNode.setParent(node);   
            145                         if(tmpNums<2)return new Object[]{minNode,tmpNums};   
            146                         minNums = tmpNums;   
            147                     }   
            148                 }   
            149             }   
            150             if(minNode==null)return curr==0?null:new Object[]{minNode,minNums};   
            151             curr++;   
            152             node = minNode;   
            153         }   
            154         return new Object[]{node,minNums};   
            155     }   
            156   
            157   
            158   
            159 /**  
            160  * SLG移動格子坐標數據定義  
            161  * @author Administrator  
            162  *  
            163  */  
            164 public class SlgNode implements Comparable<SlgNode>{   
            165     //格子坐標   
            166     private short tx;   
            167     private short ty;   
            168     //父節點   
            169     private SlgNode parent;   
            170     //步長   
            171     private byte len;   
            172        
            173     public SlgNode(){   
            174            
            175     }   
            176        
            177        
            178     public SlgNode(short tx,short ty,byte len){   
            179         this.tx = tx;   
            180         this.ty= ty;   
            181         this.len = len;   
            182     }   
            183        
            184     public short getTx() {   
            185         return tx;   
            186     }   
            187     public void setTx(short tx) {   
            188         this.tx = tx;   
            189     }   
            190     public short getTy() {   
            191         return ty;   
            192     }   
            193     public void setTy(short ty) {   
            194         this.ty = ty;   
            195     }   
            196     public SlgNode getParent() {   
            197         return parent;   
            198     }   
            199     public void setParent(SlgNode parent) {   
            200         this.parent = parent;   
            201     }   
            202     public byte getLen() {   
            203         return len;   
            204     }   
            205     public void setLen(int len) {   
            206         this.len = (byte)len;   
            207     }   
            208        
            209     public static String getCode(int x,int y){   
            210         return x+"_"+y;   
            211     }   
            212        
            213     public String getCode(){       
            214         return getCode(tx,ty);   
            215     }   
            216        
            217     public String toString(){   
            218         StringBuilder path = new StringBuilder().append("[").append(tx).append(",").append(ty).append("][").append(len).append("]");   
            219         if(this.parent!=null){   
            220             path.append("->").append(this.parent.toString());   
            221         }   
            222         return path.toString();   
            223     }   
            224   
            225     public int compareTo(SlgNode o) {   
            226         if(len>0 && o.getLen()>0){   
            227             return len-o.getLen();   
            228         }else if(o.getLen()>0){   
            229             return 1;   
            230         }   
            231         return 0;   
            232     }   
            233 }  
            234 

             

            99精品久久精品一区二区| 9191精品国产免费久久| 久久婷婷五月综合97色直播| 国产高潮国产高潮久久久91| 久久久久国产精品嫩草影院| 国产69精品久久久久观看软件| 久久久久久久精品妇女99| 青青国产成人久久91网| 欧美亚洲国产精品久久久久| www.久久热.com| 久久综合亚洲色HEZYO国产| 人妻丰满AV无码久久不卡| 久久久久久久久久久免费精品| 一本色综合久久| 国产福利电影一区二区三区,免费久久久久久久精 | 99久久精品免费看国产| 2021最新久久久视精品爱| 亚洲一本综合久久| 无码人妻久久一区二区三区 | 久久久久久久亚洲Av无码| 久久精品视屏| 亚洲一区二区三区日本久久九| 精品久久久无码人妻中文字幕| 伊人色综合久久天天| 久久99亚洲网美利坚合众国| 午夜精品久久久久久久无码| 91亚洲国产成人久久精品网址| 久久精品国产精品亚洲毛片| 色妞色综合久久夜夜| 精品国产乱码久久久久软件| 国产午夜福利精品久久| 欧美日韩中文字幕久久伊人| 久久国产热精品波多野结衣AV| 性色欲网站人妻丰满中文久久不卡| 亚洲v国产v天堂a无码久久| 国产农村妇女毛片精品久久| 久久综合狠狠综合久久激情 | 97精品国产91久久久久久| 久久精品成人免费网站| 狠狠色丁香久久婷婷综| 婷婷综合久久狠狠色99h|