`
songdawei001
  • 浏览: 51542 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

斜45度游戏涉及到计算

阅读更多

比方说定义格子的长度(W=80像素),高度(H=40像素) 
Constants.TILE_WIDTH = 80; 
Constants.TILE_HEIGHT= 40; 
Constants.TILE_WIDTH_2 = 80/2; 
Constants.TILE_HEIGHT_2= 40/2; 

1:格子坐标与像素坐标的互相转换公式 
1.1:格子坐标转像素坐标
   /**
     * 像素坐标转换成斜45度的格子坐标
     * @param px  像素X坐标
     * @param py  像素Y坐标
     * @return
     */
    public static short[] pixToTile(int px,int py){
    	int cx = (px/Constants.TILE_WIDTH)*Constants.TILE_WIDTH+Constants.TILE_WIDTH_2;
    	int cy = (py/Constants.TILE_HEIGHT)*Constants.TILE_HEIGHT+Constants.TILE_HEIGHT_2;	
    	int rx = (px-cx)*Constants.TILE_HEIGHT_2;
    	int ry = (py-cy)*Constants.TILE_WIDTH_2;
    	int tx,ty;
    	if((Math.abs(rx)+Math.abs(ry))<=(Constants.TILE_WIDTH*Constants.TILE_HEIGHT/4)){
    		tx = px/Constants.TILE_WIDTH;
    		ty = (py/Constants.TILE_HEIGHT)*2;
    	}else{
    		px = px-Constants.TILE_WIDTH_2;
    		tx = px/Constants.TILE_WIDTH+1;
    		py = py-Constants.TILE_HEIGHT_2;
    		ty = (py/Constants.TILE_HEIGHT)*2+1;
		}
    	tx = tx-(ty&1);
    	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;
	}
}




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics