Cocos2d-x游戏开发实例详解3:无限滚动地图

2015年03月25日 13:37 0 点赞 0 评论 更新于 2025-11-21 15:17

在本次内容中,我们将通过实际演练,详细解说Cocos2d-x引擎的相关模块,重点讲解无限滚动地图的实现。

无限滚动地图在游戏中的应用

一般打飞机类游戏会采用飞机不动,背景图滚动的方式,从而营造出飞机在天空飞行的效果。以MoonWarriors游戏为例,其背景包含两层:远景天空和近景漂浮物。这两层背景以不同的速度滚动,能形成一种纵深感。

游戏背景图 原内容提及图有点模糊,实际效果和html5的类似(原内容称根本就是照着它写的)。

背景分为天空和漂浮物两部分,下面分别进行详细解释。

1. 天空背景的实现

天空背景的源图是一张320 * 576的jpg图片,加载过程实质上分两次进行。

初始加载

m_backSky = CCSprite::create(s_bg01);
m_backSky->setAnchorPoint(ccp(0, 0));
m_backSkyHeight = m_backSky->getContentSize().height;
addChild(m_backSky, -10);

上述代码完成了天空背景精灵的初始创建、锚点设置、高度获取以及添加到图层的操作。加载完成后,会执行一个移动动作:

m_backSky->runAction(CCMoveBy::create(3, ccp(0, -48)));

此动作会让天空背景向下移动48像素。接着,通过任务调度来实现重复滚动:

schedule(schedule_selector(GameLayer:: movingBackground),3);

滚动函数分析

void GameLayer::movingBackground()
{
m_backSky->runAction(CCMoveBy::create(3, ccp(0, -48)));
m_backSkyHeight -= 48;
if (m_backSkyHeight <= winSize.height) {
if (!m_isBackSkyReload) {
m_backSkyRe = CCSprite::create(s_bg01);
m_backSkyRe->setAnchorPoint(ccp(0, 0));
addChild(m_backSkyRe, -10);
m_backSkyRe->setPosition(ccp(0, winSize.height));
m_isBackSkyReload = true;
}
m_backSkyRe->runAction(CCMoveBy::create(3, ccp(0, -48)));
}

if (m_backSkyHeight <= 0) {
m_backSkyHeight = m_backSky->getContentSize().height;
this->removeChild(m_backSky, true);
m_backSky = m_backSkyRe;
m_backSkyRe = NULL;
m_isBackSkyReload = false;
}
}

从代码可以看出,实际上是通过两个CCSprite轮换加载来实现滚动的。第一张图片加载后比屏幕要高一些,它向下滚动,当顶部到达屏幕顶部时,加载第二张图片,同时反转m_isBackSkyReload标志位。第二张图片紧接着滚动进入屏幕,当第一张图片滚出屏幕时,移除第一张图片的节点,将指针指向第二个精灵,释放第二个指针,同时再次反转标志位,这样就完成了一个滚动周期,整个过程会不断重复。

2. 近景漂浮物滚动的实现

近景漂浮物滚动的思路与天空背景滚动一致,但使用的图片不同,这里使用的是tmx格式的瓦片地图。

初始加载

m_backTileMap = CCTMXTiledMap::create(s_level01);
addChild(m_backTileMap, -9);
m_backTileMapHeight = m_backTileMap->getMapSize().height * m_backTileMap->getTileSize().height;
m_backTileMapHeight -= 200;
m_backTileMap->runAction(CCMoveBy::create(3, ccp(0, -200)));

上述代码完成了瓦片地图的初始创建、添加到图层、高度计算以及初始移动动作的设置。

滚动部分

m_backTileMap->runAction(CCMoveBy::create(3, ccp(0, -200)));
m_backTileMapHeight -= 200;
if (m_backTileMapHeight <= winSize.height) {
if (!m_isBackTileReload) {
m_backTileMapRe = CCTMXTiledMap::create(s_level01);
this->addChild(m_backTileMapRe, -9);
m_backTileMapRe->setPosition(0, winSize.height);
m_isBackTileReload = true;
}
m_backTileMapRe->runAction(CCMoveBy::create(3, ccp(0, -200)));
}

if (m_backTileMapHeight <= 0) {
m_backTileMapHeight = m_backTileMap->getMapSize().height * m_backTileMap->getTileSize().height;
this->removeChild(m_backTileMap, true);
m_backTileMap = m_backTileMapRe;
m_backTileMapRe = NULL;
m_isBackTileReload = false;
}

同样,这里也是通过两个CCTMXTiledMap轮换加载来实现滚动,原理与天空背景滚动类似。

综上所述,通过上述方法,我们可以在Cocos2d-x游戏中实现无限滚动地图的效果。