본문 바로가기

IT

물고기 게임2

반응형

1. 게임 메뉴 만들기

cocos2d 는 화면에 표시되는 이미지 객체들을 레이어로 관리한다.
그래서 처음 add 된 객체가 맨 밑에 깔린다.

소스를 보면서 설명해보자.

[타이틀 메뉴 구현 소스 : GrowFish.h]

// cocos2d 를 하기 위해 import 한다.
#import "cocos2d.h"


// 메뉴를 보여주기 위한 레이어를 만든다.
@interface TitleMenu : Layer { 

}
-(void) playCallback:(id) sender; // 플레이 메뉴를 선택했을 때 콜백
-(void) helpCallback:(id) sender; // help 메뉴를 선택했을 때 콜백
@end


[타이틀 메뉴 구현 소스 : GrowFish.m]

#import "GrowFish.h"


// 메인에서 선택하는 scene 클래스 명이 정리되었다.
static NSString *transitions[] = {
    @"TitleMenu",
    @"PlayGame",
};

// 플레이 메뉴를 선택할 때 해당 scene  을 돌려준다. 
Class playGameAction()
{    
    NSString *r = transitions[1];
    Class c = NSClassFromString(r);
    return c;
}

@implementation TitleMenu
-(id) init
{
    if( (self=[super init] )) {
        // 배경을 sprite 로 등록한다.
        Sprite *bg = [Sprite spriteWithFile:@"titlebg.png"];
        
        // 메뉴로 사용할 image item 을 등록한다.
        MenuItem *play = [MenuItemImage itemFromNormalImage:@"play_up_bt.png" selectedImage:@"play_dw_bt.png" target:self selector:@selector(playCallback:)];
        MenuItem *help = [MenuItemImage itemFromNormalImage:@"help_up_bt.png" selectedImage:@"help_dw_bt.png" target:self selector:@selector(helpCallback:)];
        // MenuItem 을 Menu 레이어에 올린다.
        Menu *menu = [Menu menuWithItems: play, help, nil];
        // 메뉴 간의 세로 간격을 15 픽셀로 한다.
        [menu alignItemsVerticallyWithPadding:15];
        
        // iPhone 의 화면 사이즈를 가져온다.
        CGSize size = [[Director sharedDirector] winSize];
        
        // position 값은 sprite 의 중앙 위치를 가리킨다. iPhone 화면의 중앙에 위치하도록 설정해준다.
        bg.position =  ccp( size.width/2 , size.height/2 );
        // menu 레이어도 화면의 적당한 위치에 올수 있게 조절해준다.
        menu.position = ccp( size.width/2-7 , size.height/4-2 );
        
        // 배경을 add
        [self addChild: bg];
        // menu 를 add
        [self addChild: menu];
    }
    return self;
}

- (void) dealloc
{
    NSLog(@"TitleMenu - dealloc");
    [super dealloc];
}

-(void) playCallback: (id) sender
{
    NSLog(@"play 메뉴 선택");
    // Scene 를 생성한다.
    Scene *s = [Scene node];
    // Scene 에 PlayGame 레이어를 add 한다.
    [s addChild: [playGameAction() node]];
    // 어플의 scene 를 새로 만든 scene 로 교체한다.
    [[Director sharedDirector] replaceScene: s];
    
}

// 콜백만 만들고 미구현 상태
-(void) helpCallback: (id) sender
{
    NSLog(@"help 메뉴 선택");
}

@end

2.  PlayGame 만들기
물고기들이 한쪽 방향만 바라 보고 있어서 어색하지만 
일단 중요한 건 게임 플레이 코드 구현이므로 
기능적인 부분에 중점을 맞추어서 코드를 우선 작성한다.


[PlayGame 구현 소스 : GrowFish.h]

// 주인공 물고기 클래스이다. cocos2d 샘플 중에 적당한 클래스가 있었다.
// 그래서 새로 안 만들고 그냥 import 시킨다.
#import "Paddle.h"
// 적 물고기 클래스이다.
#import "Ball.h"

// scene에 등장하는 적 물고기 수
#define NUM_ENEMYS 10
// 적 물고기의 종류 수
#define NUM_TEXTURE 9

@interface PlayGame : Layer {
    // 윈도우 사이즈 저장
    CGSize size;
    // 주인공 물고기
    Paddle * heroFish;
    // 적 물고기
    NSArray * enemyFishs;
    // 등장 적 물고기
    Texture2D * enemyFishTexture[NUM_TEXTURE];
    
    CGPoint enemyFishStartingVelocity;

}
// interval 메소드
-(void) doStep:(ccTime) dt;
// 등장하는 적 물고기를 준비하는 함수
-(void) setEnemyFishTexture;

@end

[PlayGame 구현 소스 : GrowFish.m]


// 랜덤한 값을 생성하기 위해 새로 정의된 전역 함수
float randfloat() {
    return ((float)random())/RAND_MAX;
}

// 적 물고기들의 이미지 이름을 전역 배열로 선언해 두었다.

static NSString *enemy_names[] = {
    @"fish_e0.png",
    @"fish_e1.png",
    @"fish_e2.png",
    @"fish_e3.png",
    @"fish_e4.png",
    @"fish_e5.png",
    @"fish_e5.png",
    @"fish_e6.png",
    @"fish_e7.png",
    @"fish_e8.png",
};

@implementation PlayGame
-(id) init
{
    if( (self=[super init] )) {
        
        // 터치를 가능하게 한다.        
        self.isTouchEnabled = YES;
        
        // 배경 화면
        Sprite *bg = [Sprite spriteWithFile:@"playbg.png"];    
        // 윈도우 사이즈 구하기
        size = [[Director sharedDirector] winSize];        
        // 중앙 배치
        bg.position =  ccp( size.width/2 , size.height/2 );
        // 배경 add
        [self addChild: bg];
        
        // 주인공 texture 생성
        Texture2D *heroTexture = [[TextureMgr sharedTextureMgr] addImage:@"fish_h.png"];
        heroFish = [Paddle paddleWithTexture:heroTexture];
        // 주인공 위치 설정
        heroFish.position = CGPointMake(size.width/2 , size.height/2);
        // 주인공의 처음 크기 지정
        [heroFish setScale:0.15f];
        
        // 등장하는 적 물고기들을 준비한다.
        [self setEnemyFishTexture];
        
        // 랜덤한 좌표를 생성한다.
        float xV = randfloat()*100;
        float yV = randfloat()*100;
        int t = randfloat()*4;
        if(t>3) xV *=-1;
        else if(t>2) xV *=1;
        else if(t>1) yV *= -1;
        else yV *= 1;
        enemyFishStartingVelocity = CGPointMake(xV, yV);
        
        // scene에 등장하는 물고기들을 생성한다.
        // 클래스명이 Ball 로 되어있는것은 다른 게임의 클래스를 그대로 가져와서 
        // 그런것이므로 당분간 신경쓰지 않는다.
        NSMutableArray *enemyFishM = [NSMutableArray arrayWithCapacity:NUM_ENEMYS];
        
        for(int i=0; i<NUM_ENEMYS; i++){
            int index = randfloat()*(heroFish.level+2);
            int xPoint = randfloat()*size.width;
            int yPoint = randfloat()*size.height;
            
            Ball *enemyFish = [Ball ballWithTexture:enemyFishTexture[index]];
            enemyFish.position = CGPointMake(xPoint, yPoint);
            enemyFish.velocity = enemyFishStartingVelocity;
            [enemyFishM addObject:enemyFish];
        }
        
        enemyFishs = [enemyFishM copy];
        
        // 적 물고기 scene 에 add
        for (Ball *e in enemyFishs)
            [self addChild:e];
        
        // 주인공 물고기 등장    
        [self addChild:heroFish];
        
        // interval 메소드를 지정한다. 
        // 적 물고기의 움직임, hit 체크
        [self schedule:@selector(doStep:)];
    }
    return self;
}

- (void) dealloc
{
    NSLog(@"PlayGame - dealloc");
    [super dealloc];
}

- (void)doStep:(ccTime)delta
{
    // 물고기를 움직이고, 주인공 물고기와 충돌했는지 체크
    for (Ball *e in enemyFishs){
        [e move:delta];
        [e collideWithPaddle:heroFish];
    }
}

- (void)setEnemyFishTexture
{
    // 9마리 물고기를 준비시킨다.
    for(int i=0; i<NUM_TEXTURE; i++){
        enemyFishTexture[i] = [[TextureMgr sharedTextureMgr] addImage:enemy_names[i]];
    }
}
@end

반응형