// // IMapController.h // SteveMaggieCpp // // Created by Katarzyna Kalinowska-Górska on 17.05.2017. // // #include "AniMiscUtils.h" #include "AniBasicMapController.h" #include "AniScalingUtils.h" #include "AniJSONParseUtils.h" #include "AniMathUtils.h" #include "AniTutorialMapControl.h" #include "AniScalingUtils.h" AniBasicMapController::AniBasicMapController(cocos2d::TMXTiledMap* p_map, IMapAdventureObjectMapper* p_adventureObjectMapper) : IMapController(p_map, p_adventureObjectMapper) { parseMapProperties(); m_maxMapScale = m_map->getParent()->getScale(); m_minMapScale = AniScalingUtils::imageAspectFillGetScale(m_map->getParent()->getBoundingBox().size, cocos2d::Director::getInstance()->getWinSize()); //todo if maps has darkness TODO TODO TODO change all of this to separate tmxes, remove the level call from here if(AniMiscUtils::lastLevel() == AniMiscUtils::Level::ADULT){ m_mapAdditionalDarknessLayer = cocos2d::Layer::create(); p_map->addChild(m_mapAdditionalDarknessLayer, p_map->getLayer("TileLayerDarkness")->getLocalZOrder()+1); //TODO auto mapSize = p_map->getMapSize(); for(int i = 0; i < mapSize.width; ++i){ m_darknessData.push_back(std::vector()); for(int j = 0; j < mapSize.height; ++j){ m_darknessData[i].push_back(TileDarknessData(true)); } } } else { auto layerDarkness = p_map->getLayer("TileLayerDarkness"); if(layerDarkness != nullptr){ layerDarkness->setVisible(false); } } } void AniBasicMapController::addBlockedTiles(std::vector p_tiles, bool recalculateGraph){ if(p_tiles.size() > 0){ for(auto it = p_tiles.begin(); it != p_tiles.end(); ++it){ AniMapUtils::getInstance().setTilePassable(*it, false); } if(recalculateGraph){ AniMapUtils::getInstance().recalculateMapGraph(m_map, getTileLayer(), p_tiles); } } } void AniBasicMapController::removeBlockedTiles(std::vector p_tiles, bool recalculateGraph){ if(p_tiles.size() > 0){ for(auto it = p_tiles.begin(); it != p_tiles.end(); ++it){ AniMapUtils::getInstance().setTilePassable(*it, true); } if(recalculateGraph){ AniMapUtils::getInstance().recalculateMapGraph(m_map, getTileLayer(), p_tiles); } } } // map image objects IMapImageObject* AniBasicMapController::getMapImageObject(std::string p_objectName){ if (m_mapImageObjects.find(p_objectName) != m_mapImageObjects.end()) { return m_mapImageObjects[p_objectName]; } return nullptr; } std::vector AniBasicMapController::getMapImageObjects(){ std::vector objects; for(auto it = m_mapImageObjects.begin(); it != m_mapImageObjects.end(); ++it) { objects.push_back(it->second); } return objects; } std::vector AniBasicMapController::getMapImageObjectsBoundByRect(cocos2d::Rect p_rect){ std::vector objects; for(auto it = m_mapImageObjects.begin(); it != m_mapImageObjects.end(); ++it) { if(p_rect.intersectsRect(it->second->getBoundingBox())){ objects.push_back(it->second); } } return objects; } // map adventure objects void AniBasicMapController::parseAdventureObjects(const std::string& p_mapAdventureObjectsFile, IMapAdventureObjectDelegate* p_objectsDelegate) { std::string jsonString = AniJSONParseUtils::loadJSONFromFile(p_mapAdventureObjectsFile); rapidjson::Document parsedJson; parsedJson.Parse(jsonString.c_str()); if(AniJSONParseUtils::hasMemberArray(parsedJson, "mapAdventureObjects")){ auto advObjects = parsedJson["mapAdventureObjects"].GetArray(); for (rapidjson::Value::ConstValueIterator itr = advObjects.Begin(); itr != advObjects.End(); ++itr) { auto adventureObject = m_adventureObjectMapper->createObject(*itr, this); if(p_objectsDelegate != nullptr){ adventureObject->setDelegate(p_objectsDelegate); } m_adventureObjects.push_back(adventureObject); auto occupiedTiles = adventureObject->getOccupiedTiles(); auto entryTiles = adventureObject->getEntryTiles(); auto finalTiles = occupiedTiles; for(auto it = entryTiles.begin(); it != entryTiles.end(); ++it){ if(std::find(occupiedTiles.begin(), occupiedTiles.end(), *it) == occupiedTiles.end()){ finalTiles.push_back(*it); } } for(auto it = finalTiles.begin(); it < finalTiles.end(); ++it){ m_adventureObjectsMapping.insert(std::make_pair(*it, adventureObject)); // revealTile((*it).convertToVec2()); } auto blockedTiles = adventureObject->getBlockedTiles(); addBlockedTiles(blockedTiles, false); } AniMapUtils::getInstance().recalculateMapGraphAsync(m_map, getTileLayer(), [](){}); } } std::vector AniBasicMapController::getAdventureObjectsAtTile(const AniMapUtils::TileData& p_tileData, bool activeObjectsOnly){ std::vector advObjects; auto rangeIters = m_adventureObjectsMapping.equal_range(p_tileData); for(auto objectsIter = rangeIters.first; objectsIter != rangeIters.second; ++objectsIter){ if(objectsIter->second->isActive()){ advObjects.push_back(objectsIter->second); } } return advObjects; } void AniBasicMapController::clearAdventureObjects(bool clearAssociatedImageObjects){ for(auto it = m_adventureObjects.begin(); it != m_adventureObjects.end(); ++it){ if(clearAssociatedImageObjects){ auto assMapImageObjects = (*it)->getAssociatedMapImageObjects(); for(auto mobIt = assMapImageObjects.rbegin(); mobIt != assMapImageObjects.rend(); ++mobIt){ mobIt->second->removeFromParent(); //since MapImageObjects are cocos Nodes and all cocos2d nodes are autoreleased, no need to delete automatically auto extMobIt = m_mapImageObjects.find(mobIt->first); m_mapImageObjects.erase(extMobIt->first); } } delete *it; } m_adventureObjects.clear(); m_adventureObjectsMapping.clear(); } void AniBasicMapController::clearAdventureObject(IMapAdventureObject* p_adventureObject, bool clearAssociatedImageObjects){ auto tiles = p_adventureObject->getOccupiedTiles(); for(auto it = tiles.begin(); it < tiles.end(); ++it){ auto advObjectAtTile = m_adventureObjectsMapping.equal_range(*it); for(auto objectsIter = advObjectAtTile.first; objectsIter != advObjectAtTile.second;){ if(objectsIter->second == p_adventureObject){ objectsIter = m_adventureObjectsMapping.erase(objectsIter); } else { ++objectsIter; } break; } } auto advObjIt = std::find(m_adventureObjects.begin(), m_adventureObjects.end(), p_adventureObject); m_adventureObjects.erase(advObjIt); } // costly. use with caution. void AniBasicMapController::remapAdventureObject(IMapAdventureObject* p_adventureObject){ // first, remove all the previous mappings. this is the part that is costly. for(auto advObjectsIter = m_adventureObjectsMapping.begin(); advObjectsIter != m_adventureObjectsMapping.end(); ){ if(advObjectsIter->second == p_adventureObject){ advObjectsIter = m_adventureObjectsMapping.erase(advObjectsIter); } else { ++advObjectsIter; } } //TODO make a separate func to mere those auto newOccupiedTiles = p_adventureObject->getOccupiedTiles(); auto newEntryTiles = p_adventureObject->getEntryTiles(); auto finalTiles = newOccupiedTiles; for(auto it = newEntryTiles.begin(); it != newEntryTiles.end(); ++it){ if(std::find(newOccupiedTiles.begin(), newOccupiedTiles.end(), *it) == newOccupiedTiles.end()){ finalTiles.push_back(*it); } } for(auto it = finalTiles.begin(); it < finalTiles.end(); ++it){ m_adventureObjectsMapping.insert(std::make_pair(*it, p_adventureObject)); // revealTile((*it).convertToVec2()); } } //TODO incorporate cameraCut also here cocos2d::Vec2 AniBasicMapController::moveCamera(float deltaX, float deltaY, bool animated){ auto AniMapLayerNode = m_map->getParent(); auto newX = AniMapLayerNode->getPositionX() + deltaX; auto newY = AniMapLayerNode->getPositionY() + deltaY; auto winSize = AniMapLayerNode->getParent()->getBoundingBox().size; //parent scene size //cocos2d::Director::getInstance()->getWinSize() newX = MIN(newX, - _cutLeft); newY = MIN(newY, 0); newX = MAX(newX, winSize.width - m_map->getMapSize().width*m_map->getTileSize().width - _cutRight); newY = MAX(newY, winSize.height - m_map->getMapSize().height*m_map->getTileSize().height - _cutTop); auto oldPosition = AniMapLayerNode->getPosition(); if(animated){ AniMapLayerNode->runAction(cocos2d::MoveTo::create(AniMiscUtils::StandardAnimationTime, cocos2d::Point(newX, newY))); } else { AniMapLayerNode->setPosition(cocos2d::Point(newX, newY)); } //return real deltaX and deltaY return cocos2d::Vec2(newX - oldPosition.x, newY - oldPosition.y); } bool AniBasicMapController::setCameraCenter(cocos2d::Point position, bool instantEffect){ auto AniMapLayerNode = m_map->getParent(); auto winSize = cocos2d::Director::getInstance()->getWinSize(); auto x = MAX(position.x, getMinAvailableCameraX(winSize)); auto y = MAX(position.y, getMinAvailableCameraY(winSize)); x = MIN(x, getMaxAvailableCameraX(winSize)); y = MIN(y, getMaxAvailableCameraY(winSize)); auto actualPosition = cocos2d::Point(x, y); auto centerOfView = cocos2d::Point(winSize.width/2, winSize.height/2); auto viewPoint = cocos2d::Point(centerOfView.x - actualPosition.x, centerOfView.y - actualPosition.y); // cocos2d::log("x: %f y: %f\n", x,y); if(viewPoint.x != AniMapLayerNode->getPositionX() || viewPoint.y != AniMapLayerNode->getPositionY()){ setCameraDestination(viewPoint); if(instantEffect){ AniMapLayerNode->setPosition(viewPoint); } return true; } else { return false; } } float AniBasicMapController::getMinAvailableCameraX(cocos2d::Size winSize){ if(m_cameraCut.equals(cocos2d::Rect::ZERO)){ return winSize.width/2 + _cutLeft; } else { return m_cameraCut.getMinX() + winSize.width/2; } } float AniBasicMapController::getMaxAvailableCameraX(cocos2d::Size winSize){ if(m_cameraCut.equals(cocos2d::Rect::ZERO)){ return m_map->getMapSize().width*m_map->getTileSize().width - winSize.width/2 - _cutRight; } else { return m_cameraCut.getMaxX() - winSize.width/2; } } float AniBasicMapController::getMinAvailableCameraY(cocos2d::Size winSize){ if(m_cameraCut.equals(cocos2d::Rect::ZERO)){ return winSize.height/2; } else { return m_cameraCut.getMinY() + winSize.height/2; } } float AniBasicMapController::getMaxAvailableCameraY(cocos2d::Size winSize){ if(m_cameraCut.equals(cocos2d::Rect::ZERO)){ return m_map->getMapSize().height*m_map->getTileSize().height - winSize.height/2 + _cutTop; } else { return m_cameraCut.getMaxY() - winSize.height/2; } } bool AniBasicMapController::centerCameraOnNode(cocos2d::Node* p_node, bool instantEffect){ auto nodeCenter = cocos2d::Point(p_node->getBoundingBox().getMidX(), p_node->getBoundingBox().getMidY()); return setCameraCenter(nodeCenter, instantEffect); } void AniBasicMapController::cancelZoomMode(){ if(m_isReturningFromZoomMode){ return; } if(m_isInZoomMode){ m_isReturningFromZoomMode = true; static float animTime = 0.1f; m_map->getParent()->runAction(cocos2d::Sequence::create(cocos2d::Spawn::create(cocos2d::ScaleTo::create(animTime, m_originalMapParentScale), nullptr), cocos2d::CallFunc::create([&](){ moveCamera(m_originalMapPosition.x - getCameraPosition().x, m_originalMapPosition.y - getCameraPosition().y, false); }), cocos2d::DelayTime::create(AniMiscUtils::StandardAnimationTime), cocos2d::CallFunc::create([&](){ m_isReturningFromZoomMode = false; m_isInZoomMode = false; //TODO mind it - if any stop actions are called anywhere tut_sendTappedToFinishMapMovingEvent(); }), nullptr));//todo magic number } } void AniBasicMapController::revealTile(cocos2d::Vec2 tileCoord){ if(m_darknessData[tileCoord.x][tileCoord.y].dark){ auto darknessTile = m_map->getLayer("TileLayerDarkness")->getTileAt(tileCoord); if(darknessTile != nullptr){ darknessTile->setVisible(false); m_darknessData[tileCoord.x][tileCoord.y].dark = false; } } else { auto& sprites = m_darknessData[tileCoord.x][tileCoord.y].additionalSprites; for(auto it = sprites.begin(); it != sprites.end(); ++it){ (*it)->removeFromParent(); } sprites.clear(); //TODO if there were any overlays, remove them FUNKCJA // auto additionalDSprites = m_additionalDarknessSprites.equal_range(tileCoord); // for(auto it = additionalDSprites.first; it != additionalDSprites.second; ++it){ // it->second->removeFromParent(); // it = m_additionalDarknessSprites.erase(it); // } } } void AniBasicMapController::revealTilesInRadius(cocos2d::Point p_center, float p_radiusX, float p_radiusY){ if(m_mapAdditionalDarknessLayer){ //TOOD add a boolean auto layerSize = getTileLayer()->getContentSize(); auto squareX = fmax(p_center.x - p_radiusX,0); auto squareY = fmax(p_center.y - p_radiusY,0); auto squareMaxX = fmin(p_center.x + p_radiusX, layerSize.width); auto squareMaxY = fmin(p_center.y + p_radiusY, layerSize.height); auto square = cocos2d::Rect(squareX, squareY, squareMaxX - squareX, squareMaxY - squareY); auto tileSize = m_map->getTileSize(); auto mapSize = m_map->getMapSize(); std::vector borderTiles; auto tilesToReveal = AniMapUtils::getInstance().getTilesIntersectingRect(square, tileSize.width, tileSize.height, m_map->getMapSize().width, m_map->getMapSize().height, borderTiles); for (auto it = tilesToReveal.begin(); it != tilesToReveal.end(); ++it) { revealTile((*it).convertToVec2()); } // auto darknessLayer = m_map->getLayer("TileLayerDarkness"); for (auto it = borderTiles.begin(); it != borderTiles.end(); ++it) { auto bTile = *it; auto tileNeighbours = AniMapUtils::getInstance().listTileNeighbours(bTile, m_map, getTileLayer(), true); for(auto n_it = tileNeighbours.begin(); n_it != tileNeighbours.end(); ++n_it){ //TODO separate func auto nTile = *n_it; if(m_darknessData[nTile.col][nTile.row].dark){ // if neighbour is still dark std::string borderSpriteFilePath; //TODO separate func if(nTile.col > bTile.col){ if(nTile.row == bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_right.png"; } else if(nTile.row < bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_tr.png"; } else {// if(nTile.row > bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_br.png"; } } else if(nTile.col < bTile.col){ if(nTile.row == bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_left.png"; } else if(nTile.row < bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_tl.png"; } else {// if(nTile.row > bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_bl.png"; } } else { //if(nTile.col == bTile.col){ if(nTile.row < bTile.row){ borderSpriteFilePath = "graphics/game_map/tile_black_up.png"; } else { borderSpriteFilePath = "graphics/game_map/tile_black_down.png"; } } if(!borderSpriteFilePath.empty()){ auto additionalSprite = cocos2d::Sprite::create(borderSpriteFilePath); m_mapAdditionalDarknessLayer->addChild(additionalSprite); additionalSprite->setPosition(AniMapUtils::getInstance().getTileMiddlePosition(m_map, bTile.col, bTile.row)); m_darknessData[bTile.col][bTile.row].additionalSprites.push_back(additionalSprite); } } else if (std::find(borderTiles.begin(), borderTiles.end(), nTile) == borderTiles.end()) { //if neighbour not dark, does not belong to the border and happens to have any sprites, and no more dark neighbours, remove them auto neighboursNeighbours = AniMapUtils::getInstance().listTileNeighbours(nTile, m_map, getTileLayer(), true); auto deleteSprites = true; for(auto nnIt = neighboursNeighbours.begin(); nnIt != neighboursNeighbours.end(); ++nnIt){ if(m_darknessData[nnIt->col][nnIt->row].dark){ deleteSprites = false; } } if(deleteSprites){ auto& sprites = m_darknessData[nTile.col][nTile.row].additionalSprites; for(auto it = sprites.begin(); it != sprites.end(); ++it){ (*it)->removeFromParent(); } sprites.clear(); } } } } } } void AniBasicMapController::parseMapProperties(){ auto mapProps = m_map->getProperties(); auto scale = 1/cocos2d::Director::getInstance()->getContentScaleFactor(); if(mapProps.find("cutLeft") != mapProps.end()){ _cutLeft = mapProps["cutLeft"].asFloat()*scale; } if(mapProps.find("cutTop") != mapProps.end()){ _cutTop = mapProps["cutTop"].asFloat()*scale; // m_map->getParent()->setContentSize(cocos2d::Size(m_map->getParent()->getContentSize().width, m_map->getParent()->getContentSize().height + _cutTop)); } if(mapProps.find("cutRight") != mapProps.end()){ _cutRight = mapProps["cutRight"].asFloat()*scale; } } void AniBasicMapController::update(float dt) { if(_movingMap){ // log("velocity: "+this.currentMapVelocityX + " " + this.currentMapVelocityY); auto deltaMoveX = _currentMapVelocityX * dt; auto deltaMoveY = _currentMapVelocityY * dt; auto deltas = this->moveCamera(deltaMoveX, deltaMoveY); if(deltas.x == 0){ _currentMapVelocityX = 0; } if(deltas.y == 0){ _currentMapVelocityY = 0; } auto mapAcceleration = MapAcceleration*AniScalingUtils::scaleAspectFillToDesignIpadProSize(); if(_currentMapVelocityX != 0){ auto newVelocityX = _currentMapVelocityX > 0 ? _currentMapVelocityX + mapAcceleration * dt : _currentMapVelocityX - mapAcceleration * dt; if(AniMathUtils::signum(newVelocityX) != AniMathUtils::signum(_currentMapVelocityX) || newVelocityX == 0){ newVelocityX = 0; } _currentMapVelocityX = newVelocityX; } if(_currentMapVelocityY != 0){ auto newVelocityY = _currentMapVelocityY > 0 ? _currentMapVelocityY + mapAcceleration * dt : _currentMapVelocityY - mapAcceleration * dt; if(AniMathUtils::signum(newVelocityY) != AniMathUtils::signum(_currentMapVelocityY) || newVelocityY == 0){ newVelocityY = 0; } _currentMapVelocityY = newVelocityY; } if(_currentMapVelocityX == 0 && _currentMapVelocityY == 0){ _movingMap = false; } } else if(!m_isInZoomMode) { auto cameraPos = getCameraPosition(); if(cameraPos != m_cameraDestination){ // cocos2d::log("UPDATE CHECK pos: %f x %f dst: %f x %f\n", cameraPos.x, cameraPos.y, m_cameraDestination.x, m_cameraDestination.y); auto fullDelta = m_cameraDestination - cameraPos; auto autoDeltaValue = m_cameraVelocity*AniScalingUtils::scaleAspectFillToDesignIpadProSize()*dt; // cocos2d::log("delta: %f %f\n", fullDelta.x, fullDelta.y); auto deltaX = abs(fullDelta.x) < autoDeltaValue ? fullDelta.x : autoDeltaValue*AniMathUtils::signum(fullDelta.x); auto deltaY = abs(fullDelta.y) < autoDeltaValue ? fullDelta.y : autoDeltaValue*AniMathUtils::signum(fullDelta.y); moveCamera(deltaX, deltaY); // cocos2d::log("UPDATE CHECK pos: %f x %f dst: %f x %f AFTER\n", cameraPos.x, cameraPos.y, m_cameraDestination.x, m_cameraDestination.y); } } } void AniBasicMapController::reset(){ for(auto it = m_adventureObjects.begin(); it != m_adventureObjects.end(); ++it){ (*it)->reset(); } } // IMapControlInterface void AniBasicMapController::handleCommandMultipleXYPress(const std::vector& eventData){ if(m_isReturningFromZoomMode){ return; } if(!m_isInZoomMode){ auto AniMapLayer = m_map->getParent(); m_originalMapParentScale = AniMapLayer->getScale(); m_originalMapPosition = AniMapLayer->getPosition(); m_originalAnchorPoint = AniMapLayer->getAnchorPoint(); m_isInZoomMode = true; auto touchMiddlePoint = (eventData[0].screenPointCurrent + eventData[1].screenPointCurrent) / 2; auto mapMidPoint = AniMapLayer->convertToNodeSpace(touchMiddlePoint); auto newAnchorPoint = cocos2d::Point(mapMidPoint.x/AniMapLayer->getContentSize().width, mapMidPoint.y / AniMapLayer->getContentSize().height); if(AniMapLayer->getBoundingBox().getMinX() == 0){ newAnchorPoint.x = 0; } AniMapLayer->setAnchorPoint(newAnchorPoint); m_onZoomEnteredCallback(); } _mapMoveStartLocation = eventData[0].screenPointCurrent; _mapMoveStartTime = cocos2d::utils::getTimeInMilliseconds(); m_mapZoomStartDistance = (eventData[0].screenPointCurrent - eventData[1].screenPointCurrent).length(); m_mapZoomStartScale = m_map->getParent()->getScale(); } void AniBasicMapController::handleCommandMultipleXYMove(const std::vector&eventData){ if(m_isReturningFromZoomMode || !m_isInZoomMode){ return; } // TODO add debug assert for debug build and this? if(eventData.size() > 1) auto currentPoint1 = eventData[0].screenPointCurrent; auto currentPoint2 = eventData[1].screenPointCurrent; auto prevPoint1 = eventData[0].screenPointPrevious; auto prevPoint2 = eventData[1].screenPointPrevious; auto delta1 = currentPoint1 - prevPoint1; auto delta2 = currentPoint2 - prevPoint2; auto AniMapLayer = m_map->getParent(); auto newZoomDistance = (currentPoint1 - currentPoint2).length(); auto scale = newZoomDistance / m_mapZoomStartDistance * m_mapZoomStartScale; scale = MAX(scale, m_minMapScale); scale = MIN(scale, m_maxMapScale); AniMapLayer->setScale(scale); // cocos2d::log("scale: %f\n", scale); auto delta = currentPoint1 - prevPoint1; moveCamera(delta.x, delta.y); if(AniMapLayer->getBoundingBox().getMinX() >= -_cutLeft){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.x = 0; AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionX(0); } else if(AniMapLayer->getBoundingBox().getMaxX() <= cocos2d::Director::getInstance()->getWinSize().width -_cutRight){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.x = 1; AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionX(cocos2d::Director::getInstance()->getWinSize().width - m_map->getMapSize().width*m_map->getTileSize().width -_cutRight); } if(AniMapLayer->getBoundingBox().getMinY() >= 0){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.y = 0; AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionY(0); } else if(AniMapLayer->getBoundingBox().getMaxY() <= cocos2d::Director::getInstance()->getWinSize().height - _cutTop*AniMapLayer->getScale()){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.y = 1 + _cutTop/(m_map->getMapSize().height*m_map->getTileSize().height); AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionY(cocos2d::Director::getInstance()->getWinSize().height -_cutTop - m_map->getMapSize().height*m_map->getTileSize().height); } } void AniBasicMapController::handleCommandMultipleXYRelease(const std::vector& eventData){ tut_sendMapMovingFinishedEvent(); } void AniBasicMapController::handleCommandSingleXYPress(const IMapControlSingleXYEventData& eventData){ // nothing } void AniBasicMapController::handleCommandSingleXYMove(const IMapControlSingleXYEventData& eventData){ if(!m_isInZoomMode){ return; } // TODO add debug assert for debug build and this? if(eventData.size() > 1) auto currentPoint = eventData.screenPointCurrent; auto prevPoint = eventData.screenPointPrevious; auto delta = currentPoint - prevPoint; auto AniMapLayer = m_map->getParent(); moveCamera(delta.x, delta.y); //TODO dedup if(AniMapLayer->getBoundingBox().getMinX() >= -_cutLeft){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.x = 0; AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionX(0); } else if(AniMapLayer->getBoundingBox().getMaxX() <= cocos2d::Director::getInstance()->getWinSize().width -_cutRight){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.x = 1; AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionX(cocos2d::Director::getInstance()->getWinSize().width - m_map->getMapSize().width*m_map->getTileSize().width -_cutRight); } if(AniMapLayer->getBoundingBox().getMinY() >= 0){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.y = 0; AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionY(0); } else if(AniMapLayer->getBoundingBox().getMaxY() <= cocos2d::Director::getInstance()->getWinSize().height - _cutTop*AniMapLayer->getScale()){ auto newAnchorPoint = AniMapLayer->getAnchorPoint(); newAnchorPoint.y = 1 + _cutTop/(m_map->getMapSize().height*m_map->getTileSize().height); AniMapLayer->setAnchorPoint(newAnchorPoint); AniMapLayer->setPositionY(cocos2d::Director::getInstance()->getWinSize().height -_cutTop - m_map->getMapSize().height*m_map->getTileSize().height); } } void AniBasicMapController::handleCommandSingleXYRelease(const IMapControlSingleXYEventData& eventData){ tut_sendMapMovingFinishedEvent(); } void AniBasicMapController::handleCommandSingleXYTap(const IMapControlSingleXYEventData& eventData){ // cancelZoomMode(); } void AniBasicMapController::tut_sendMapMovingFinishedEvent(){ auto mapEvent = new AniTutorialMapControl::MapFinishedMovingEvent(); m_mapControl->mapEvent(this, mapEvent); delete mapEvent; } void AniBasicMapController::tut_sendTappedToFinishMapMovingEvent(){ auto mapEvent = new AniTutorialMapControl::MapTappedToFinishMovingEvent(); m_mapControl->mapEvent(this, mapEvent); delete mapEvent; }