본문 바로가기

프로그래밍/cocos2d

CCDirector와 CCMenu로 게임 일시정지/플레이 구현하기


게임에서 일시정지와 이어서 하기를 구현하는 방법을 학습합니다.

작업할 파일은 다음과 같습니다.
(1) GameLayer.h
(2) GameLayer.m

 



//

//  GameLayer.h

//  GameDemo

//

//  Created by cmpak on 5/10/10.

//  Copyright 2010 thefirstgood.com. All rights reserved.

//


#import "cocos2d.h"


// 적이 쓰러질 방향

typedef enum {

    kFallRight,

    kFallLeft

}FallDirection;


// 현재 게임 진행 상황

typedef enum {

    kGamePlaying,

    kGamePaused

}GameStatus;


@class EnergyBar;


@interface GameLayer : CCLayer {

    CGSize winSize;

    

    // 방향 전환에 쓰일 버튼

    // 눌리기 전과 눌렸을 때에 있도록 방향별로 두개씩 만든다.

    CCSprite  *rightSprite;

    CCSprite  *rightPressedSprite;

    CCSprite  *leftSprite;

    CCSprite  *leftPressedSprite;

// 발차기 버튼

    CCSprite  *kickSprite;

    CCSprite  *kickPressedSprite;

    

    BOOL isLeftPressed;

    BOOL isRightPressed;

    

    // 주인공 캐릭터 - 여자 이미지를 사용하지만 prince라고 부르겠습니다.

    CCSprite *princeSprite;

    

    // 주인공 캐릭터의 걷기 애니메이션

    CCAnimate *princeWalkAnimate;

// 주인공 발차기 애니메이션

    CCAnimate *princeKickAnimate;

// 발차기 애니메이션이 진행 중인지 검사하는데 사용합니다.

    BOOL isAnimating;

    

    // 주인공 에너지 변수와

    NSInteger energyValue;

    EnergyBar *princeEnergyBar;

    

    // 캐릭터

    CCSpriteSheet *enemySpriteSheet;

    

    // 캐릭터 애니메이션

    CCAnimation   *enemyWalkAnimation;

    CCAnimation   *enemyAttackAnimation;

    

    // 점수와 라이프 값을 담을 변수와 화면에 표시할 레이블

    NSInteger scoreValue;

    NSInteger lifeValue;

    

    CCBitmapFontAtlas *scoreLabel;

    CCBitmapFontAtlas *lifeLabel;

// 게임을 일시정지/플레이하기 위해 상용되는 메뉴아이템(버튼)

    CCMenuItem *pauseMenuItem;

    CCMenuItem *playMenuItem;

    

    // 게임이 일시정지 또는 플레이 중인지 나타냄

    GameStatus gameStatus;

}


@property (nonatomic, retain) CCSprite  *rightSprite;

@property (nonatomic, retain) CCSprite  *rightPressedSprite;

@property (nonatomic, retain) CCSprite  *leftSprite;

@property (nonatomic, retain) CCSprite  *leftPressedSprite;

@property (nonatomic, retain) CCSprite  *kickSprite;

@property (nonatomic, retain) CCSprite  *kickPressedSprite;

@property (nonatomic, retain) CCSprite  *princeSprite;

@property (nonatomic, retain) CCAnimate *princeWalkAnimate;

@property (nonatomic, retain) CCAnimate *princeKickAnimate;

@property (nonatomic, retain) EnergyBar *princeEnergyBar;


@property (nonatomic, retain) CCSpriteSheet *enemySpriteSheet;

@property (nonatomic, retain) CCAnimation   *enemyWalkAnimation;

@property (nonatomic, retain) CCAnimation   *enemyAttackAnimation;


@property (nonatomic, retain) CCBitmapFontAtlas *scoreLabel;

@property (nonatomic, retain) CCBitmapFontAtlas *lifeLabel;


- (void) createBackgroundParallax;

- (void) createLabels;

- (void) createArrowButtons;

- (void) createPrinceAndAnimation;

- (void) createEnemyAndAnimation;

- (void) createEnergyBar;

- (void) createGamePauseResumeMenu;


- (void) moveBackground;


- (void) startPrinceWalking;

- (void) stopPrinceWalking;


- (void) displayScore;

- (void) displayLife;


- (void) princeAttacked:(FallDirection)fallDirection;


- (void) handleKickHit:(CGPoint)effectPoint enemySprite:(CCSprite*)enemy directionToFall:(FallDirection)fallDirection;


- (void) animateScoreSprite:(CGPoint)position;


@end


(1) 새로운 enum 타입으로 GameStatus를 정의했습니다.
(2) 정지/플레이 버튼을 만들기 위해 CCMenuItem 변수를 정의했습니다.
(3) 버튼을 만들어줄 함수를 정의했습니다.






//

//  GameLayer.m

//  GameDemo

//

//  Created by cmpak on 5/10/10.

//  Copyright 2010 thefirstgood.com. All rights reserved.

//


enum {

    kTag_Parallax,

    kTag_Prince,

    kTag_Enemy,

    kTag_Effect,

    kTag_Label,

    kTag_ControlButtonPressed,

    kTag_ControlButton,

kTag_PauseResumeMenu

};


- (id) init {

    if( (self=[super init]) ) {

        // CCLayer 터치이벤트를 처리할 있도록 활성화시킵니다.

        self.isTouchEnabled = YES;

        

        // 화면의 픽셀 크기를 구합니다.

        winSize = [[CCDirector sharedDirector] winSize];

        

        // 초기값 설정

        gameStatus = kGamePlaying;

        scoreValue = 0;

        //lifeValue = 3;

        lifeValue = INIT_NUM_LIFE;

        energyValue = INIT_NUM_ENERGY;

        

        [self createBackgroundParallax];

        [self createLabels];

        [self createPrinceAndAnimation];

        [self createEnemyAndAnimation];

        [self createArrowButtons];

        [self createEnergyBar];

[self createGamePauseResumeMenu];

    }

    

    return self;

}


- (void) createGamePauseResumeMenu {

    pauseMenuItem = [CCMenuItemImage itemFromNormalImage:@"btn_pause.png"

selectedImage:@"btn_pause_s.png"

target:self

selector:@selector(playPauseMenuCallback:)];

    playMenuItem  = [CCMenuItemImage itemFromNormalImage:@"btn_play.png"

selectedImage:@"btn_play_s.png"

target:self

selector:@selector(playPauseMenuCallback:)];

    

    CCMenu *menu = [CCMenu menuWithItems: pauseMenuItem, playMenuItem, nil];   

    menu.position = ccp(0, 0);

    

    pauseMenuItem.position = ccp(winSize.width - pauseMenuItem.contentSize.width / 2 -5 ,

                                 winSize.height - pauseMenuItem.contentSize.height / 2 - 5 );

    

    // 플레이 메뉴아이템이 일시정지 메뉴아이템 위에 표시됨.  CCMenu 추가될 z order 하나씩 늘어남.

    playMenuItem.position = pauseMenuItem.position;

    

    // 처음에는 게임이 플레이 모드이므로 플레이 메뉴아이템을 보이지않도록 합니다.

    playMenuItem.visible = NO;

    

    [self addChild:menu z:kTag_PauseResumeMenu tag:kTag_PauseResumeMenu];

}


#pragma mark Menu Handlers

- (void) playPauseMenuCallback:(id)sender {

    // 플레이 메뉴아이템이 보이지않는 상태이면, 게임을 일시정지 시킵니다.

    if(playMenuItem.visible == NO) {

        gameStatus = kGamePaused;

        

        // 모든 애니메이션을 일시정지 시킵니다.

        // pause 시켜도 계속해서 터치이벤트를 받습니다.

        [[CCDirector sharedDirector] pause];

        

        // 플레이 메뉴아이템을 보여줍니다.

        playMenuItem.visible = YES;

    }else {

        gameStatus = kGamePlaying;

        

        playMenuItem.visible = NO;

        

        // 모든 애니메이션을 다시 작동시킵니다.

        [[CCDirector sharedDirector] resume];

    }

}



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

// pause 시켜도 계속해서 터치이벤트를 받기때문에, 방향버튼과 공격버튼의

    // 터치이벤트를 처리하면 안됩니다. 이를 방지하기 위하여 GameStatus 값을

    // 사용합니다.

    if(gameStatus == kGamePaused || isAnimating == YES) {

        NSLog(@"Touch Began ignored");

        return;

    }


}


// 손가락을 떼는 순간 호출됩니다.

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

if(gameStatus == kGamePaused

        return;


}


// 손가락을 움직일 계속해서 호출됩니다.

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

if(gameStatus == kGamePaused

        return;


}


(1) 이미지를 이용하여 CCMenuItem을 만듭니다. 일시정지와 플레이용 두 개를 만듭니다. 버튼이 눌리면 playPauseMenuCallback 메서드를 호출합니다.
(2) 버튼이 보이는지 그렇지 않은지 visible 값으로 현재의 게임 상황을 판단합니다.