Как загрузить анимацию Cocos2d внутри UIViewController в приложении на основе UIKit? - PullRequest
3 голосов
/ 22 февраля 2012

Можно смешать в обычном проекте xcode для iOS в UIViewController одну анимацию на основе cocos2d?

Я экспериментирую с анимацией, выполненной UIImageView, и вместо этого пытаюсь использовать cocos2d. У меня есть пара просмотров, где размещены анимации.

Возможно ли создать объект CC2dAnimationObject для использования в UIViewController?

Спасибо.

решено -

Привет всем, я счастливый парень. Я получаю подход.

Я создал пару классов один CCScoreBoardLG (имена не являются окончательными), этот класс является подклассом UIViewController и загружает EAGLView с объектом OTAnimationCC2d, который является контейнером анимации.

CCScoreBoardLG можно разместить в любом месте UIKit View Controller, а фон прозрачен для размещения анимации и просмотра содержимого за ней.

Некоторые части жестко запрограммированы, потому что в целях тестирования их легко адаптировать для загрузки любого вида анимации. анимация находится в середине CCScene и находится в режиме цикла.

Вот классы:

OTAnimationCC2d.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface OTAnimationCC2d : CCLayer{

}
+(id) scene;
@end

OTAnimationCC2d.m

#import "OTAnimationCC2d.h"


@implementation OTAnimationCC2d
+(id) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    OTAnimationCC2d *layer = [OTAnimationCC2d node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}
-(id)init {
    self = [super init];

    if (self) {

        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"OTScoreBoard_LG_Atlas_Team_1_4.plist"];
        CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"OTScoreBoard_LG_Atlas_Team_1_4.png"];
        [self addChild:spriteSheet];

        NSMutableArray *animFrames = [NSMutableArray array];
        for (int i = 1; i <= 50; i++) {
            NSString *file;

            if (i<10)
                file = [NSString stringWithFormat:@"Frame_00%d.png", i];
            else if (i<100)
                file = [NSString stringWithFormat:@"Frame_0%d.png", i];
            else if (i<1000)
                file = [NSString stringWithFormat:@"Frame_%d.png", i];

            CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:file];

            [animFrames addObject:frame];
        }

        CGSize s = [[CCDirector sharedDirector] winSize];

        CCSprite *player = [CCSprite spriteWithSpriteFrameName:@"Frame_001.png"];
        player.rotation = -90;
        player.position = ccp(s.width/2,s.height/2);

        [spriteSheet addChild:player];

        CCAnimation *anim = [CCAnimation animationWithFrames:animFrames delay:0.05f];
        CCRepeatForever *repeat = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:anim restoreOriginalFrame:NO]];
        [player runAction:repeat];
    }

    return self;
}
@end

CCScoreBoardLG.h

#import <UIKit/UIKit.h>
#import "cocos2d.h"
#import "CCOTConfig.h"
#import "OTAnimationCC2d.h"

@interface CCScoreBoardLG : UIViewController
- (void)startCCLayer;
@end

CCScoreBoardLG.m

#import "CCScoreBoardLG.h"

@implementation CCScoreBoardLG
- (void) removeStartupFlicker
{
#if GAME_AUTOROTATION == kGameAutorotationUIViewController

        CC_ENABLE_DEFAULT_GL_STATES();
        CCDirector *director = [CCDirector sharedDirector];
        CGSize size = [director winSize];
        CCSprite *sprite = [CCSprite spriteWithFile:@"OTScoreBoardBackground.png"];
        sprite.position = ccp(size.width/2, size.height/2);
        sprite.rotation = -90;
        [sprite visit];
        [[director openGLView] swapBuffers];
        CC_ENABLE_DEFAULT_GL_STATES();

#endif
}
- (void)startCCLayer
{
    if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
        [CCDirector setDirectorType:kCCDirectorTypeDefault];


    CCDirector *director = [CCDirector sharedDirector];

    EAGLView *glView = [EAGLView viewWithFrame:[self.view frame]
                                   pixelFormat:kEAGLColorFormatRGBA8    // kEAGLColorFormatRGBA8
                                   depthFormat:0                        // GL_DEPTH_COMPONENT16_OES
                        ];

    [director setOpenGLView:glView];
    [director openGLView].opaque = NO;
    [director openGLView].backgroundColor = [UIColor clearColor];

    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[director openGLView].layer;
    eaglLayer.opaque = NO;
    eaglLayer.frame = self.view.bounds;

    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
    const CGFloat myColor[] = {0.0, 0.0, 0.0, 0.0};
    eaglLayer.backgroundColor = CGColorCreate(rgb, myColor);
    CGColorSpaceRelease(rgb);

    [director openGLView].opaque = NO;
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 

#if GAME_AUTOROTATION == kGameAutorotationUIViewController
    [director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#else
    [director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#endif

    [director setAnimationInterval:1.0/60];
    [director setDisplayFPS:NO];

    [self setView:glView];

    [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];

    [self removeStartupFlicker];

    [[CCDirector sharedDirector] runWithScene: [OTAnimationCC2d scene]];

}


// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    //
    // There are 2 ways to support auto-rotation:
    //  - The OpenGL / cocos2d way
    //     - Faster, but doesn't rotate the UIKit objects
    //  - The ViewController way
    //    - A bit slower, but the UiKit objects are placed in the right place
    //

#if GAME_AUTOROTATION==kGameAutorotationNone
    //
    // EAGLView won't be autorotated.
    // Since this method should return YES in at least 1 orientation, 
    // we return YES only in the Portrait orientation
    //
    return ( interfaceOrientation == UIInterfaceOrientationPortrait );

#elif GAME_AUTOROTATION==kGameAutorotationCCDirector
    //
    // EAGLView will be rotated by cocos2d
    //
    // Sample: Autorotate only in landscape mode
    //
    if( interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
        [[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeRight];
    } else if( interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        [[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeLeft];
    }

    // Since this method should return YES in at least 1 orientation, 
    // we return YES only in the Portrait orientation
    return ( interfaceOrientation == UIInterfaceOrientationPortrait );

#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
    //
    // EAGLView will be rotated by the UIViewController
    //
    // Sample: Autorotate only in landscpe mode
    //
    // return YES for the supported orientations

    return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );

#else
#error Unknown value in GAME_AUTOROTATION

#endif // GAME_AUTOROTATION


    // Shold not happen
    return NO;
}

//
// This callback only will be called when GAME_AUTOROTATION == kGameAutorotationUIViewController
//
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    //
    // Assuming that the main window has the size of the screen
    // BUG: This won't work if the EAGLView is not fullscreen
    ///
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGRect rect = CGRectZero;


    if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)      
        rect = screenRect;

    else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
        rect.size = CGSizeMake( screenRect.size.height, screenRect.size.width );

    CCDirector *director = [CCDirector sharedDirector];
    EAGLView *glView = [director openGLView];
    float contentScaleFactor = [director contentScaleFactor];

    if( contentScaleFactor != 1 ) {
        rect.size.width *= contentScaleFactor;
        rect.size.height *= contentScaleFactor;
    }
    glView.frame = rect;
}
#endif // GAME_AUTOROTATION == kGameAutorotationUIViewController


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

@end

Как использовать. Из вида, где мы хотим разместить анимацию CC2d:

CCScoreBoardLG *LG = [[CCScoreBoardLG alloc] init];
LG.view.frame = CGRectMake(10, 300, 1004, 300);
[LG.view setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:LG.view];
[LG startCCLayer];

Я абсолютно нуб в техниках CC2d и GL. Извините, если какой-либо гуру CC2d находит ошибки или вещи, которые не являются правильными. Это работает для меня.

Ответы [ 2 ]

0 голосов
/ 11 апреля 2012

CCDirector в Cocos2D 2.x основан на UIViewController.

Таким образом, вы можете добавить его представление, как и любой другой UIView.

0 голосов
/ 22 февраля 2012

Нет, не напрямую. Вам придется вручную обновить все анимированные свойства узла cocos2d и применить изменения к соответствующим свойствам UIView в каждом кадре.

Существует класс CCUIViewWrapper , который может помочь вам в этом, по крайней мере, он выглядит как хороший шаблон, который вы можете изменить в соответствии со своими потребностями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...