论坛首页 Java企业应用论坛

斜45度游戏涉及到计算

浏览 3088 次
精华帖 (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;
	}
}




论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics