【木头Cocos2d-x 012】游戏实例-《跑跑跑》制作教程(第四篇)——地图卷动

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/musicvs/article/details/8190473

Cocos2d-x游戏实例-《跑跑跑》制作教程(第四篇)——地图卷动

 

笨木头花心贡献,啥?花心?不呢,是用心~

转载请注明,原文地址
 http://blog.csdn.net/musicvs/article/details/8190473 

 

正文:

 

注:本文使用到的资源请到这里下载:http://download.csdn.net/detail/musicvs/4769412

 

 

上一篇我们已经把我们跑的主题体现出来了,但是,主角跑没多久就离开地图了,也离开屏幕了,这不靠谱啊喂,我们得让地图也动起来(难道我做这么长的地图是摆设么~)。

 

1. 地图卷动规则

首先要定一个规则,地图怎么卷动?我们定义为这样,地图只会横向往左卷动,当主角超过屏幕中点的时候地图就开始卷动。最终的效果应该是这样的:

 

留意最左边,地图最左边已经有部分没有显示出来了,证明地图已经往左移动了一小段距离。

 

2. 触发卷动

我们在主角坐标改变的时候就判断是否需要移动地图,来,我们给Player类增加一个函数:

void Player::setViewPointByPlayer()
{
    if(mSprite == NULL) {
        return;
    }
    CCLayer* parent = (CCLayer* )mSprite->getParent();

/* 地图方块数量 */    
CCSize mapTiledNum = map->getMapSize();

    /* 地图单个格子大小 */
    CCSize tiledSize = map->getTileSize();
    
/* 地图大小 */
    CCSize mapSize = CCSize::CCSize(
        mapTiledNum.width * tiledSize.width, 
        mapTiledNum.height * tiledSize.height);

    /* 屏幕大小 */
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

    /* 精灵的坐标 */
    CCPoint spritePos = mSprite->getPosition();

    /* 如果精灵坐标小于屏幕的一半,则取屏幕中点坐标,否则取精灵的坐标 */
    float x = max(spritePos.x, visibleSize.width / 2);
    float y = max(spritePos.y, visibleSize.height / 2);

    /* 如果x、y的坐标大于右上角的极限值,则取极限值的坐标(极限值是指不让地图超出屏幕造成出现黑边的极限坐标) */
    x = min(x, mapSize.width - visibleSize.width / 2);
    y = min(y, mapSize.height - visibleSize.height / 2);

    CCPoint destPos = CCPoint::CCPoint(x, y);
    CCPoint centerPos = CCPoint::CCPoint(visibleSize.width / 2, visibleSize.height / 2);
    
    /* 计算屏幕中点和所要移动的目的点之间的距离 */
    CCPoint viewPos = ccpSub(centerPos, destPos);

    parent->setPosition(viewPos);
}


 

 

这个函数的功能是,让地图所在图层以主角为中心进行移动,也就是,让世界的焦点停留在主角身上,屏幕随着主角移动,这样说比较清晰。

这个函数的算法解释起来可能有点繁琐,总之就是为了让地图跟随主角移动,并且要判断边界值,不能让地图超出屏幕从而导致有黑边出现。大家可以根据这个思路自己写一个算法,也许比我的更好~

然后,我们的Player要重写父类的setSimplePosition函数:

void Player::setSimplePosition( int x, int y )
{
    Entity::setSimplePosition(x, y);

    /* 以主角为中心移动地图 */
    setViewPointByPlayer();
}

 

记得在头文件里加上这句:

/* 重写父类的函数 */
virtual void setSimplePosition(int x, int y);


 

于是,编译运行,就能看到主角在跑,地图也随之移动!

呼呼,终于有点意思了~

 

 

下一篇我们将给主角添加一个新的很帅的功能——上下移动。

 

来自未来的PS(2013.01.14):

多位朋友问过我为什么map变量未声明,可能是我忘记说了,map变量在Entity.h文件里声明的:

class Entity : public CCNode, public ControllerListener {
public:
    void setSprite(CCSprite* mSprite);
    void setController(Controller* controller);

    /* 实现SimpleMoveListener接口的方法 */
    virtual void setSimplePosition(int x, int y);
    virtual CCPoint getCurPosition();
protected:
    CCSprite* mSprite;
    Controller* mController;
    CCTMXTiledMap* map;  /* ------------------------ Hi,我在这里~~!!! --------------------------- */

    CCTMXLayer* meta;   /* 检测碰撞的地图层 */
    CCTMXLayer* barrier;/* 障碍物层 */

    /* 将像素坐标转换为地图格子坐标*/
    CCPoint tileCoordForPosition(CCPoint pos);
};


 

 

阅读更多
换一批

没有更多推荐了,返回首页