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); }