Pull to refresh

Создание приложения на framework Cocos2d под iOS

Reading time5 min
Views11K
Здравствуйте, хабражители!

Первая моя игра была написана iPhone SDK про писающего мальчика, она очень тормозила на 3G и 3GS. Вторую сделал с меньшей нагрузкой на процессор, при этом я уже слышал о cocos2d, прочитав документацию про него, я решил к SDK, больше не возвращаться и начал программировать под эту платформу. В этой статье я не буду описывать как устанавливать cocos2d, это описано здесь, постараюсь не повторяться с этим постом. Могу лишь добавить есть стабильная 1.0.1 версия. В этой статье я расскажу как создать меню, анимацию и переход между слоями.

Итак, к делу.

Создаем проект на cocos2d, ориентируем его на iPad, переходим к файлу HelloWorldLayer.m и в методе -(id) init создаем спрайт для заднего фона:

-(id) init
{
	if( (self=[super init])) {
        
                // автоматически определяет размеры экрана, в зависимости от девайса
                 CGSize size = [[CCDirector sharedDirector] winSize];
		
		//Создаем backgroung
                CCSprite * background = [CCSprite spriteWithFile:@"clean bg.png"];
                //Распологаем наш спрайт по центру
                background.position = ccp(size.width/2, size.height/2);
                //добовляем наш спрайт на CCLayer при этом он должен быть на заднем фоне,
                //за это отвечает z:-1
                [self addChild:background z:-1];    
	}
	return self;
}

могу добавить, что когда добавляем наш спрайт на слой можно добавить тег: [self addChild:background z:-1 tag:100]; это делается для того что бы можно было найти спрайт по тегу в другом методе или классе, это делается так: CCSprite *spr = (CCSprite *)[self getChildByTag:100]; потом делаете что хотите с этим спрайтом.

Далее, здесь же создаем меню:

//Создаем ячейки меню
        
        //Ячейка с картинкой
        CCMenuItemImage * image = [CCMenuItemImage itemFromNormalImage:@"new_game.png" 
                                             selectedImage:@"new_game.png" target:self
                                              selector:@selector(perehod_v_igru)];
        //Распологаем нашу ячейку относительно меню(начало координат в центре,
        //там где мы расположили наше меню)
        image.position = ccp(0, 50);
        
        //Ячейка с font
        CCMenuItemFont * font = [CCMenuItemFont itemFromString:@"Опции" target:self 
                        selector:@selector(options)];
        font.position = ccp(0, -50);
        
        //Создаем меню
        //Заносим в меню наши ячейки
        CCMenu * menu = [CCMenu menuWithItems:image, font, nil];
        
        //Распологаем по центру
        menu.position = ccp(size.width /2 , size.height/2);
        
        //Добавляем наше меню
        [self addChild:menu];


меню cocos2d является альтернативой кнопок iPhone SDK, здесь мы рассмотрели 2 вида ячеек(картинка и надпись), как видете они ссылаются на некие методы, в нашем случае это переходы на другие слои:

-(void)perehod_v_igru
{   
    //Заменяем слой главного меню на слой самой игры
    [[CCDirector sharedDirector] replaceScene:[CCTransitionPageTurn transitionWithDuration:1
               scene:[Game node]]];
}


CCTransition отвечает за эффект перехода с одного слоя на другой в течении определенного времени.

-(void)options
{
    //Накладываем слой опции на текущий
    [[CCDirector sharedDirector] pushScene:[Options node]];
}


В этом случае pushScene применяется для временного наложения слоя.

Создаем файлы Options, нажимаем команд + N:

image

image

image

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

Далее создаем CCMenu и метод возвращающий обатно в главно меню:

-(id) init {
    //В RGB можем настроить цвет слоя
    if ((self = [super initWithColor:ccc4(255, 0, 0, 155)])) {  
        
                CGSize size = [[CCDirector sharedDirector] winSize];
        
                CCMenuItemFont * font = [CCMenuItemFont itemFromString:@"В МЕНЮ" target:self 
                selector:@selector(backItem)];
                font.position = ccp(0, 0);
        
                CCMenu * menu = [CCMenu menuWithItems: font, nil];
                menu.position = ccp(size.width /2 , size.height/2);
                [self addChild:menu];

	}
	return self;
}

-(void)backItem{
    //Переходим обратно в главное меню
    [[CCDirector sharedDirector] popScene];
}


popScene убирает текущий слой. Будьте осторожны под этим слоем должен быть любой другой, как писалось выше, мы именно накладываем слой, в противном случае выдаст ошибку.

Далее создаем слой Game:

image

image

image

Создаем задний фон и ставим задержку перед созданием другого спрайта в файле Game.m:

-(id) init
{
	if( (self=[super init])) {
        
                CGSize size = [[CCDirector sharedDirector] winSize];
		
		//Создаем background
                CCSprite * background = [CCSprite spriteWithFile:@"clean bg.png"];
        
                //anchorPoint это точка от которой происходят манипуляции со спрайтом, по умолчанию
                //background.anchorPoint = ccp(0.5f,0.5f); все манипуляции происходят в середине спрайта
                //в нашем случае я поставил anchorPoint = ccp(1, 1); все манипуляции начинаются с правого 
                // верхнего угла, при (0, 0) левый нижний угол
                background.anchorPoint = ccp(1, 1);
        
                background.position = ccp(size.width, size.height);
                [self addChild:background z:-1];
        
                //Создадим спрайт после задержки в 0,5 секунды
                [self performSelector:@selector(sozdanie_CCSprite) withObject:self afterDelay:0.5];
	}
	return self;
}


здесь я применил anchorPoint, далее увидим его реальное применение:

-(void)sozdanie_CCSprite
{
            //Впринцепе так же делается как и background
            CCSprite * tarakan = [CCSprite spriteWithFile:@"tarakan0.png"];
            tarakan.position = ccp(512, 100);
            tarakan.anchorPoint = ccp(0,0);    
            [self addChild:tarakan];
    
            //Actions
            //Отвечает за смещение на определеное количество пикселей за определеный промежуток времени
            id move = [CCMoveBy actionWithDuration:2 position:ccp(0, 500)];
            //Отвечает за ускорение и замедление
            id accel = [CCEaseInOut actionWithAction:move rate:5];
            //Действие вращения
            id rotate = [CCRotateBy actionWithDuration:2.0f angle:360];
            //Запускаем движение
            [tarakan runAction:[CCSequence actions:accel, rotate, nil]];
    
            //Запустим анимацию
            [self performSelector:@selector(animation) withObject:self afterDelay:3.5];
    
}


здесь мы применяем разные действия над тараканом. Когда скомпилируем и увидем, что таракан двигается с ускорением, а потом вращается, при этом точка вращения левый нижний угол, это и есть тот anchorPoint которому мы указали (0, 0). Мы указали движение таракана, за перемещение отвечает CCMoveBy, за плавность ускорения и замедления во время перемещения отвечает CCEaseInOut, за вращение CCRotateBy. Так же мы тут видим применение CCSequence, эта команда применяется для того, что бы действия над спрайтом шли по очереди.

И последнее, создаем анимацию после задержки:

-(void)animation {
            CGSize size = [[CCDirector sharedDirector] winSize];
    
            //Указываем plist с кадрами и картинку с текстурами 
            [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"tarakan.plist"
                    textureFile:@"tarakan.png"];
            //CCSpriteBatchNode это особый класс в cocos2d, который может выступать в качестве родителя 
            //к целому ряду спрайтов
            //Его используют для экономии памяти в проекте
            CCSpriteBatchNode * bowSheet = [CCSpriteBatchNode batchNodeWithFile:@"tarakan.png"];
    
            NSString *topbird = @"tarakan";
            NSMutableArray *walkAnimFrames = [NSMutableArray array];
            //Прогоняем кадры в цикле
            for(int i = 1; i <= 4; ++i) {
                        CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] 
                                   spriteFrameByName: topbird stringByAppendingString:[
                                   NSString stringWithFormat:@"%d.png", i]]];
                        [walkAnimFrames addObject:frame];
            }
            //Создаем анимацию в которой кадры меняются за определеный промежуток времени
            CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];        
    
            NSString *bowFrame = [topbird stringByAppendingString:@"1.png"];
            //Создаем спрайт с первым кадром
            CCSprite * bow = [CCSprite spriteWithSpriteFrameName:bowFrame];
            bow.position = ccp(size.width/2 , -100);
            [bowSheet addChild:bow];
    
            //CCAnimate присваевает имена спрайтов CCAnimation 
            //Создаем действие из анимации и выделяем память под CCAnimate
            CCAnimate * bowAnim = [[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:YES] 
                      retain];
            [self addChild:bowSheet];
    
            //Создаем повторяемое действие
            id walkAction = [CCRepeat actionWithAction:bowAnim times:5]; 
            //Создаем движение
            id da = [CCMoveBy actionWithDuration:2 position:ccp(0, 600)];
            //Применяем одновремено все действия спрайту
            [bow runAction:[CCSpawn actions:da, walkAction, nil]];    
}


большую часть я прокомментировал, добавлю что текстуру я создавал с помощью zwoptexapp.com, это бесплатно, там я получил plist и png файлы, перетащил их в проект. Так выглядит tarakan.plist файл:

image

а так tarakan.png файл:

image

Так же видно, при применении действия вместо CCSequence, применили CCSpawn, эта команда применяется для того, что бы действия над спрайтом шли одновременно.

Часто вижу на форумах проблемы с созданием анимации на cocos2d, поэтому включил её в эту статью. Надеюсь эта статья будет кому-то полезна.

Проект можно скачать здесь.
Tags:
Hubs:
+25
Comments9

Articles