Skip to content
isdnetworks
Go back

상태를 바꾸면 값 두 개가 같이 움직였다

장비를 바꾸면 공격력이 안 맞을 때가 있었다.

Table of contents

Open Table of contents

두 값을 따로 고치고 있었다

장비를 끼는 함수는 장비와 공격력을 같이 고쳤다.

void Player::equip(const Item& item) {
    m_equipped = item;
    m_attack = m_baseAttack + item.attack;
}

한 함수 안에 있으니 괜찮아 보였는데 벗는 쪽은 달랐다. 장비만 비우고 공격력을 안 고쳤다. 두 값이 함께 움직여야 하는데 함께 바꾸는 자리가 한 곳뿐이었다.

계산해서 쓰게 바꿨다

값을 둘 두는 대신 필요할 때 계산하게 했다.

int Player::getAttack() const {
    return m_baseAttack + m_equipped.attack;
}

m_attack 이라는 저장 값을 아예 없애니 고칠 자리가 하나로 줄었다. 계산이 무거우면 이렇게 못 하지만 더하기 하나라 상관없었다.

바꾸는 자리를 하나로 모았다

계산이 무거운 것도 있었다. 그건 표시만 켜 두고 나중에 계산하게 했다. 문제는 표시를 켜는 것을 빠뜨리면 옛 값이 나온다는 점이다.

void Player::setEquipped(const Item& item) {
    m_equipped = item;
    m_statDirty = true;
}

값을 바꾸는 자리를 이 함수 하나로 모았다. 밖에서 못 건드리게 CC_PROPERTY_READONLY 로 바꿔 setter 를 없애고, 안에서 직접 대입하던 자리는 grep 으로 찾아 전부 고쳤다. 대입이 이 함수 안에만 남은 것을 확인하고 끝냈다.

같이 움직이는 것을 전부 찾아보니 더 있었다. 레벨과 최대 체력, 버프와 속도가 같은 모양이었다. 대부분 계산해서 쓰는 쪽으로 바꿨는데 체력만 따로 다뤘다. 최대치가 줄면 현재 값도 줄여야 하기 때문이다.

반대 방향의 확인

이 버그는 벗을 때만 났다. 끼는 것만 확인하고 넘어갔기 때문이다.

끼기와 벗기와 바꿔 끼기 셋 중 확인한 것이 하나였다. 바꿔 끼기는 벗기와 끼기가 연달아 일어난다. 그 순서에서 또 다른 것이 날 수 있었다. 한쪽 방향만 확인하면 반대 방향에서 난다.

화면이 옛 값을 그리는 것도 같이 봤다. 값이 맞아도 화면이 안 바뀌면 사용자에게는 같다. scheduleUpdate() 를 걸어 update() 에서 매 프레임 읽어 갔다. 달라졌을 때만 CCLabelTTFsetString() 을 부르게 뒀다. 알려 주는 방식으로 하면 알려 주는 자리를 또 빠뜨린다.

정리


Share this post on:

Previous Post
업데이트하니 저장이 깨졌다
Next Post
하나를 눌렀는데 여러 곳이 바뀌었다