2013-09-01 2 views
1

경계 상자가 제대로 작동하려고하지만 맵의 크기가 조정될 때 계속 실패합니다. 이것이 내 존재의 상처이기 때문에 여기에서 약간의 도움을 사용할 수 있습니다.Cocos2d-X 경계 상자 문제

간단히 말해서, 1 장면, 2 개의 레이어가 있습니다. 하나의 레이어는 HUD이고 다른 레이어는지도입니다. 지도는 큰 슬라이스 이미지에서 100 개의 이미지를 타일링하여 렌더링되는 레이어입니다. 나는이 이미지를 주어진 공간적 스케일링으로 스케일링하고 모든 크기로 멋지게 보입니다. 이 문제는 배율을 조정하는 동안지도의 너비/높이에 대한 경계 상자를 설정하려고 할 때 발생합니다. 제대로 잠글 수 없습니다. 오른쪽 경계선과 위쪽 경계선, 왼쪽과 아래쪽 경계선 만 제대로 작동합니다. 참고로이 기능은 Scale이 1과 같을 때 아름답게 작동하지만 크기가 조정되는대로 모든 것이 어색해집니다. Sprite의 크기를 조정할 때지도 타일의 X, Y가 변경 될 가능성이 큽니다.

bool MapLayer::init() 
{ 
    // Super init 
    if (!CCLayer::init()) 
    { 
     return false; 
    } 

    // We need to enable touches for this layer 
    setTouchEnabled(true); 

    // Set the Anchor Point 
    setAnchorPoint(ccp(0,0)); 

    // We need to initialize the Map Textures for Rendering (Break up further for performance) 
    for(int row = 0; row < NUM_MAP_FRAME_ROWS; row++) 
    { 
     for(int col = 0; col < NUM_MAP_FRAME_COLS; col++) 
     { 
      char imageFrameFile[25] = ""; 
      int imageFrame = ((row * 10) + col) + 1; 

      // Create the String to load the image frame 
      sprintf(imageFrameFile, "map_%02d.png", imageFrame); 

      // Create the Sprite 
      map[row][col] = CCSprite::create(imageFrameFile); 

      // Add the Sprite to the Scene 
      this->addChild(map[row][col], 0); 
     } 
    } 

    // Render the Map at the default Scale (Show entire Map) 
    renderMap(); 

    // Position the Viewport to the center of the map 
    setPosition(ccp(0 - (((map[9][9]->getPosition().x + map[9][9]->getContentSize().width)/2.0f) - ((map[9][9]->getContentSize().width/2.0f))), 
        0 - ((map[0][0]->getPosition().y/2.0f) - ((map[0][0]->getContentSize().height/2.0f))))); 

    return true; 
} 



void MapLayer::renderMap(void) 
{ 
    int overlapBuffer = 0; 
    float spritePositionX = 0.0f; 
    float spritePositionY = 0.0f; 

    // Reset our Boundary variables 
    rightBoundary = 0; 
    topBoundary = 0; 

    // Display the Tile-based Map 
    for(int row = NUM_MAP_FRAME_ROWS - 1; row >= 0; row--) 
    { 
     // Reset the starting position 
     spritePositionX = 0.0f; 

     for(int col = 0; col < NUM_MAP_FRAME_COLS; col++) 
     { 
      CCSprite * pSprite = map[row][col]; 
      CCSize spriteContentSize = pSprite->getContentSize(); 
      float spriteWidth = spriteContentSize.width; 
      float spriteHeight = spriteContentSize.height; 

      // Position the Sprite by using the previous Sprite's location 
      pSprite->setScale(getScale()); 
      pSprite->setAnchorPoint(ccp(0, 0)); 
      pSprite->setPosition(ccp(spritePositionX, spritePositionY)); 

      // Increment for the next Sprite Position 
      spritePositionX += (float)(spriteWidth * pSprite->getScale()) - overlapBuffer; 

      // Increment if this is the last column item 
      if(col == (NUM_MAP_FRAME_COLS - 1)) 
      { 
       // Increment for the next Sprite Position 
       spritePositionY += (float)(spriteHeight * pSprite->getScale()) - overlapBuffer; 
      } 
     } 
    } 





    // TEST CODE 
    CCPoint boundaries = convertToWorldSpace(ccp(spritePositionX, spritePositionY)); 
    rightBoundary = boundaries.x; 
    topBoundary = boundaries.y; 
    // TEST CODE 
} 












void MapLayer::scale(float newScale, CCPoint scaleCenter) 
{ 
    // scaleCenter is the point to zoom to.. 
    // If you are doing a pinch zoom, this should be the center of your pinch. 

    // Get the original center point. 
    CCPoint oldCenterPoint = ccp(scaleCenter.x * getScale(), scaleCenter.y * getScale()); 

    // Set the scale. 
    setScale(newScale); 

    // Get the new center point. 
    CCPoint newCenterPoint = ccp(scaleCenter.x * getScale(), scaleCenter.y * getScale()); 

    // Then calculate the delta. 
    CCPoint centerPointDelta = ccpSub(oldCenterPoint, newCenterPoint); 

    // Now adjust your layer by the delta. 
    setPosition(ccpAdd(getPosition(), centerPointDelta)); 

    // Render the Map to the new Scale 
    renderMap(); 
} 







void MapLayer::checkBoundingBox(void) 
{ 
    // Grab the display size from the director 
    CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 






    cocos2d::CCLog("************************************"); 
    cocos2d::CCLog("WORLD Position-X: %f", convertToWorldSpace(getPosition()).x); 
    cocos2d::CCLog("WORLD Position-Y: %f", convertToWorldSpace(getPosition()).y); 

    cocos2d::CCLog("Position-X: %f", (getPosition()).x); 
    cocos2d::CCLog("Position-Y: %f", (getPosition()).y); 

// cocos2d::CCLog("Map[0][0]-X: %f", convertToWorldSpace(map[0][0]->getPosition()).x); 
// cocos2d::CCLog("Map[0][0]-Y: %f", convertToWorldSpace(map[0][0]->getPosition()).y); 
// cocos2d::CCLog("Map[9][9]-X: %f", convertToWorldSpace(map[9][9]->getPosition()).x); 
// cocos2d::CCLog("Map[9][9]-Y: %f", convertToWorldSpace(map[9][9]->getPosition()).y); 
    cocos2d::CCLog("WinSize Width: %f", winSize.width); 
    cocos2d::CCLog("WinSize Height: %f", winSize.height); 


    /* 
    * Check if we have scaled beyond our limits 
    */ 
    // Check the Width 
    if(getPositionX() >= 0) 
    {   
     // Set the Position 
     setPositionX(0); 
    } 

    // Check the Height 
    if(getPositionY() >= 0) 
    {   
     // Set the Position 
     setPositionY(0); 
    } 




    setPosition(ccpClamp(getPosition(), 
         ccp(-(rightBoundary - winSize.width), 
          -(topBoundary - winSize.height)), 
         ccp(0,0)));   
} 








void MapLayer::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) 
{ 
    // Verify that we are Panning the Map 
    if(pTouches->count() == 1) 
    { 
     // Grab the touch to handle the pan 
     CCTouch * panTouch = (CCTouch *)pTouches->anyObject(); 

     // Get the touch and previous touch 
     CCPoint touchLocation = panTouch->getLocationInView(); 
     CCPoint previousLocation = panTouch->getPreviousLocationInView(); 

     // Get the distance for the current and previous touches. 
     float currentDistanceX = touchLocation.x - previousLocation.x; 
     float currentDistanceY = touchLocation.y - previousLocation.y; 

     // Set new position of the layer 
     setPosition(ccp(getPosition().x + currentDistanceX, getPosition().y - currentDistanceY)); 
    } 

    // Verify that we are Zooming the Map 
    else if (pTouches->count() == 2) 
    { 
     // Grab Touch One 
     CCTouch * touchOne = (CCTouch *)pTouches->anyObject(); 

     // Don't grab the same Touch 
     pTouches->removeObject(touchOne); 

     // Grab Touch Two 
     CCTouch * touchTwo = (CCTouch *)pTouches->anyObject(); 

     // Get the touches and previous touches. 
     CCPoint touchLocationOne = touchOne->getLocationInView(); 
     CCPoint touchLocationTwo = touchTwo->getLocationInView(); 

     CCPoint previousLocationOne = touchOne->getPreviousLocationInView(); 
     CCPoint previousLocationTwo = touchTwo->getPreviousLocationInView(); 

     // Get the distance for the current and previous touches. 
     float currentDistance = sqrt(pow(touchLocationOne.x - touchLocationTwo.x, 2.0f) + 
            pow(touchLocationOne.y - touchLocationTwo.y, 2.0f)); 

     float previousDistance = sqrt(pow(previousLocationOne.x - previousLocationTwo.x, 2.0f) + 
             pow(previousLocationOne.y - previousLocationTwo.y, 2.0f)); 

     // Get the delta of the distances. 
     float distanceDelta = currentDistance - previousDistance; 

     // Next, position the camera to the middle of the pinch. 
     // Get the middle position of the pinch. 
     CCPoint pinchCenter = ccpMidpoint(touchLocationOne, touchLocationTwo); 

     // Then, convert the screen position to node space... use your game layer to do this. 
     pinchCenter = convertToNodeSpace(pinchCenter); 

     // Finally, call the scale method to scale by the distanceDelta, pass in the pinch center as well. 
     // Also, multiply the delta by PINCH_ZOOM_MULTIPLIER to slow down the scale speed. 
     scale(getScale() + (distanceDelta * PINCH_ZOOM_MULTIPLIER), pinchCenter); 
    } 

    /* 
    * Verify that the new position is within our bounding box, otherwise lock it 
    */ 
    checkBoundingBox(); 
} 

답변

1

당신은 정확한 경계 상자를 계산할 수 있습니다

내가 뭘 잘못 모르고 공간 주위에 내 머리를 정리 할 수 ​​없기 때문에 도와주세요 ... 다음은 몇 가지 도움이되는 코드 친 노드의 위치, 축척 및 기준점에 상대적입니다. 다음과 같이 할 수 있습니다 :

CCSize size = CCSizeMake(node.width * node.scaleX, node.height * node.scaleY); 
CCPoint origin = ccp(node.position.x - (size.width * node.anchorPoint.x), node.position.y - (size.height * node.anchorPoint.y)); 
CCRect boundingBox = (CCRect){origin, size}; 
+0

노드가 회전하면 어떻게됩니까? –