Cocos2d как масштабировать спрайт без масштабирования слоя? Или как масштабировать и обрезать спрайт / слой?

Настройка приложения для iPad: SceneA содержит слой A - 1024x768. Нажмите кнопку в layerA, layerB опускается сверху, используя действие CCMoveTo. LayerB имеет размер только 800x600, поэтому вы можете видеть слой LayerA позади него (подумайте о наложенном эффекте типа экрана паузы). LayerB содержит спрайт 800x600, который пользователь может увеличить, нажав кнопку. Эффект масштабирования - это просто комбинация CCScaleTo и CCMoveTo, позволяющая удерживать его по центру той части, которую он увеличивает. Однако, когда спрайт масштабируется, слой B также располагается поверх слоя A. Есть ли способ масштабировать спрайт в ограниченном окне?


person BobbyScon    schedule 07.03.2012    source источник


Ответы (1)


LayerB должен использовать GL_SCISSOR_TEST, чтобы обрезать себя снаружи. Вы можете легко найти в Google дополнительную информацию об этом, он в основном определяет rect, а затем использует glScissor на нем для удаления внешнего вида. У меня есть класс, который я расширяю, когда мне нужно это сделать, он выглядит следующим образом:

//
//  CCNodeClip.h
//
//  Created by Ignacio Orlandoni on 7/29/11.
//

#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface CCNodeClip : CCLayer {

}

-(void)preVisit;
-(void)postVisit;

@end

-

//
//  CCNodeClip.m
//
//  Created by Ignacio Orlandoni on 7/29/11.
//

#import "CCNodeClip.h"
@implementation CCNodeClip

-(void)visit {
    [self preVisit];
    [super visit];
    [self postVisit];
}

-(void)preVisit {
    if (!self.visible)
        return;

    glEnable(GL_SCISSOR_TEST);

    CGPoint position = [self position];

    //I don't remember if this rect really serves for both orientations, so you may need to change the order of the values here.
    CGRect scissorRect = CGRectMake(position.x, position.y, [self contentSize].width, [self contentSize].height);

    //    CCLOG(@"Scrissor Rect: X: %02f, Y:%02f, W: %02f, H: %02f", scissorRect.origin.x,     scissorRect.origin.y, scissorRect.size.width, scissorRect.size.height);

    // Handle Retina
    scissorRect = CC_RECT_POINTS_TO_PIXELS(scissorRect);

    glScissor((GLint) scissorRect.origin.x, (GLint) scissorRect.origin.y,
              (GLint) scissorRect.size.width, (GLint) scissorRect.size.height);
}

-(void)postVisit {
    glDisable(GL_SCISSOR_TEST);
}


@end 

Теперь, когда это импортировано в LayerB, вы можете определить его как CCNodeClip вместо CCLayer.

Некоторые ссылки ...

glScissor ‹< Форум cocos2d

Обрезка формы круга с помощью opengl-es в cocos2d ‹< StackOverflow

Cocos2d iPhone - обрезка спрайтов / маска / рамка ‹< StackOverflow

Еще одна жемчужина Cocos2D: ClippingNode ‹< Learn-Cocos2d.com

В качестве примечания ...

CCScaleTo + CCMoveTo можно избежать, если точка привязки для спрайта находится по центру, поэтому изображение остается в центре контейнера при масштабировании. (.anchorPoint = ccp(0.5, 0.5);)

person IOrlandoni    schedule 09.03.2012
comment
Кажется, использование вашего кода отлично работает! Это было очень легко реализовать. Мое приложение имеет только альбомную ориентацию, и мне не пришлось ничего менять в вашем коде. Что касается CCScaleTo и MoveTo, я фактически увеличиваю масштаб в разных точках слоя в зависимости от того, где пользователь касается, а не только от центра. Но хороший момент. Огромное спасибо! - person BobbyScon; 09.03.2012
comment
Несмотря на то, что проблема решена, я рекомендую вам поискать GlScissor, чтобы попытаться полностью понять, как это работает и что может. Добро пожаловать. - person IOrlandoni; 09.03.2012
comment
Да, как только я увидел ваш пост (примерно через 3 минуты после того, как вы его разместили), я выполнил поиск в Google и нашел многие из тех же ссылок, которые вы разместили. Моя проблема заключалась в том, что я не знал, что искать. Раньше я не слышал о GLScissor. Ваш код кажется более эффективным, чем настройка на Learn-Cocos2d.com - person BobbyScon; 09.03.2012
comment
Все зависит от того, что вам нужно. Код @ LearnCocos2D учитывает масштабирование, ориентацию и изменения ориентации. Кроме того, сам пост дает хорошие советы и ссылки. - person IOrlandoni; 09.03.2012