어데이드 2017. 12. 19. 17:38

게임에서는 bool형 변수를 여러 개 만드는 대신 unsigned형 변수 하나에 여러 플래그를 묶어 넣는 방법을 자주 사용한다.

4바이트=32비트 크기인 unsigned형 변수 하나에는 플래그 변수를 32개 모아 둘 수 있다.

또한 정수 변수에서 미사용한 부분을 플래그로 사용하는 경우도 있다.


플래그 저장

플래그 클래스 예제


class Flag{

bool check(인수 미정) const;

void set(인수 미정);

void reser(인수 미정);

private:

unsigned char mFlags;

};


check 함수로 특정 플래스 상태를 조사하고

set 함수로 특정 플래그를 온으로 하며

reset 함수로 특정 플래그를 오프로 한다.


플래그 추출: 시프트 연산 이용

우선 열거형을 숫자 그대로가 아니라 '2의 몇 승'인지로 정의하자.


enum Flag {

FLAG_WALL = 7,

FLAG_GOAL = 6,

}


나머진 이를 이용하여 다음과 같이 쓸 수 있다.


boolFlag::check(unsigned char f) {

unsigned char t = mFlags;

t >>= f;

t <<= 7;

return (t != 0) ? true : false;

}


플래그 추출: 비트 연산 이용

미리 열거형을 준비하면 함수를 깔끔하게 작성할 수 있다.


enum Flag {

FLAG_WALL = (1 << 7),

FLAG_GOAL = (1 << 6),

}


bool Flag::check(unsigned char f) {

return ((mFlag & f) != 0)

}


플래그 온

void Flag::set(unsigned char f) {

mFlag |= f;

}


플래그 오프

void Flag::reset(unsigned char f) {

mFlags &= ~f;

}


여러 플래그 한꺼번에 조작

함수를 두 번 호출하기 귀찮다면 플래그 열거형 두개를 붙일 수 있다.


Flag.check(FLAG_WALL | FLAG_GOAL);

Flag.set(FLAG_WALL | FLAG_GOAL);

Flag.reset(FLAG_WALL | FLAG_GOAL);


만약 한 번에 플래그 하나만 조작한다는 것을 알고 있다면 다음처럼 할 수 있다.


enum Flag {

FLAG_WALL,

FLAG_GOAL,

}


즉 아무것도 쓰지 않고 0부터 차례로 할당받아 조작하는 함수 내에서 시프트하는 것이다.

전달받은 열거형 변수를 f로 해서 코드로 작성하면 다음과 같다.


return (mFlag & (1 << f) );  //check

mFlags |= (1 << f);            //set

mFlags &= ~(1 << f);        //reset

enum이 깔끔해지고 오타가 날 일도 줄어들으니 이 방식을 권장하지만

플래그를 복수로 조작해야 하는 경우도 꽤 있으므로 고민해야할 부분이다.