iDev/Cocos2D

드래곤 플라이트 따라 만들기 - 5. 총알 추가

KraZYeom 2013. 1. 29. 08:02
반응형

이번 파트에서는 총알을 생성하고 총알과 적의 충돌처리 하는 것을 구현하겠다. 


총알 추가

플레이어 케릭터에서는 특별한 액션이 필요하지 않고 끊임없이 총알이 발사 된다. 레벨에 따라서 총알의 모양, 강도만 다를 뿐이다. 


총알 스프라이트를 구현하기 위해서 Bullet 스프라이트를 CCSprite를 상속받아서 생성한다. 그리고 Bullet.h 이동한다. 아래 코드를 추가한다. 


//총알의 종류와 강도

typedef enum {

    //총알의 강도를 나타낸다.

    kFirst = 20

} BulletType;


@interface Bullet : CCSprite {

}


@property (nonatomic, readwrite) BulletType bulletType;

총알의 종류와 강도를 나타내는 변수와  총알 타입을 설정 할 수 있는 프로퍼티도 설정한다. 


Bullet.m 으로 이동해서 init 메소드를 아래와 같이 작성한다. 

- (id)init

{

    // 번째 총알 이미지

    self = [super initWithSpriteFrameName:@"bullet_01_01.png"];

    if (self) {

    //총알 타입을 정한다.

        _bulletType = kFirst;

    }

    return self;

}

스프라이트에 이미지를 넣고 총알 강도를 나타내는 타입을 지정한다. 이번 따라하기 시리즈에서는 레벨이 개념이 없으므로 그냥 한 개의 타입 밖에 없다. 


총알이 앞으로 나아가게 하기 위해 - (void)updateBullet:(ccTime)dt 메소드를 추가하고 아래 코드를 추가한다.  

- (void)updateBullet:(ccTime)dt {

    CGSize winSize = [[CCDirector sharedDirector] winSize];

    //총알의 움직임 가속도

    CGPoint bulletVel = ccp(0, 300);

    //총알의 현재위치

    CGPoint currentPostion = self.position;

    //화면 밖으로 넘어가면 총알을 숨긴다.

    if (currentPostion.y > winSize.height){

        self.visible = NO;

    } else{

        //아니면 계속해서 앞으로 보낸다.

        self.position = ccpAdd(ccpMult(bulletVel, dt), self.position);

    }

}

이전 적, 배경과 처럼, 총알의 속도를 정하고 현재 위치를 확인해서 화면 밖으로 넘어가면 숨김 처리한다. 아니면 계속해서 앞으로 나아가게 한다. 


updateBullet: 메소드를 호출을 위해서 onEnter 메소드에 아래 코드를 추가한다.

-(void)onEnter{

    [super onEnter];

    //스케쥴로 호출

    [self schedule:@selector(updateBullet:) interval:0.05];

}

0.05초 마다 updateBullet: 메소드를 호출한다.


기본적인 총알 스프라이트 구성은 완성되었다. GameLayer에 추가하여서 화면에 보이도록 하자.


GameLayer.h 화일로 이동해서 아래 코드를 추가한다. 

    //총알을 담을 배열

    CCArray *bulletsArray;

    //마지막 총알 확인용

    int lastBullet;


@property (nonatomic, weak) CCSpriteBatchNode *batchNode;


총알을 재사용하기 위해 배열을 사용하고 마지막으로 사용된 총알확인을 위한 변수를 하나 추가한다. 그리고 총알의 이미지 하나를 사용해서 여러개의 총알을 생성하기 위해서 배치노드를 사용한다. 배치노드 사용 성능에 관해서는 CCSpriteBatchNode 성능 테스트를 참조하도록 한다. 


GameLayer.h이동해서 상단에 총알 클래스를 임포트하는 코드를 아래와 같이 추가한다.

#import "Bullet.h"


init 메소드로 이동해서 아래 코드를 스프라이트 캐쉬위에 추가한다. 

//마지막 총알 번호를 위해 초기화

lastBullet = 0;


//총알등을 위해 배치노드 사용

_batchNode = [CCSpriteBatchNode batchNodeWithFile:@"dragonRideSprite.pvr.ccz"];

[self addChild:_batchNode];


//스프라이트 프레임 케쉬에 스프라이트를 저장한다.

[[CCSpriteFrameCache sharedSpriteFrameCacheaddSpriteFramesWithFile:@"dragonRideSprite.plist"];

마지막 총알 위치를 초기화하고 배치노드를 추가한다. 


총알을 생성하기 위해서 initBullet메소드를 생성하고 아래 코드를 추가한다.

#define kMaxBullet 30


-(void)initBullet {

    //총알 갯수만큼 배열을 만든다.

    bulletsArray = [[CCArray alloc] initWithCapacity:kMaxBullet];

    //총알 갯수만큼 배열에 넣는다.

    for (int i = 0; i < kMaxBullet; i++) {

        //총알 노드를 생성

        Bullet *bullet = [Bullet node];

        //처음에는 보이는 상태로 만든다.

        bullet.visible = NO;

        //총알의 위치는 플레이어 케릭터의 앞에 위치.

        bullet.position = ccp(_player.position.x, _player.position.y + _player.boundingBox.size.height / 2);

        //배치노드에 넣는다.

        [_batchNode addChild:bullet z:99];

        //충돌등 계산을 쉽게 하기 위해 배열에 넣는다

        [bulletsArray addObject:bullet];

    }

}

총알의 갯수는 30개로 하며 배력에 넣고 재사용한다. 이때 GameLayer에 바로 추가하는게 아니라 방금전에 생성했던 배치노드에 추가한다. 그렇게 되면 하나의 동일한 이미지로 효율성 있게 재사용하게 된다. 


init 메소드로 이동해서 아래 코드를 추가한다. 

        //총알 초기화

        [self initBullet];


기본적인 생성은 끝났으니 사용해보도록 구현하겠다. 


-(void)updateBullet:(ccTime)dt메소드를 생성하고 아래 코드를 추가한다. 

-(void)updateBullet:(ccTime)dt {

    //배열에서 하나씩 총알을 꺼낸다.

    Bullet *bullet = (Bullet*)[bulletsArray objectAtIndex:lastBullet];

    //움직일때는 보이게 설정

    bullet.visible = YES;

    //총알의 위치는 플레이어 케릭터의 앞에 위치.

    bullet.position = ccp(_player.position.x, _player.position.y + _player.boundingBox.size.height / 2);

    //마지막 총알이 배열의 마지막이면 다시 초기화 한다.

    if (++lastBullet == kMaxBullet) {

        lastBullet = 0;

    } 

}

배열에서 마지막으로 사용했던 총알위치에서 총알을 꺼내고 보이게 설정한다. 총알의 위치는 플레이어 케릭터의 위이다. 


onEnter메소드에 위에 생성했던 메소드를 스케쥴러를 통해서 호출하기 위해서 아래 코드를 추가한다. 

    [self schedule:@selector(updateBullet:) interval:0.05f];


Cmd(⌘) + R을 해서 Run을 해보자. 그러면 총알이 플레이어 케릭터에서 마구 나가는 모습을 확인 할 수 있다. 





반응형