COCOS2D-X中45度地图通过位置获得对应行列数中的三角变换理解

来源:互联网 发布:工业企业数据库 161 编辑:程序博客网 时间:2024/04/30 11:13

晚上看COCOS2d-X的瓦片地图集这块,发现有2种地图,普通的和45度视角的。普通的通过位置获取所在行列数比较简单,大概就是具体的位置除以图素的宽高,而45度脚的方法则能够实现2.5D的效果,理解起来也相对困难一点。下面是一张45度的地图示意。


通过图中,我们发现其视觉定位与以往看见的不相同,在坐标的设定上也不一样,当光标放在上面顶点的时候,坐标为(0,0)表示为图素的标号(0,0),向右为第一个分量(可理解为X方向),向左为第二个分量(可理解为y方向)。这个要注意。而在选取位置的时候则需要按照地图的设定,向右为X方向,向上为Y方向,且处于GL的坐标绘制范围。相关的示例程序如下,其中引用了CCTMXTileMap,整体比较简单,但要注意其中的convertto2d函数,控制了相关的转换,使得可以在45度角地图中,获得相关的行列数。

void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){CCSetIterator it = pTouches->begin();    CCTouch* touch = (CCTouch*)(*it);        CCPoint m_tBeginPos = touch->locationInView();    m_tBeginPos = CCDirector::sharedDirector()->convertToGL( m_tBeginPos );         CCTMXTiledMap* map = (CCTMXTiledMap*) getChildByTag(1);     CCPoint mapp = map->getPosition();     CCPoint aimmapindex = <span style="background-color: rgb(51, 255, 51);">convertto2d(m_tBeginPos.x - mapp.x,m_tBeginPos.y - mapp.y)</span>;     if(aimmapindex.x < 0 || aimmapindex.y < 0 || aimmapindex.x >= map->getMapSize().width || aimmapindex.y >= map->getMapSize().height)     {     return;     }     CCTMXLayer* layer = map->layerNamed("grass");     layer->setTileGID(4,aimmapindex);}


下面是convertto2d函数的代码

CCPoint HelloWorld::convertto2d(float x,float y){CCTMXTiledMap* map = (CCTMXTiledMap*) getChildByTag(1);int mapWidth = map->getMapSize().width * map->getTileSize().width;int mapHeight = map->getMapSize().height * map->getTileSize().height;double distanse,sin1,sin11,sin22,cos11,cos1;int d2x,d2y;double mystatic5 = sqrt(5.0);double mystatic = 16 * mystatic5;if(<span style="background-color: rgb(51, 255, 51);">x > mapWidth/2</span>){        distanse = sqrt((x - mapWidth/2) * (x - mapWidth/2) + (mapHeight - y) * (mapHeight - y));        sin1 = (mapHeight - y)/distanse;        cos1 = (x - mapWidth/2)/distanse;        sin11 = (sin1 * 2 - cos1) / mystatic5;        cos11 = (sin1 + cos1 * 2) / mystatic5;        d2y = distanse * 5 / 4 * sin11 / mystatic;        sin22 = (2 * sin1 + cos1) / mystatic5;        d2x = distanse * 5 / 4 * sin22 / mystatic;        return ccp(d2x,d2y);}else{        distanse = sqrt((mapWidth/2 - x) * (mapWidth/2 - x) + (mapHeight - y) * (mapHeight - y));        sin1 = (mapHeight - y)/distanse;        cos1 = (mapWidth/2 - x)/distanse;        sin11 = (sin1 * 2 - cos1) / mystatic5;        cos11 = (sin1 + cos1 * 2) / mystatic5;        d2x = distanse * 5 / 4 * sin11 / mystatic;        //sin22 = 4.0 * cos11 / 5 + 3.0 * sin11 / 5;        sin22 = (2 * sin1 + cos1) / mystatic5;        d2y = distanse * 5 / 4 * sin22 / mystatic;        return ccp(d2x,d2y);}}
前面的计算部分都比较简单,要说明的是45角地图采用的是菱形,整个地图的对角线比例为2:1,因此斜边的比例为sqrt(5.0)。中间涉及到三角函数的转换和计算,具体的说明,我在纸上画了图形和说明。


发现通过对X的位置的划分,进行了左右的不同情况的计算,利用和差化积公司,倍角公式,正玄定理等等三角函数,利用已知的AC的长度,和可以计算出来的点C与水平线的夹角角1(见图中所示),继而计算出角11(图中所示),接着利用角度关系计算出来角CDA,最后得到相关结果,最后除以相关方向的图素大小即可得到相关的行列数。


开始找了很多资料,都没有找到仔细的介绍,还是自己下点功夫,好好专研下解决了是王道。加油!! 希望能帮到看到这里困惑的朋友。。



0 0
原创粉丝点击