cocos2d-x 地图随英雄移动

来源:互联网 发布:如何安装网络监控 编辑:程序博客网 时间:2024/05/01 22:25

转载自:http://blog.csdn.net/mydreamremindme/article/details/9933105?utm_source=tuicool


代码如下:

[cpp] view plaincopyprint?
  1. void HelloWorld::screenMove(CCPoint point)  
  2. {  
  3.     float x=heroSprite->getPosition().x;  
  4.     float y=heroSprite->getPosition().y;  
  5.     x=MAX(x,screenSize.width/2);  
  6.     y=MAX(y,screenSize.height/2);  
  7.     x=MIN(x,mapSize.width*mapTileSize.width-screenSize.width/2);  
  8.     y=MIN(y,mapSize.height*mapTileSize.height-screenSize.height/2);  
  9.   
  10.     CCPoint targetPosition=CCPoint(screenSize.width/2-x,screenSize.height/2-y);  
  11.     this->setPosition(targetPosition);  
  12. }  

当精灵在场景中移动的时候,不可能只限制在地图的那一部分内移动吧。。我们还需要看到地图更多的东西,这时就需要场景跟随着精灵移动。我们假设精灵在任何一点都需要场景的移动。

[cpp] view plaincopyprint?
  1. x=MAX(x,screenSize.width/2);  
  2. y=MAX(y,screenSize.height/2);  
两层意思:如果精灵的任何一个方向(x,y)的位置的值大于屏幕的大小,那么就需要移动将屏幕中心移动到该点(这是我的这个游戏的设定,其他的也可以),如果精灵就是在地图的左下角那一部分(0,0)到(screenSize.width/2,screenSize.height/2),那么我们还是一样的想法,只不过这次是将屏幕中心移动原来的屏幕中心,实际上还是没有移动。

但是我们不能一直这么移动下去吧。。如果窗口显示出了不存在地图的那部分(黑色),那这游戏就是失败的。。

[cpp] view plaincopyprint?
  1. x=MIN(x,mapSize.width*mapTileSize.width-screenSize.width/2);  
  2. y=MIN(y,mapSize.height*mapTileSize.height-screenSize.height/2);  
这就是限制我们的屏幕中心的方法,屏幕中心的范围是从screenSize.width/2,screenSize.height/2)到(mapSize.width*mapTileSize.width-screenSize.width/2,mapSize.height*mapTileSize.height-screenSize.height/2)

此时我们的(x,y)就是屏幕中心最终要到的地方,(书上说是精灵要到的地方,我觉得不太好理解,甚至感觉不是这样的,比如:精灵就在(0,0)到(screenSize.width/2,screenSize.height/2)这部分之内,精灵实际的位置还是在x,y没改变之前的那个位置,因为测试x,y已经变成了screenSize.width/2,screenSize.height/2。这是屏幕中心的位置啊!!我很费解。所以擅自把它给 改了)。屏幕要移动到(x,y),那么就需要场景从(screenSize.width/2-x,screenSize.height/2-y)这个方向去移动,屏幕肯定不会移动了啦,移动的是场景。。

[cpp] view plaincopyprint?
  1. this->setPosition(targetPosition);  

这就是场景移动的算法。这样写估计性能不是太好,但是简单吧。。

因为场景移动是每时每刻都要监测的,所以要放在update()中。。




在看到其中的地图跟随角色移动(一般情况下保持角色在屏幕中央附近,到地图边缘时移动角色)的问题时看的不大明白,自己搞了好久才搞懂,这里我已经将代码注释,希望对跟我一样的新手有所帮助。

代码如下:

void TiledMapTestScene::setCneterPointOfView( CCPoint p )
{
//因为这里是要通过传入的点p来显示设定CCLayer的位置,p为英雄坐标,当做显示中心点。
//TileMap的size肯定大于WinSize(分辨率),不然有黑边,而且也不用移动地图了。
//因此p的x、y的值肯定要大于等于屏幕中心的值

int x = MAX(p.x , winSize.width / 2);
int y = MAX(p.y , winSize.height / 2);

//同理,p的x、y要小于等于TileMap的size的宽高减去WinSize的中心值,不然也会出现黑边
x = MIN(x,mapSize.width * tileSize.width - winSize.width / 2);
y = MIN(y,mapSize.height * tileSize.height - winSize.height / 2);

/*这里是用地图中心的真实坐标减去屏幕中心坐标来得到两个中心之差(
真实中心肯定为屏幕中心右上部),得到的差值就是TileMap的偏移值(其x、y都为非正数)。
重点:由于CClayer为了初始化位置是始终显示到屏幕左下角方便,因此其锚点为(0,0),
刚好可以把以上求得的偏移值作为其坐标。
*/
CCPoint actualPosition = ccp(x,y);
CCPoint winCenter = ccp(winSize.width / 2 , winSize.height /2);
CCPoint viewPosition = ccp(winCenter.x-actualPosition.x,winCenter.y-actualPosition.y);

this->setPosition(viewPosition);
}

好了,大概就这样了,相信初学者也可以看明白的。


lua 代码

function MainScene:setViewPointCenter(px,py)    local visibleSize = cc.Director:getInstance():getVisibleSize();    local origin = cc.Director:getInstance():getVisibleOrigin();    local x = math.max(px, visibleSize.width/2);    local y = math.max(py, visibleSize.height/2);    x = math.min(x, MAIN_MAP_LENGTH - visibleSize.width/2);    y = math.min(y, MAIN_MAP_HEIGHT - visibleSize.height/2);    local actualPoint = cc.p(x, y);    local offsetX = visibleSize.width/2 - x;    local offsetY = visibleSize.height/2 - y;    self._scene_layer:setPosition(cc.p(offsetX, offsetY));end


0 0
原创粉丝点击