[세가] 팁:플래그
게임에서는 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이 깔끔해지고 오타가 날 일도 줄어들으니 이 방식을 권장하지만
플래그를 복수로 조작해야 하는 경우도 꽤 있으므로 고민해야할 부분이다.