/***************************************************************************** * Function: int _DtHelpCeGetSdlIdPath(volume, target_id, ret_ids); * * Parameters: * * Returns: > 0 if successful, -1 if not. * * Memory: The memory returned is owned by the caller. * * Purpose: Get the list of location ids between the top and the * target_id. * *****************************************************************************/ int _DtHelpCeGetSdlIdPath( _DtHelpVolumeHdl volume, char *target_id, char ***ret_ids) { _DtCvSegment *idSegs; _DtCvSegment *targetEl; int hiddenNo = -1; targetEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1); if (targetEl == NULL) return -1; *ret_ids = NULL; if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0) return NULL; if (_SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)) >= SDL_DTD_1_1) hiddenNo = 0; return (MapPath(&idSegs, targetEl, -1, 0, hiddenNo, ret_ids)); }
bool GameMap::loadMap(const int& level) { string fileName = StringUtils::format("map/map_%03d.tmx", level); TMXTiledMap* map = TMXTiledMap::create(fileName); m_map = map; float scale = 1 / Director::getInstance()->getContentScaleFactor(); //GridPos TMXObjectGroup* group = map->getObjectGroup("TowerPos"); ValueVector vec = group->getObjects(); m_gridPos.clear(); m_gridPos.resize(vec.size()); if (!vec.empty()) { int i = 0; for (const auto& v : vec) { const ValueMap& dict = v.asValueMap(); m_gridPos[i] = new GridPos( i, Rect(dict.at("x").asFloat(), dict.at("y").asFloat(), dict.at("width").asFloat(), dict.at("height").asFloat())); i++; } } //计算临近的塔的ID float h = group->getProperty("TowerPosHeight").asFloat() *scale; float w = group->getProperty("TowerPosWidth").asFloat() *scale; float dis = (h + 2)*(h + 2) + (w + 2)*(w + 2); vector<int> GridPosID; for (auto t1 : m_gridPos) { GridPosID.clear(); Point pos = t1->getPos(); for (auto t2 : m_gridPos) { if (t1 != t2 && pos.distanceSquared(t2->getPos())<=dis) { GridPosID.push_back(t2->ID); } } int around[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; for (auto tid : GridPosID) { Rect rect = m_gridPos[tid]->getRect(); if (rect.containsPoint( Point(pos.x , pos.y + h )))around[North] = tid; else if (rect.containsPoint( Point(pos.x - w, pos.y + h )))around[NorthWest] = tid; else if (rect.containsPoint( Point(pos.x - w, pos.y )))around[West] = tid; else if (rect.containsPoint( Point(pos.x - w, pos.y - h )))around[SouthWest] = tid; else if (rect.containsPoint( Point(pos.x , pos.y - h )))around[South] = tid; else if (rect.containsPoint( Point(pos.x + w, pos.y - h )))around[SouthEast] = tid; else if (rect.containsPoint( Point(pos.x + w, pos.y )))around[East] = tid; else if (rect.containsPoint( Point(pos.x + w, pos.y + h )))around[NorthEast] = tid; } t1->setAroundGridPosID(around); } //MonsterPath group = map->getObjectGroup("Path"); vec = group->getObjects(); MonsterPath.clear(); if (!vec.empty()) { vector<Point> posvec; for (const auto& var : vec) { posvec.clear(); const ValueMap& dict = var.asValueMap(); const ValueVector& vec2 = dict.at("polylinePoints").asValueVector(); Point pos = Point(dict.at("x").asFloat(), dict.at("y").asFloat()); for (const auto& v : vec2) { const ValueMap& dict = v.asValueMap(); posvec.push_back(Point(pos.x + dict.at("x").asFloat()*scale, pos.y - dict.at("y").asFloat()*scale)); //posvec.push_back(Point(pos.x + dict.at("x").asFloat(), pos.y - dict.at("y").asFloat())); } MonsterPath.push_back(MapPath(dict.at("LoopTo").asInt(), posvec)); } } //WaveData int waveCount= map->getProperty("WaveCount").asInt(); std::stringstream ss; string propertyName; WaveList.clear(); for (int i = 1; i <= waveCount; i++) { propertyName = StringUtils::format("Wave%03d", i); group = map->getObjectGroup(propertyName); CCASSERT(group != nullptr, string("propertyName :" + propertyName +" NOT found").c_str()); Wave wave; wave.WaveTime = group->getProperty("waveTime").asInt(); int momsterCount = group->getProperty("momsterCount").asInt(); for (int j = 1; j <=momsterCount; j++) { propertyName = StringUtils::format("m%03d", j); ss.clear(); ss << group->getProperty(propertyName).asString(); WaveData data; ss >> data.MonsterID; ss >> data.PathID; ss >> data.NextDalay; wave.wavedata.push_back(data); } WaveList.push_back(wave); } return true; }
/****************************************************************************** * Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids) * * Parameters: * * Return Value: 0 if successful, -1 if failure. * * Memory: The memory returned in ret_ids is owned by the caller. * * Purpose: To come up with a path from the top of the volume to the * target id. * ******************************************************************************/ static int MapPath ( _DtCvSegment **cur_id, _DtCvSegment *target_el, int stop_lev, int lev_cnt, int hidden_no, char ***ret_ids) { _DtCvSegment *mySeg = *cur_id; int count = -1; int myLev; SDLIdInfo *info; while (mySeg != NULL) { /* * Does this match the target id? * And, is the element a child of the current path? */ info = _SdlSegToSdlIdInfoPtr(mySeg); myLev = _SdlIdInfoPtrRlevel(info); if (target_el == mySeg && (myLev == -1 || myLev > stop_lev)) { /* * matched the target id. * allocate memory and return. */ count = 0; if (_SdlIdInfoPtrType(info) == SdlIdVirpage) { count++; lev_cnt++; } *ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1)); if ((*ret_ids) == NULL) return -1; (*ret_ids)[lev_cnt] = NULL; if (_SdlIdInfoPtrType(info) == SdlIdVirpage) (*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg)); return count; } else if (myLev != -1 && myLev != hidden_no && _SdlIdInfoPtrType(info) == SdlIdVirpage) { char *myId = _DtCvContainerIdOfSeg(mySeg); /* * If we've hit a virpage that is a sibling or an aunt * set the search pointer to this segment (since this * is where we want to start searching again) and return * a negative on the successful search. */ if (myLev <= stop_lev) { *cur_id = mySeg; return -1; } /* * this virpage is a child of mine, so look at it's children * for the target id. */ mySeg = mySeg->next_seg; count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no, ret_ids); /* * successful response on finding the target id in the virpage's * children. Duplicate the virpage's id string and return to * my parent. */ if (count != -1) { (*ret_ids)[lev_cnt] = strdup(myId); count++; return count; } } else /* did not match the target id and is not a virpage * or is a hidden virpage */ mySeg = mySeg->next_seg; } *cur_id = mySeg; return -1; }