浏览 3088 次
锁定老帖子 主题:斜45度游戏涉及到计算
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-30
比方说定义格子的长度(W=80像素),高度(H=40像素) Constants.TILE_WIDTH = 80; Constants.TILE_HEIGHT= 40; 1:格子坐标与像素坐标的互相转换公式 1.1:格子坐标转像素坐标 /** * 像素坐标转换成斜45度的格子坐标 * @param px 像素X坐标 * @param py 像素Y坐标 * @return */ public static short[] pixToTile(int px,int py){ int ty= 2*py/Constants.TILE_HEIGHT-1; if(ty<0){ log.error("ty:"+py); ty = 0; } int tx= (px-(ty&1)*(Constants.TILE_WIDTH/2))/Constants.TILE_WIDTH; if(tx<0){ log.error("tx:"+px); tx = 0; } return new short[]{(short)tx,(short)ty}; } 1.2:像素坐标转格子坐标 /** * 斜45度的格子坐标转换成像素坐标 * @param tx 斜45度的格子X坐标 * @param ty 斜45度的格子Y坐标 * @return */ public static short[] tileToPix(int tx,int ty){ int px=(tx*Constants.TILE_WIDTH+((ty&1)+1)*(Constants.TILE_WIDTH/2)); int py=(ty+1)*(Constants.TILE_HEIGHT/2); return new short[]{(short)px,(short)py}; } 2:两格子坐标四方向相差的格子数计算 /** * 忽略地图地形(计算两个格子之间经过的格子数) * @param bx 开始格子X坐标 * @param by 开始格子Y坐标 * @param ex 目标格子X坐标 * @param ey 目标格子Y坐标 * @return */ public static int getTileNumFromTile(short bx,short by,short ex,short ey){ short[] beginPix = tileToPix(bx,by); short[] endPix = tileToPix(ex,ey); int subX = Math.abs(endPix[0]-beginPix[0])/(Constants.TILE_WIDTH/2); int subY = Math.abs(endPix[1]-beginPix[1])/(Constants.TILE_HEIGHT/2); return Math.max(subX, subY); } 3:靠近某目标格子的相关计算 /** * 获取以此格子坐标(x,y)为中心的四个方向的其他格子坐标 * @param x * @param y * @return */ public static short[][] getNext4(short x,short y){ short[][] nextXy= new short[4][2]; //Y坐标偶数时 X坐标减1 if(y%2==0){ short preX = (short)(x-1); short preY = (short)(y-1); short nexY = (short)(y+1); nextXy[0]=new short[]{preX,preY}; nextXy[1]=new short[]{preX,nexY}; nextXy[2]=new short[]{x,preY}; nextXy[3]=new short[]{x,nexY}; }else{ short preY = (short)(y-1); short nexY = (short)(y+1); short nextX = (short)(x+1); nextXy[0]=new short[]{x,preY}; nextXy[1]=new short[]{x,nexY}; nextXy[2]=new short[]{nextX,preY}; nextXy[3]=new short[]{nextX,nexY}; } return nextXy; } /** * 找出最短格子路线 * @param map 地图数据 * @param begin 起点位置数据 * @param end 目标位置格子坐标 * @param moveAbility 可移动的格子数 * @param areaNum 所占格子数 * @param isOmit 忽略地形 * @return */ public static Object[] findMinTileLine(byte[][]map,SlgNode begin,short[] end,byte moveAbility,byte areaNum,boolean isOmit){ //最小格子数 int minNums = getTileNumFromTile(begin.getTx(),begin.getTy(),end[0],end[1]); if(minNums<2)return null; if(areaNum>1){ short[][] infos = getTopArea(begin.getTx(),begin.getTy(),areaNum); for(int i=1;i<infos.length;i++){ int tmpNums = getTileNumFromTile(infos[i][0],infos[i][1],end[0],end[1]); if(tmpNums<minNums){ minNums = tmpNums; if(minNums < 2) return null; } } } int curr=0; SlgNode node = begin; while(curr<moveAbility){ //找出周围四个格子离目标的位置 short[][] data = getNext4(node.getTx(),node.getTy()); SlgNode minNode = null; int omit = (isOmit?2:1); for(int i=0;i<data.length;i++){ short tx =data[i][0],ty =data[i][1]; //格子位置是否合法(没有被障碍物阻止) if(ty>=0&&ty<map.length&&tx>=0&&tx<map[0].length&&map[ty][tx]<omit){ int tmpNums = getTileNumFromTile(tx,ty,end[0],end[1]); boolean isFlag = true; //如果是占用多格子的检测其他的格子是否合法 if(areaNum>1){ short[][] infos = getTopArea(tx,ty,areaNum); for(int j=1;j<infos.length;j++){ short tx0 = infos[j][0],ty0=infos[j][1]; if(ty0<map.length&&tx0 <map[0].length && ty0>=0&&tx0>=0&&map[ty0][tx0]<omit){ if(tmpNums>1){ int tmpNums0 = getTileNumFromTile(tx0,ty0,end[0],end[1]); if(tmpNums0<tmpNums)tmpNums = tmpNums0; } }else{ isFlag = false;break; } } } if(tmpNums<minNums && isFlag){ minNode= new SlgNode(tx,ty,(byte)(node.getLen()+1)); minNode.setParent(node); if(tmpNums<2)return new Object[]{minNode,tmpNums}; minNums = tmpNums; } } } if(minNode==null)return curr==0?null:new Object[]{minNode,minNums}; curr++; node = minNode; } return new Object[]{node,minNums}; } /** * SLG移动格子坐标数据定义 * @author Administrator * */ public class SlgNode implements Comparable<SlgNode>{ //格子坐标 private short tx; private short ty; //父节点 private SlgNode parent; //步长 private byte len; public SlgNode(){ } public SlgNode(short tx,short ty,byte len){ this.tx = tx; this.ty= ty; this.len = len; } public short getTx() { return tx; } public void setTx(short tx) { this.tx = tx; } public short getTy() { return ty; } public void setTy(short ty) { this.ty = ty; } public SlgNode getParent() { return parent; } public void setParent(SlgNode parent) { this.parent = parent; } public byte getLen() { return len; } public void setLen(int len) { this.len = (byte)len; } public static String getCode(int x,int y){ return x+"_"+y; } public String getCode(){ return getCode(tx,ty); } public String toString(){ StringBuilder path = new StringBuilder().append("[").append(tx).append(",").append(ty).append("][").append(len).append("]"); if(this.parent!=null){ path.append("->").append(this.parent.toString()); } return path.toString(); } public int compareTo(SlgNode o) { if(len>0 && o.getLen()>0){ return len-o.getLen(); }else if(o.getLen()>0){ return 1; } return 0; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |