작업 할 파일은 다음과 같습니다.
(1) EnergyBar.h
(2) EnergyBar.m
(3) GameLayer.h
(4) GameLayer.m
//
// EnergyBar.h
// GameDemo
//
// Created by Chang-Min Pak on 6/12/10.
// Copyright 2010 thefirstgood.com. All rights reserved.
//
//#import <Foundation/Foundation.h>
#import "cocos2d.h"
//@interface EnergyBar : NSObject {
@interface EnergyBar : CCNode {
CGFloat maxValue;
CGFloat curValue;
CGSize maxSize; // 에너지 바의 픽셀 크기
}
- (id) initWithMaxSize:(CGSize)size maxValue:(CGFloat)maxVal;
- (void) updateBar:(CGFloat)curValue;
@end
(1) cocos2d의 가장 기본 클래스인 CCNode를 상속받는 EnergyBar 클래스를 정의합니다.
//
// EnergyBar.m
// GameDemo
//
// Created by Chang-Min Pak on 6/12/10.
// Copyright 2010 thefirstgood.com. All rights reserved.
//
#import "EnergyBar.h"
@implementation EnergyBar
- (id) initWithMaxSize:(CGSize)size maxValue:(CGFloat)maxVal {
if( (self=[super init]) ) {
// anchorPoint를 왼쪽 아래로 잡습니다.
self.anchorPoint = CGPointZero;
// 에너지 바의 이미지 크기
maxSize = size;
// 전체 에너지 바에 몇개의 에너지가 있는지 설정
maxValue = maxVal;
curValue = maxValue;
}
return self;
}
- (void) draw {
// 그려야할 길이를 픽셀값으로 계산합니다.
CGFloat width = maxSize.width * curValue / maxValue;
// 선의 두께를 설정합니다.
glLineWidth(maxSize.height);
// 색을 설정합니다: RGB Alpha
// 전체 에너지 값의 40%이내로 떨어지면 빨간색으로 표시합니다.
glColor4ub(57, 248, 11, 255);
if(curValue / maxValue <= 0.4)
glColor4ub(217, 79, 62, 255);
ccDrawLine( ccp(0, 0), ccp(width, 0) );
}
- (void) updateBar:(CGFloat)curVal {
curValue = curVal;
if(curValue < 0)
curValue = 0;
else if(curValue > maxValue)
curValue = maxValue;
[self draw];
}
@end
(1) glLineWidth와 glColor4ub는 OpenGL ES에서 제공하는 API입니다. glLineWidth 메서드로 선의 두께를 지정합니다.
glColor4ub 메서드를 사용하여 RGB와 알파 값으로 선의 색을 설정한 후 ccDrawLine 메서드로 시작점과 끝점을 지정하여 선을 그립니다.
//
// 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;
@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;
}
@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) 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
//
// GameLayer.m
// GameDemo
//
// Created by cmpak on 5/10/10.
// Copyright 2010 thefirstgood.com. All rights reserved.
//
#import "EnergyBar.h"
#define INIT_NUM_LIFE 3
#define INIT_NUM_ENERGY 10@synthesize princeEnergyBar;
- (id) init {
if( (self=[super init]) ) {
// CCLayer가 터치이벤트를 처리할 수 있도록 활성화시킵니다.
self.isTouchEnabled = YES;
// 화면의 픽셀 크기를 구합니다.
winSize = [[CCDirector sharedDirector] winSize];
// 초기값 설정
scoreValue = 0;
//lifeValue = 3;
lifeValue = INIT_NUM_LIFE;
energyValue = INIT_NUM_ENERGY;
[self createBackgroundParallax];
[self createLabels];
[self createPrinceAndAnimation];
[self createEnemyAndAnimation];
[self createArrowButtons];
[self createEnergyBar];
}
return self;
}
- (void) createEnergyBar {
// 에너지 바의 가로*세로 크기를 정하고, 최고 에너지 값을 정해줍니다.
EnergyBar *bar = [[EnergyBar alloc] initWithMaxSize:CGSizeMake(120, 10) maxValue:INIT_NUM_ENERGY];
self.princeEnergyBar = bar;
self.princeEnergyBar.position = ccp(winSize.width / 2 + 75, winSize.height - 22);
[self addChild:self.princeEnergyBar z:kTag_Label];
[bar release];
}
- (void) princeAttacked:(FallDirection)fallDirection {
// 에너지를 감소시킵니다.
energyValue--;
if(energyValue <= 0) {
// 라이프를 감소시킨다.
lifeValue--;
if(lifeValue <= 0) {
NSLog(@"GAME OVER");
// 임시로 다시 원래값으로 리셋합니다.
lifeValue = INIT_NUM_LIFE;
}
[self displayLife];
// 에너지를 재충전 시킨다.
energyValue = INIT_NUM_ENERGY;
}
// 에너지 바를 업데이트 한다.
[self.princeEnergyBar updateBar:energyValue];
// 좌우로 60픽셀만큼 밀려나게 합니다.
CGFloat xDiff = 60.0;
if(fallDirection == kFallLeft)
xDiff *= -1.0;
// x좌표의 값이 화면 바깥으로 나가지않도록 합니다.
CGFloat xPos = self.princeSprite.position.x + xDiff;
if(xPos < 0)
xPos = 0;
else if(xPos > winSize.width)
xPos = winSize.width;
CGPoint targetPoint = CGPointMake(xPos, self.princeSprite.position.y);
CGFloat duration = 0.5;
// 빨간색으로 변화시킵니다.
id tint = [CCTintBy actionWithDuration:duration/2.0 red:0 green:-255 blue:-255];
// CCEaseExponentialOut을 사용하여 속도감이 있도록 합니다.
id move = [CCEaseExponentialOut actionWithAction:[CCMoveTo actionWithDuration:duration position:targetPoint]];
id spawn = [CCSpawn actions:tint, move, nil];
[self.princeSprite runAction:[CCSequence actions:
spawn,
[CCCallFunc actionWithTarget:self selector:@selector(princeAttackedCompleteHandler)],
nil]];
}