您的位置:首页 > 其它

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

2013-06-04 11:16 387 查看
本站文章均为 ftyszyx 原创,转载务必在明显处注明: 原文链接: /article/10497129.html

在游戏中,为了在二维平面呈现立体效果常常需要使用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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: