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

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

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

通过图中,我们发现其视觉定位与以往看见的不相同,在坐标的设定上也不一样,当光标放在上面顶点的时候,坐标为(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 = convertto2d(m_tBeginPos.x - mapp.x,m_tBeginPos.y - mapp.y);
     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(x > mapWidth/2){
        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)。中间涉及到三角函数的转换和计算,具体的说明,我在纸上画了图形和说明。

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


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


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



你可能感兴趣的:(cocos2dx,cocos2d-x,地图,45度角地图,三角变换,convertto2d)