cocos2d-x-3.16 实例开发之ParkourBall【5】游戏主场景

游戏主场景:PlayScene

一、创建物理场景

物理场景跟关卡界面是类似的

	//创建一个物理场景
	_scene = Scene::createWithPhysics();
	//_scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
	//设置物理世界的重力
	_scene->getPhysicsWorld()->setGravity(Vect(0, -1300));
	//添加层到物理世界中
	PlayScene *layer = PlayScene::create();
	_scene->addChild(layer);

创建线状刚体

void PlayScene::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->getShape(0)->setFriction(0);
	//设置body是否受引力影响
	body->setGravityEnable(false);
	//类别标示掩码
	body->setCategoryBitmask(0x01);
	body->setCollisionBitmask(0x01);
	body->setContactTestBitmask(0x01);
	auto edgeNode = Node::create();
	edgeNode->setPosition(0, visibleSize.height/2);
	edgeNode->setPhysicsBody(body);
	edgeNode->setTag(edgeNodeTag);
	this->addChild(edgeNode, 2);
}

还有设置碰撞监听等

二、初始界面

1、初始球、圆盘等

	//背景
	auto *spriteBG = Sprite::create(PLAY_BG);
	spriteBG->setPosition(centerPos);
	this->addChild(spriteBG,0);
	
	//球
	ball = Ball::create();
	
	//球的初始位置
	ball->setPosition(size.width/4, size.height/2 + ball->getConSize().height / 2);
	this->addChild(ball,2); 
	setBallDefaultColor();
......
	//cylinder管理类
	m_manager = BaseManager::create();
	this->addChild(m_manager,1);
	
	//粒子
	ParticleSystem *_emitter = ParticleRain::create();
	_emitter->setAutoRemoveOnFinish(true);
	_emitter->setPosition(size.width/2,size.height);
	this->addChild(_emitter, 5);

	//进度
	labelTTFCardNumber = LabelTTF::create("0", "HiraKakuProN-w6", 50);
	labelTTFCardNumber->setColor(Color3B::WHITE);
	labelTTFCardNumber->setPosition(
		Point(size.width / 2, size.height / 2 + labelTTFCardNumber->getContentSize().height + 20));
	this->addChild(labelTTFCardNumber, 2);
	labelTTFCardNumber->setString(
		StringUtils::format("%d%%", 0));

2、游戏方式介绍

根据不同关卡展示不同玩法

void PlayScene::createPlayWay(){
	auto size = Director::getInstance()->getVisibleSize();
	auto zeroPos = Director::getInstance()->getVisibleOrigin();
	auto centerPos = Point(size.width / 2, size.height / 2);
	auto *menu = Menu::create();
	menu->setPosition(zeroPos);
	if (checkPoint == 1){
		auto * menuItemPLay = MenuItemSprite::create(Sprite::create(PLAY_WAY_1), Sprite::create(PLAY_WAY_1), CC_CALLBACK_1(PlayScene::onStart, this));
		menuItemPLay->setPosition(centerPos);
		menu->addChild(menuItemPLay);
	}
	else if (checkPoint == 2){
		auto * menuItemPLay = MenuItemSprite::create(Sprite::create(PLAY_WAY_2), Sprite::create(PLAY_WAY_2), CC_CALLBACK_1(PlayScene::onStart, this));
		menuItemPLay->setPosition(centerPos);
		menu->addChild(menuItemPLay);
	}
	else if (checkPoint == 3){
		auto * menuItemPLay = MenuItemSprite::create(Sprite::create(PLAY_WAY_3), Sprite::create(PLAY_WAY_3), CC_CALLBACK_1(PlayScene::onStart, this));
		menuItemPLay->setPosition(centerPos);
		menu->addChild(menuItemPLay);
	}
	else if (checkPoint == 4){
		auto * menuItemPLay = MenuItemSprite::create(Sprite::create(PLAY_WAY_4), Sprite::create(PLAY_WAY_4), CC_CALLBACK_1(PlayScene::onStart, this));
		menuItemPLay->setPosition(centerPos);
		menu->addChild(menuItemPLay);
	}
	else if (checkPoint == 5 ){
		auto * menuItemPLay = MenuItemSprite::create(Sprite::create(PLAY_WAY_5), Sprite::create(PLAY_WAY_5), CC_CALLBACK_1(PlayScene::onStart, this));
		menuItemPLay->setPosition(centerPos);
		menu->addChild(menuItemPLay);
	}
	else if ( checkPoint == 6){
		auto * menuItemPLay = MenuItemSprite::create(Sprite::create(PLAY_WAY_6), Sprite::create(PLAY_WAY_6), CC_CALLBACK_1(PlayScene::onStart, this));
		menuItemPLay->setPosition(centerPos);
		menu->addChild(menuItemPLay);
	}
	menu->setTag(playwayTag);
	this->addChild(menu,10);
}

3、点击游戏玩法响应,游戏正式开始

void PlayScene::onStart(cocos2d::Ref* pSender){
	isGameBegin = true;
	//移除介绍游戏方式菜单
	this->removeChildByTag(playwayTag);
	//播放音乐
	playMusicByCheckPoint();
	//设置重力
	setWorldGravity();
	//创建控制按钮
	createControlBtn();
	//给小球速度
	ball->jump();
	//进度更新
	this->schedule(schedule_selector(PlayScene::addTime), 1.0f, kRepeatForever, 1);
}

三、游戏中

游戏开始有给小球速度,由于刚体设置摩擦力为0,完全弹力等因素影响,小球将无限弹起落下到游戏结束。主要逻辑在碰撞监听函数里实现,不同的关卡游戏失败的逻辑有所区别

bool PlayScene::onContactBegin(PhysicsContact& contact){
	auto size = Director::getInstance()->getVisibleSize();
	if (!isGameBegin){
		return true;
	}
	//获取碰撞物体
	auto body1 = (Sprite *)contact.getShapeA()->getBody()->getNode();
	auto body2 = (Sprite *)contact.getShapeB()->getBody()->getNode();
	CylinderColor ballColor = normal;
	CylinderColor cylinderColor = normal;
	
	//判断是否为球
	if (body1->getTag() == ballTag){
		ballColor = ball->getBallColor();
	}
	if (body2->getTag() == ballTag){
		ballColor = ball->getBallColor();
	}

	//从圆盘列表里获取当前碰撞圆盘的颜色
	list <Cylinder*> cylinderList = m_manager->getCylinderList();
	Cylinder* cylinder;
	for (list<Cylinder*>::iterator iter = cylinderList.begin(); iter != cylinderList.end(); iter++){
		cylinder = (Cylinder*)*iter;
		if (cylinder->getPosition().x == size.width/4){
			cylinderColor = cylinder->getCylinderColor();
			break;
		}
	}
	//关卡
	switch (checkPoint)
	{
	case 1:
		//如果颜色不同且圆盘不是最后一个则游戏结束
		if (cylinderColor != normal && cylinderColor != endColor  && cylinderColor != ballColor){
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
			GameOver();
			auto endLayer = TransitionFade::create(1, EndLayer::createScene(false, percent));
			Director::getInstance()->replaceScene(endLayer);


			return false;
		}
		else if (cylinderColor == endColor){
			if (CCUserDefault::sharedUserDefault()->getBoolForKey("sound", true)){
				CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(MUSIC_WIN, false);
			}

			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();

			//设置下一关卡开启
			String *c_str = String::createWithFormat("checkPoint%i", checkPoint + 1);
			CCUserDefault::sharedUserDefault()->setBoolForKey(c_str->getCString(), true);
			//跳转到游戏成功结束界面
			auto endLayer = TransitionFade::create(1, EndLayer::createScene(true, percent));
			Director::getInstance()->replaceScene(endLayer);
			return true;
		}
		break;
	case 2:
		//关卡2是要求球与圆盘颜色相反,所以如果相同则失败
		if (cylinderColor != normal && cylinderColor != endColor && cylinderColor == ballColor){
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
			GameOver();
			auto endLayer = TransitionFade::create(1, EndLayer::createScene(false, percent));
			Director::getInstance()->replaceScene(endLayer);
			return false;
		}
		else if (cylinderColor != normal && ballColor == normal){
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
			GameOver();
			auto endLayer = TransitionFade::create(1, EndLayer::createScene(false, percent));
			Director::getInstance()->replaceScene(endLayer);
			return false;
		}
		else if (cylinderColor == endColor){
			if (CCUserDefault::sharedUserDefault()->getBoolForKey("sound", true)){
				CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(MUSIC_WIN, false);
			}
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();

			String *c_str = String::createWithFormat("checkPoint%i", checkPoint + 1);
			CCUserDefault::sharedUserDefault()->setBoolForKey(c_str->getCString(), true);

			auto endLayer = TransitionFade::create(1, EndLayer::createScene(true, percent));
			Director::getInstance()->replaceScene(endLayer);
			return true;
		}
		break;
	case 3:
	case 4:
	case 5:
		//
		if (cylinderColor != normal && cylinderColor != endColor  && cylinderColor != ballColor){
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
			GameOver();
			auto endLayer = TransitionFade::create(1, EndLayer::createScene(false, percent));
			Director::getInstance()->replaceScene(endLayer);
			return false;
		}
		else if (cylinderColor == endColor){
			if (CCUserDefault::sharedUserDefault()->getBoolForKey("sound", true)){
				CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(MUSIC_WIN, false);
			}
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();

			String *c_str = String::createWithFormat("checkPoint%i", checkPoint + 1);
			CCUserDefault::sharedUserDefault()->setBoolForKey(c_str->getCString(), true);

			auto endLayer = TransitionFade::create(1, EndLayer::createScene(true, percent));
			Director::getInstance()->replaceScene(endLayer);
			return true;
		}
		break;
	case 6:
		if (cylinderColor != normal && cylinderColor != endColor  && cylinderColor != ballColor){
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
			GameOver();
			auto endLayer = TransitionFade::create(1, EndLayer::createScene(false, percent));
			Director::getInstance()->replaceScene(endLayer);
			return false;
		}
		else if (cylinderColor == endColor){
			if (CCUserDefault::sharedUserDefault()->getBoolForKey("sound", true)){
				CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(MUSIC_WIN, false);
			}
			CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();

			auto scene = TransitionFade::create(1, LeaveLayer::createScene());
			Director::getInstance()->replaceScene(scene);
			return true;
		}
		break;
	default:
		break;
	}
	//球自旋转
	ball->rotateAction();
	//圆盘管理
	m_manager->update(0);
	return true;
}


发表评论

(必填)

(必填)

(以便回访)

博客已稳定运行: 访问量:115,603 views 网站备案号:闽ICP备17026396号-1