コード例 #1
0
bool FiledScene::init(){
	if (!Layer::init())
		return false;
	
	_isGameOver = false;
	auto visibleSize = Director::getInstance()->getVisibleSize();
	_screenWidth = visibleSize.width;
	_screenHeight = visibleSize.height;

	_tileMap = TMXTiledMap::create("field_map.tmx");
	_tileMap->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
	_tileMap->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

	// ②获取障碍层,并设置障碍层为不可见
	_collidable = _tileMap->getLayer("collidable");
	_collidable->setVisible(false);
	/********③初始化读取地图所有网格,并确定网格对象是否是障碍物,将信息保存到网格二维数组**************/
	for (int i = 0; i < _tileMap->getMapSize().width; i++) {
		// 内部网格集合([x,0]-[x-20]),存储网格
		Vector<Grid*> inner;
		for (int j = 0; j < _tileMap->getMapSize().height; j++) {
			// 设置网格对象的x轴和y轴以及是否可通过变量值
			Grid *o = Grid::create(i, j);
			// 将网格加入到集合
			inner.pushBack(o);
		}
		// 将内部集合加入到网格集合
		_gridVector.push_back(inner);
	}
	// 循环保存根据每个网格的x轴和y轴查找对应的地图的GID,判断是否可通过
	for (int i = 0; i < _gridVector.size(); i++) {
		Vector<Grid*> inner = _gridVector.at(i);
		// 循环内部网格集合
		for (int j = 0; j < inner.size(); j++) {
			// 获取每一个网格对象
			Grid *grid = inner.at(j);
			// 获取每一个网格对象对应的的坐标
			Vec2 tileCoord = Vec2(grid->getX(), grid->getY());
			// 使用TMXLayer类的tileGIDAt函数获取TileMap坐标系里的“全局唯一标识”GID
			int tileGid = _collidable->getTileGIDAt(tileCoord);
			if (tileGid) {
				// 使用GID来查找指定tile的属性,返回一个Value
				Value properties = _tileMap->getPropertiesForGID(tileGid);
				// 返回的Value实际是一个ValueMap
				ValueMap map = properties.asValueMap();
				// 查找ValueMap,判断是否有”可碰撞的“物体,如果有,设置网格对象的isPass变量为false
				std::string value = map.at("collidable").asString();
				if (value.compare("true") == 0) {
					grid->setPass(false);
				}
			}
		}
	}

	// 人物出场特效
	auto effects_player_out = Sprite::create("effects/effects_player_out/effects_player_out_11.png");
	effects_player_out->setPosition(Vec2(visibleSize.width*0.3,visibleSize.height*0.3));
	this->addChild(effects_player_out, 1);
	auto player_out_animate = getAnimateByName("effects/effects_player_out/effects_player_out_", 0.1f, 11);
	auto delay1 = DelayTime::create(1.5f);
	auto fadeOut = FadeOut::create(0.2f);
	auto sequence = Sequence::create(delay1, player_out_animate, fadeOut, nullptr);
	effects_player_out->runAction(sequence);

	_player = SpriteBase::create("player/player_sword/player_sword_stand.png");
	this->addChild(_player, 1);
	_player->setPosition(Vec2(visibleSize.width*0.3, visibleSize.height*0.3));
	this->addChild(_tileMap,0);
	_player->setFlippedX(true);
	XmlTools::readPlayerData(_player);

	/// 传送门
	ArmatureDataManager::getInstance()->addArmatureFileInfo("/buildings/gate/AnimationStart0.png", "/buildings/gate/AnimationStart0.plist", "/buildings/gate/AnimationStart.ExportJson");
	Armature *armature = Armature::create("AnimationStart");
	armature->getAnimation()->play("Start");
	this->addChild(armature);
	armature->setScale(0.3);
	armature->setPosition(Vec2(visibleSize.width*0.9, visibleSize.height*0.7));
	auto gate_effect = ParticleSystemQuad::create("effects/gate_effect.plist");
	this->addChild(gate_effect);
	gate_effect->setScale(0.3);
	gate_effect->setPosition(Vec2(visibleSize.width*0.9, visibleSize.height*0.75));
	gate_effect->setPositionType(kCCPositionTypeRelative);

	// 结束战斗按钮
	auto end_fight_button = Button::create("ui/end_fight.png");
	end_fight_button->setPosition(Vec2(visibleSize.width*0.95, visibleSize.height*0.97));
	end_fight_button->setScale(0.5f);
	this->addChild(end_fight_button, 0);
	//结束战斗对话框
	auto end_fight_dialog_bg = Sprite::create("ui/end_fight_dialog_bg.png");
	end_fight_dialog_bg->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
	end_fight_dialog_bg->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
	this->addChild(end_fight_dialog_bg, 3);

	// 确定结束战斗按钮
	auto end_fight_sub_button = Button::create("ui/end_fight_sub_button.png");
	end_fight_dialog_bg->addChild(end_fight_sub_button);
	end_fight_sub_button->setAnchorPoint(Vec2::ZERO);
	end_fight_sub_button->setPosition(Vec2(20, 30));
	end_fight_sub_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type){
		XmlTools::writePlayerData(_player);
		auto transition = TransitionSplitCols::create(2, Game::createScene());
		Director::getInstance()->pushScene(transition);
	});

	// 取消结束战斗按钮
	auto end_fight_cancel_button = Button::create("ui/end_fight_cancel_button.png");
	end_fight_dialog_bg->addChild(end_fight_cancel_button);
	end_fight_cancel_button->setAnchorPoint(Vec2::ZERO);
	end_fight_cancel_button->setPosition(Vec2(140, 30));
	end_fight_cancel_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type){
		end_fight_dialog_bg->setVisible(false);
	});

	end_fight_dialog_bg->setVisible(false);

	end_fight_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type){
		if (type == Widget::TouchEventType::ENDED){
			end_fight_dialog_bg->setVisible(true);
		}
	});

	// ⑤创建事件监听器
	auto gameListener = EventListenerTouchOneByOne::create();
	// 响应触摸事件函数
	gameListener->onTouchBegan = [](Touch* touch, Event* event){return true; };
	gameListener->onTouchEnded = [=](Touch *touch, Event *event){
		// OpenGL坐标
		Vec2 touchLocation = touch->getLocation();
		// 将触摸点坐标转换成相对的Node坐标
		Vec2 nodeLocation = this->convertToNodeSpace(touchLocation);
		// 玩家镜像反转
		if (_player->getPosition().x > nodeLocation.x) {
			if (_player->isFlippedX() == true){
				_player->setFlippedX(false);
			}
		}
		else{
			if (_player->isFlippedX() == false)
				_player->setFlippedX(true);
		}

		// 用玩家位置作为起点,触摸点作为终点,转换为网格坐标,在地图上查找最佳到达路径
		Vec2 from = tileCoordForPosition(_player->getPosition());
		Vec2 to = tileCoordForPosition(nodeLocation);
		// 如果终点是不可通过(即有障碍物)的位置,则直接return
		int tileGid = _collidable->getTileGIDAt(to);
		if (tileGid) {
			// 使用GID来查找指定tile的属性,返回一个Value
			Value properties = _tileMap->getPropertiesForGID(tileGid);
			// 返回的Value实际是一个ValueMap
			ValueMap map = properties.asValueMap();
			// 查找ValueMap,判断是否有”可碰撞的“物体,如果有,直接返回
			std::string value = map.at("collidable").asString();
			if (value.compare("true") == 0) {
				return;
			}
		}

		/**************玩家精灵移动到指定位置************************/
		// 在玩家精灵移动过程中,如果用户在此触摸屏幕移动玩家时,如果精灵没有运行动作,直接执行移动动作
		if (_player->getNumberOfRunningActions() == 0) {
			this->playerMover(nodeLocation);
		}
		else
		{
			//如果精灵正在运行动作,先停止精灵动作和层动作,再执行移动动作
			_player->stopAllActions();
			this->stopAllActions();
			this->playerMover(nodeLocation);
		}

		// 接触传送门, 如果boss被杀死, 则传送回主场景.
		if (_player->getBoundingBox().intersectsRect(armature->getBoundingBox())){
			if (monster_1->isVisible()==false){
				_player->setExp(_player->getExp() + 200);
				_player->setGold(_player->getGold() + 1000);
				XmlTools::writePlayerData(_player);

				const string player_task = FileUtils::getInstance()->fullPathForFilename("data/kill_count.xml");
				ssize_t  player_taskFile_size;
				char* pPlayerTaskContent = (char*)FileUtils::getInstance()->getFileData(player_task, "r", &player_taskFile_size);
				TiXmlDocument* player_task_el = new TiXmlDocument();
				player_task_el->Parse(pPlayerTaskContent, 0, TIXML_ENCODING_UTF8);
				TiXmlElement* rootElement = player_task_el->RootElement();//Root
				TiXmlElement* player_kill_count_1 = rootElement->FirstChildElement();
				string accept = player_kill_count_1->GetText();
				TiXmlElement* player_kill_count_2 = player_kill_count_1->NextSiblingElement();
				stringstream ss;
				string kill_count = player_kill_count_2->GetText();
				int kill_count_int;
				ss << kill_count;
				ss >> kill_count_int;

				if (accept=="true"){
					kill_count_int += 1;
					player_kill_count_2->Clear();
					string kill_count_str;
					stringstream ss;
					ss << kill_count_int;
					ss >> kill_count_str;
					TiXmlText* kill_count_text = new TiXmlText(kill_count_str.c_str());
					player_kill_count_2->LinkEndChild(kill_count_text);
					player_task_el->SaveFile(player_task.c_str());
				}
				
				auto transform_to = TransitionSplitCols::create(2.0f, Game::createScene());
				Director::getInstance()->pushScene(transform_to);
			}