原文链接
要实现的效果如下:
即是要求人物在移动的时候,保持地图滚动,因为地图足够长的时候,不能让人物一出场就跑出屏幕的范围,而要使其在屏幕上跑完整个地图。效果如上图示。
这个实现就用到了上面所说的坐标系的理解,精灵的坐标系是相对于其所在的图层而言的。
当精灵的横坐标小于屏幕的横坐标时候,可以使精灵继续向前移动,如下:
但是当精灵的坐标大于屏幕的一般的时候,如果不采取措施,精灵就会继续向前移动,直至走出屏幕,那么应该采取什么行动呢?
首先我们已经明白,精灵的所谓的坐标是相对于图层而言的,因此实际上精灵向前移动仅仅是相对于下面的地图的移动,如果地图也以相同的变化移动的话,那么精灵和地图在我们看来就是相对静止的。(坐标参考系的不同)。这个时候精灵的坐标虽然在变化,但是在屏幕的位置却没有变化,但是精灵确实在走地图。
还是上代码吧:
- void Player::setViewPointByPlayer() {
- if (m_sprite == NULL) {
- return;
- }
- Layer* parent = (Layer*)getParent();
-
-
- Size mapTiledNum = m_map->getMapSize();
-
-
- Size tiledSize = m_map->getTileSize();
-
-
- Size mapSize = Size(
- mapTiledNum.width * tiledSize.width,
- mapTiledNum.height * tiledSize.height);
-
-
- Size visibleSize = Director::getInstance()->getVisibleSize();
-
-
- Point spritePos = getPosition();
-
-
- float x = std::max(spritePos.x, visibleSize.width / 2);
- float y = std::max(spritePos.y, visibleSize.height / 2);
-
-
-
- x = std::min(x, mapSize.width - visibleSize.width / 2);
- y = std::min(y, mapSize.height - visibleSize.height / 2);
-
- if (x >= visibleSize.width);
-
- Point destPos = Point(x, y);
-
-
- Point centerPos = Point(visibleSize.width / 2, visibleSize.height / 2);
-
-
- Point viewPos = centerPos - destPos;
-
- parent->setPosition(viewPos);
- }
由于地图移动也有一个限度,就是不能将地图移出屏幕,否则就会出现黑框,这个时候的坐标就是当地图的极限坐标。
其实也可以理解为精灵在地图上移动,我们拿着一个镜头记录,为了保持精灵在镜头的中心,要么移动镜头,要么拖着地图(包括精灵)往精灵移动的反方向移动。
想通了就觉得很好理解了。就是一个相对的问题。