2011-05-07 7 views
20

Estoy trabajando en un juego con motor de juego cocos2D y hago cargar todo el sprites mientras carga el nivel, ahora porque algunos de sprites (obstáculos) son más altos que 320 píxeles, por lo que parece difícil de verificar. Por lo tanto, para mayor comodidad quiero aplicar el efecto ZOOM IN y ZOOM out, que minimiza todos los sprites de todo el nivel a la vez, y en caso de alejamiento, estos residirán en su antigua posición.Aplicación del efecto de zoom en el entorno de juego cocos2D?

¿Se puede lograr esto?

En caso afirmativo, ¿cómo?

Dígale acerca de pellizcar zoom también.

Respuesta

27

Hacer zoom, es bastante simple, simplemente establece la propiedad de escala de tu capa principal de juego ... pero hay algunas capturas.

Al escalar la capa, cambiará la posición de la capa. No se acercará automáticamente al centro de lo que está mirando actualmente. Si tiene algún tipo de desplazamiento en su juego, tendrá que dar cuenta de esto.

Para hacer esto, configure anchorPoint de su capa en ccp(0.0f, 0.0f), y luego calcule cuánto ha cambiado su capa, y vuelva a colocarla como corresponda.

- (void) scale:(CGFloat) newScale scaleCenter:(CGPoint) 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. 
    CGPoint oldCenterPoint = ccp(scaleCenter.x * yourLayer.scale, scaleCenter.y * yourLayer.scale); 

    // Set the scale. 
    yourLayer.scale = newScale; 

    // Get the new center point. 
    CGPoint newCenterPoint = ccp(scaleCenter.x * yourLayer.scale, scaleCenter.y * yourLayer.scale); 

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

    // Now adjust your layer by the delta. 
    yourLayer.position = ccpAdd(yourLayer.position, centerPointDelta); 
} 

Pinch zoom es más fácil ... solo detecta los toquesMoved, y luego llama a tu rutina de escalado.

- (void) ccTouchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { 

    // Examine allTouches instead of just touches. Touches tracks only the touch that is currently moving... 
    // But stationary touches still trigger a multi-touch gesture. 
    NSArray* allTouches = [[event allTouches] allObjects]; 

    if ([allTouches count] == 2) {    
     // Get two of the touches to handle the zoom 
     UITouch* touchOne = [allTouches objectAtIndex:0]; 
     UITouch* touchTwo = [allTouches objectAtIndex:1]; 

     // Get the touches and previous touches. 
     CGPoint touchLocationOne = [touchOne locationInView: [touchOne view]]; 
     CGPoint touchLocationTwo = [touchTwo locationInView: [touchTwo view]]; 

     CGPoint previousLocationOne = [touchOne previousLocationInView: [touchOne view]]; 
     CGPoint previousLocationTwo = [touchTwo previousLocationInView: [touchTwo view]]; 

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

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

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

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

     // Then, convert the screen position to node space... use your game layer to do this. 
     pinchCenter = [yourLayer 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.  
     // A PINCH_ZOOM_MULTIPLIER of 0.005f works for me, but experiment to find one that you like. 
     [self scale:yourlayer.scale - (distanceDelta * PINCH_ZOOM_MULTIPLIER) 
      scaleCenter:pinchCenter]; 
    }  
} 
+0

Puede sonar tonto pero no tengo idea de cómo calcular [glc_ getModifiedScale], súplicas e elaborarlo. Gracias. – rptwsthi

+0

@rptwsthi Lo siento, ese fue mi error. Ese fue uno de mis códigos que no solucioné para que coincida con el resto. Debería tener más sentido ahora. –

+0

¿podría explicar mejor cómo "convierte la posición de la pantalla en espacio de nodo"? He intentado usar '[self scale: (distanceDelta/PTM_RATIO) scaleCenter: pinchCenter];' y también '[self scale: distanceDelta scaleCenter: [self converttoToNodeSpace: pinchCenter]];' pero ambos (y combinaciones del dos) se vuelven locas cuando apenas pellizco la pantalla. –

1

Si todos los sprites tienen el mismo elemento primario, puede escalar su elemento primario y se escalarán con él, manteniendo sus coordenadas relativas al elemento primario.

+0

Sí, pero la pista de tacto pierde en este caso también, como si el alejamiento se hubiera hecho, entonces para tocar un sprite necesito tocarlo después de 50 a 100 píxeles después de ese sprite ... :( – rptwsthi

0

esta escala código de mi capa por 2 a ubicación específica

[layer setScale:2]; 
    layer.position=ccp(240/2+40,160*1.5); 
    double dx=(touchLocation.x*2-240); 
    double dy=(touchLocation.y*2-160); 
    layer.position=ccp(inGamePlay.position.x-dx,inGamePlay.position.y-dy); 
0

Mi código y funciona mejor que otros:

- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 

    NSArray* allTouches = [[event allTouches] allObjects]; 
    CCLayer *gameField = (CCLayer *)[self getChildByTag:TAG_GAMEFIELD]; 
    if (allTouches.count == 2) { 

     UIView *v = [[CCDirector sharedDirector] view]; 
     UITouch *tOne = [allTouches objectAtIndex:0]; 
     UITouch *tTwo = [allTouches objectAtIndex:1]; 
     CGPoint firstTouch = [tOne locationInView:v]; 
     CGPoint secondTouch = [tTwo locationInView:v]; 
     CGPoint oldFirstTouch = [tOne previousLocationInView:v]; 
     CGPoint oldSecondTouch = [tTwo previousLocationInView:v]; 
     float oldPinchDistance = ccpDistance(oldFirstTouch, oldSecondTouch); 
     float newPinchDistance = ccpDistance(firstTouch, secondTouch); 

     float distanceDelta = newPinchDistance - oldPinchDistance; 
     NSLog(@"%f", distanceDelta); 
     CGPoint pinchCenter = ccpMidpoint(firstTouch, secondTouch); 
     pinchCenter = [gameField convertToNodeSpace:pinchCenter]; 

     gameField.scale = gameField.scale - distanceDelta/100; 
     if (gameField.scale < 0) { 

      gameField.scale = 0; 
     } 
    } 
} 
+0

y ¿qué hay de malo en mi código?no hay código funcional y completo en esta página, excepto el mío. – user2083364

+0

Funciona maravillosamente, muchas gracias. ¡He estado luchando con este pinchZoom por un tiempo! +1 – stenger96

Cuestiones relacionadas