游戏中45度地图的坐标转换

本站文章均为 ftyszyx 原创,转载务必在明显处注明: 原文链接: http://blog.csdn.net/ftyszyx/article/details/9020101


在游戏中,为了在二维平面呈现立体效果常常需要使用45度角地图,最近有用到,原本以为很简单,结果搞了好几天才搞明白,因此记录下,以防以后忘记

首先要清楚几个概念:

如下是一张地图


地图宽:size_W

地图高:size_H

地图块高:tile_H

地图块宽:tile_W

具体如上图所示。


现在我们假设地图上有一点A,屏幕坐标第的原理在O点基向量为(XY),地图坐标系的原点在M点,基向量分别为(MXMY)如下图:(注意,粗体是向量)


我们现在已知A点的屏幕坐标(x,y),地图原理M的屏幕坐标(size_W/2,size_H)要求A点的地图坐标(相对于地图坐标系),假设为(m,n)

MA=mMX+nMY

MX=tile_H/2X+(-tile_W/2)Y

MY=(-tile_H/2)X+(-tile_W/2)Y

所以可得MA的屏幕坐标表示:(m-n)*tile_H/2  X +(m+n)*(-tile_W/2) Y

因OA=OM+MA

所以可得OA=(size_W/2+(m-n)*tile_H/2 ) X +(size_H+(m+n)*(-tile_W/2) ) Y,

于是有了这两个等式:

x=size_W/2+(m-n)*tile_H/2 

   y=size_H+(m+n)*(-tile_W/2)

求解可得m=(x-size_W/2)/tile_H-(y-size_H)/tile_W;

            n=-(x-size_W/2)/tile_H-(y-size_H)/tile_W;

同理,也可以根据A的地图坐标求得A的屏幕坐标:

具体程序实现如下:

//将标准坐标转为地图坐标
CCPoint MapScene::converttomapPonit(float x,float y)
{
	//求map原点坐标
	CCTMXTiledMap* map = (CCTMXTiledMap*) getChildByTag(kTagTileMap);
	int tilewidth=map->getTileSize().width;
	int tilehigh=map->getTileSize().height;
	float mapOrginX=map->getPosition().x+map->getContentSize().width/2;
	float mapOrginy=map->getPosition().y+map->getContentSize().height;
	//O为地图的原点,A是要求的点,oa向量的值
	float OA_x=x-mapOrginX;
	float OA_y=y-mapOrginy;
	//假设以地图的原点为初始坐标(正上方那个点),对应的所示点的坐标值为m,n
	//将地图坐标(m,n)转为标准坐标,则有:
	//(x,y)-(mapOrginX,mapOrginy)=m(tilewidth/2,-tilehigh/2)+n(-tilewidth/2,-tilehigh/2)
	//因此m=(OA_x/(tilewidth/2)+OA_y/(-tilehigh/2)/2=OA_x/tilewidth-OA_y/tilehigh
	//n=(OA_y/(-tilehigh/2)-OA_x/(tilewidth/2))/2=-(OA_y/tilehigh+OA_x/tilewidth)
	float m=OA_x/tilewidth-OA_y/tilehigh;
	float n=-(OA_y/tilehigh+OA_x/tilewidth);
	if(m<0 ) m=0;
	if(n<0) n=0;
	if(m>map->getMapSize().width-1) m=map->getMapSize().width-1;
	if(n>map->getMapSize().height-1) n=map->getMapSize().height-1;
	return CCPoint((int)m,(int)n);
}
//将地图坐标转成屏幕坐标
CCPoint MapScene::convertTOSecenPoint(int x,int y)
{
	//求map原点坐标
	CCTMXTiledMap* map = (CCTMXTiledMap*) getChildByTag(kTagTileMap);
	float tilewidth=map->getTileSize().width;
	float tilehigh=map->getTileSize().height;
	//原点下移了到方块的中心
	int mapOrginX=map->getPosition().x+map->getContentSize().width/2;
	int mapOrginy=map->getPosition().y+map->getContentSize().height;
	if (x>map->getMapSize().width || x<0
		|| y>map->getMapSize().height || y<0)
	{//超出范围
		return CCPoint(0,0);
	}
	float OA_x=(x-y)*tilewidth/2.0;
	float OA_y=-(x+y)*tilehigh/2.0;
	return CCPoint(mapOrginX+OA_x,mapOrginy+OA_y);
}


  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值