Sweet Snippet 之 BitMask

63 篇文章 1 订阅

本文简述了 BitMask 的(一种)使用场景和实现方法

游戏开发中往往会遇到不同游戏逻辑触发相同游戏操作的情况,举个简单的例子:在播放游戏过场动画时,我们往往需要隐藏游戏UI;而当我们进行游戏截屏时,往往也需要隐藏游戏UI.

假设显示/隐藏游戏UI的接口如下:

void SetUIActive(bool active);

按照上面所说的功能需求(过场动画和游戏截屏都需要隐藏游戏UI),我们可能会写下如下的代码:

void OnEnterCutscene()
{
    SetUIActive(false);
}

void OnLeaveCutscene()
{
    SetUIActive(true);
}

void OnEnterCapture()
{
    SetUIActive(false);
}

void OnLeaveCapture()
{
    SetUIActive(true);
}

至此我们实现了在过场动画和游戏截屏时隐藏游戏UI,一切表现都很正常,直到我们支持了在过场动画中进行游戏截屏…:

考虑在过场动画中进行游戏截屏的逻辑过程:

  • 首先我们进入过场动画(OnEnterCutscene),隐藏了游戏UI
  • 接着我们进入游戏截屏(OnEnterCapture),又隐藏了一次游戏UI
  • 接着我们退出游戏截屏(OnLeaveCapture),显示了游戏UI(Ops,过场动画还没结束就显示了游戏UI…)
  • 最后我们退出过场动画(OnLeaveCutscene),又显示了一次游戏UI

上面所述的第三步中产生了问题(过场动画还没结束就显示了游戏UI),本质原因是因为过场动画和游戏截屏进行了相同的逻辑操作,于是他们在非顺序执行时便产生了操作冲突.

解决该问题的一种方法就是使用 BitMask,即通过位掩码来"分离"相同的游戏操作,说的有些抽象,我们直接看源码便明白了~

首先是 BitMask 的实现:

using UnityEngine;

public class BitMask
{
    private int m_num;

    public BitMask(bool state = true)
    {
        m_num = state ? -1 : 0;
    }

    public bool Get(int maskIndex)
    {
        Debug.Assert(maskIndex >= 0 && maskIndex < 32, "[BitMask]BitMask only support mask index from 0 to 31, current mask index : " + maskIndex);
        return (m_num & (1 << maskIndex)) != 0;
    }

    public void Set(int maskIndex, bool maskValue)
    {
        Debug.Assert(maskIndex >= 0 && maskIndex < 32, "[BitMask]BitMask only support mask index from 0 to 31, current mask index : " + maskIndex);
        if (maskValue)
        {
            m_num = m_num | (1 << maskIndex);
        }
        else
        {
            m_num = m_num & ~(1 << maskIndex);
        }
    }

    public bool GetAll()
    {
        return AllBitsTrue();
    }

    public void SetAll(bool state)
    {
        m_num = state ? -1 : 0;
    }

    public bool AllBitsTrue()
    {
        return (~m_num) == 0;
    }

    public bool AnyBitTrue()
    {
        return m_num != 0;
    }

    public bool AllBitsFalse()
    {
        return m_num == 0;
    }

    public bool AnyBitFalse()
    {
        return (~m_num) != 0;
    }
}

使用上面的 BitMask,我们重新实现下之前的功能需求(过场动画和游戏截屏都需要隐藏游戏UI):

enum UIActiveMask 
{
    Cutscene = 0,
    Capture,
}

BitMask mask = new BitMask(true);

void OnEnterCutscene()
{
    mask.Set(UIActiveMask.Cutscene, false);
    SetUIActive(mask.GetAll());
}

void OnLeaveCutscene()
{
    mask.Set(UIActiveMask.Cutscene, true);
    SetUIActive(mask.GetAll());
}

void OnEnterCapture()
{
    mask.Set(UIActiveMask.Capture, false);
    SetUIActive(mask.GetAll());
}

void OnLeaveCapture()
{
    mask.Set(UIActiveMask.Capture, true);
    SetUIActive(mask.GetAll());
}

至此我们便通过 BitMask 解决了之前在过场动画中进行游戏截屏时出现的问题(过场动画还没结束就显示了游戏UI).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值