关卡选择场景MainScene

游戏共有6个关卡可供选择,当然,最开始游戏只能选择第一关,只有通过该关卡就能解锁下一关卡

一、物理场景

1、创建

//创建一个物理场景
_scene = Scene::createWithPhysics();
//_scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
//设置物理世界的重力
_scene->getPhysicsWorld()->setGravity(Vect(0, -1000));
//添加层到物理世界中
MainScene *layer = MainScene::create();
_scene->addChild(layer);
2、在进入MainScene时设置碰撞监听事件,碰撞后做球的自旋转动作

void MainScene::onEnter(){
Layer::onEnter();
//碰撞事件监听
auto contactListenner = EventListenerPhysicsContact::create();
contactListenner->onContactBegin = CC_CALLBACK_1(MainScene::onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListenner, this);
}
bool MainScene::onContactBegin(PhysicsContact& contact){
ball->rotateAction();
return true;
}
3、初始化时还创建一个静态的线状刚体,让球落下来与该刚体发生碰撞弹起

void MainScene::initPhysicWorld(){
auto visibleSize = Director::getInstance()->getVisibleSize();
auto origin = Director::getInstance()->getVisibleOrigin();
//创建一个静态的线状刚体
auto body = PhysicsBody::createEdgeSegment(origin, Point(visibleSize.width, 0), PHYSICSBODY_MATERIAL_DEFAULT, 1);
//设置弹性 1-完全
body->getShape(0)->setRestitution(1);
//设置body是否受引力影响
body->setGravityEnable(false);
//类别标示掩码
body->setCategoryBitmask(0x01);
//碰撞掩码
body->setCollisionBitmask(0x01);
//接触测试掩码,表示哪些类别的物体“接触”时,会产生消息
body->setContactTestBitmask(0x01);
auto edgeNode = Node::create();
edgeNode->setPosition(0, visibleSize.height/5);
edgeNode->setPhysicsBody(body);
this->addChild(edgeNode, 2);
}
4、禁用一个物理世界的auto step,然后通过设定PhysicsWorld::step(time)来手动刷新PhysicsWorld

_scene->getPhysicsWorld()->setAutoStep(false);
scheduleUpdate();
void MainScene::update(float t){
int steps = 3;
float dt = CCDirector::getInstance()->getAnimationInterval() / (float)steps;
PhysicsWorld* s = getScene()->getPhysicsWorld();
for (int i = 0; i<steps; i++){
s->step(dt);
}
}
二、按钮、关卡界面

1、开始、声音按钮

auto *menu = Menu::create();
menu->setPosition(zeroPos);
//开始按钮
auto * menuItemPLay = MenuItemSprite::create(Sprite::create(START_NORMAL), Sprite::create(START_PRESS), CC_CALLBACK_1(MainScene::onPlay, this));
menuItemPLay->setPosition(centerPos.x,centerPos.y+30);
menuItemPLay->setTag(0);
menu->addChild(menuItemPLay);
MenuItemToggle可以实现声音按钮的开关两种状态,类似”ON”->”OFF”.

//声音菜单
auto soundOnMenuItem = MenuItemImage::create(
SOUND_OPEN,
SOUND_OPEN);
auto soundOffMenuItem = MenuItemImage::create(
SOUND_CLOSE,
SOUND_CLOSE);
auto soundToggleMenuItem = MenuItemToggle::createWithCallback(
CC_CALLBACK_1(MainScene::onPlay, this),
soundOnMenuItem,
soundOffMenuItem,
NULL);
soundToggleMenuItem->setAnchorPoint(ccp(0.5, 0.5));
soundOnMenuItem->setScale(0.8);
soundOffMenuItem->setScale(0.8);
soundToggleMenuItem->setTag(100);
soundToggleMenuItem->setPosition(
Point(soundOnMenuItem->getContentSize().width / 2, soundOnMenuItem->getContentSize().height / 2));
menu->addChild(soundToggleMenuItem);
2、关卡选择

用循环将六个关卡展示出来,如果还未解锁的加锁标志

//显示关卡
int num = CHECK_POINT_NUM + 1;
for (int i = 1; i < num; i++){
auto * menuCheckPoint = MenuItemSprite::create(Sprite::createWithSpriteFrameName("cylinder.png"), Sprite::createWithSpriteFrameName("cylinder_press.png")
, CC_CALLBACK_1(MainScene::onPlay, this));
menuCheckPoint->setTag(i);
menuCheckPoint->setPosition(Point(size.width / num * i, size.height/5 ));
menuCheckPoint->setScale(0.8);
menu->addChild(menuCheckPoint);
//数字
String *str = String::createWithFormat("checkPoint%i.png", i);
Sprite *sprite = Sprite::createWithSpriteFrameName(str->getCString());
sprite->setPosition(Point(size.width / num * i, size.height/5 - sprite->getContentSize().height / 2 - menuCheckPoint->getContentSize().height / 2));
this->addChild(sprite);

//不可选择关卡加锁标志
String *c_str = String::createWithFormat("checkPoint%i",i);
if (i != 1 && !CCUserDefault::sharedUserDefault()->getBoolForKey(c_str->getCString(), false) ){
    Sprite *lockSprite = Sprite::createWithSpriteFrameName("lock.png");
    lockSprite->setPosition(Point(size.width / num * i, size.height/5 + lockSprite->getContentSize().height / 2 + menuCheckPoint->getContentSize().height / 2));
    this->addChild(lockSprite);
}

}