您的位置:首页 > 移动开发 > Cocos引擎

【cocos2d-x】游戏构成要素③----游戏关卡的实现

2012-09-14 10:47 393 查看
到目前为止,我们讨论了多个场景和多个层的应用。现在我们来讨论关卡。

大家应该对关卡的概念都很熟悉,所以我不在这里做解释了。设计关卡的难点是决定用什么样的方式来设计基于关卡的游戏。
在Cocos2d-x中个关卡都使用一个场景,或者在同一个场景里设置多个层作为关卡。选择哪种方式取决于关卡在你游戏中的作用。

No.1 每一个关卡都使用一个场景

最直接的方法是每一个关卡都使用一个单独的场景。你可以为每一个关卡创建一个新的场景类(Scene class),或者通过把关卡号码或其它与关卡相关的信息传递给一个通用的关卡场景类(LevelScene class)用于加载正确的关卡数据。
这个方法很适合每个关卡之间没有多大关系,关卡可以清晰地分开的情况。你可能需要保存玩家的得分和当前剩余的生命数,除此之外不需要再保存其它的信息了。这种情况下的用户界面可能是静态的,或者最多只有一个暂停按钮。

No.2 同一个场景里设置多个层作为关卡

如果你有一个复杂的用户界面,并且在关卡转换时不允许重置游戏场景的话,你就需要在同一个场景里用不同的层来加载和显示不同的关卡。在转换关卡时,你可能会将游戏角色和其它的游戏物体保持在同一个位置。
你可能使用几个变量来保存当前的游戏状态信息和用户界面设置信息,比如说仓库里的物品。如果你使用多个场景作为关卡的话,在转换关卡的时候,你就需要做很多工作来保存和重置游戏设置,还有重置所有的视觉元素。

这个方式很适合物品寻找类或者冒险类游戏,因为玩家需要在不同的房间之间移动。特别是你想在替换关卡内容的过程中使用动画的情况下。

CCLayerMultiplex
CCLayerMultiplex类可被用于这种方式中。它可以同时包含多个节点,但是任意时间里只有一个节点是有效的。但是唯一的缺点是你不能在层之间使用过渡效果。因为任意时间里只能有一个层是可视的,所以任何过渡效果都是不可能发生的。
CCLayerMultiplex *multiplex=CCLayerMultiplex::layerWithLayers(layer1,layer2,NULL);
//切换到第二个Layer
multiplex->switchTo(1);
//切换到第二个Layer并且释放当前Layer 以后就不能切换到当前Layer
multiplex->switchToAndReleaseMe(1);


CCLayerColor

CCLayerColor类可用于改变背景颜色

CCLayerColor *layercolor=CCLayerColor::layerWithColor(ccc4(225,0,225,255));
this->addChild(layercolor,0);


如果你熟悉OpenGL的话,你可能会觉得没有必要为了改变背景颜色而添加一个单独的层。你可以使用以下OpenGL代码得到相同的效果:

glClearColor(255,0,255,255);


但是如果你在场景中使用了过渡效果的话,你最好先在游戏里测试一下上述OpenGL代码,因为glClearColor对场景过渡效果会产生不好的影响。
一些很酷的CCNode类

以下我会介绍四个基于CCNode可以满足特定要求的类。它们是:

CCProgressTimer,

CCParallaxNode,

CCMotionStreak。

CCProgressTimer进度条

CCSize size = CCDirector::sharedDirector()->getWinSize();
middle = CCProgressTimer::create(CCSprite::create("time.png"));

//      setType  设置类型
//      kCCProgressTimerTypeRadial为弧形
//      kCCProgressTimerTypeBar为条形
middle->setType(kCCProgressTimerTypeRadial);

//      setMidpoint 实现向左,向右,向上,向下或中间像两头移动的,
//      你只要改变ccp(x,y)中x,y的值来实现
//      ccp(0,0)这表示从左到右的曾加,
//      ccp(1,0)表示从右到左的增加
//      ccp(0,1)表示从下到上的增加
//      ccp(0.5f,0)表示从中间向左向右两头增加,
//      还有很多,看你怎么设置了
middle->setMidpoint(ccp(0,0));
//设置进度  0-100
middle->setPercentage(proportion);
middle->setPosition(ccp(size.width/2,size.height/2));
addChild(middle);
//进度条需要预约的更新方法来更新自身的状态
scheduleUpdate();

进度条有一个缺点:它不会自己更新自己。你必须经常更新进度条的百分比数值来显示进度.
Update方法代码:

void MyScene::update(ccTime time) {
proportion++;
middle->setPercentage(proportion);
if (proportion >= 100)
proportion= 0;
}

CCParallaxNode 视差视图

“视差”(Parallaxing)是2D游戏中通过让不同层上的图片用不同的速度移动,来创造视觉深度的方法。前景的图片移动的比背景图片要快。cocos2d-x有一个特殊的节点用于实现这个效果

bool ParallaxScreen::init() {
bool bRet = false;
do {

CCSize size = CCDirector::sharedDirector()->getWinSize();
node = CCParallaxNode::create();
this->addChild(node);
CCSprite *sprite1 = CCSprite::create("parallax/parallax1.png");
CCSprite *sprite2 = CCSprite::create("parallax/parallax2.png");

//设置速度
CCPoint speed1 = CCPointMake(0.5,0.5);
CCPoint speed2 = CCPointMake(0.1,0.1);

node->addChild(sprite1, 1, speed1, CCPointMake(0,0));
node->addChild(sprite2, 2, speed2, CCPointMake(0,size.width/2));

this->scheduleUpdate();
bRet = true;
} while (0);
return bRet;
}

void ParallaxScreen::update(ccTime time) {

CCSize size = CCDirector::sharedDirector()->getWinSize();
CCPoint backgroundScrollVert = CCPointMake(1000,0);
node->setPosition(
ccpAdd(node->getPosition(), ccpMult(backgroundScrollVert, time)));
if (node->getPosition().x > size.width*4) {
node->setPosition(CCPointMake(0,node->getPosition().y));
}
}

CCMotionStreak(拖尾效果)

bool Ribbon::init() {
bool bRet = false;
do {
CCSize size=CCDirector::sharedDirector()->getWinSize();
//      第一个参数用于决定元素消失的速度,它的值越小,元素消失的越快
//      第二个参数是间隐片断的大小
//      第三个参数是贴图的宽
//      第四个参数是颜色值argb
//      第五个参数是贴图的路径
motion = CCMotionStreak::create(3, 3, 32, ccc3(255, 255, 0), "s1.png");
motion->setPosition(CCPointMake(size.width/2,size.height/2));
this->addChild(motion);
this->setTouchEnabled(true);
bRet = true;
} while (0);
return bRet;
}

void Ribbon::registerWithTouchDispatcher(){
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
}

void Ribbon::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
CCLog("拖动");
CCPoint point = pTouch->getLocation();
//  convertToGL: 转换成opengl坐标啊,(0,0)在左下方
//  convertToUI:转换成quartz坐标,(0,0)在左上方的.
point=CCDirector::sharedDirector()->convertToUI(point);
motion->setPosition(point);
}

//bool Ribbon::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){
//  CCLog("触摸到屏幕");
//  return true;
//}


接下来一章将深入的讲解CCsprite(精灵),如有问题,请提出
本教程根据Cocos2d教程翻译过来
使用的cocos2d-x版本为2.02
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  游戏 cocos 2dx