Java双缓冲机制游戏开发,游戏中的双缓冲模式试验

我们假设一个游戏,舞台上有三个演员(A,B,C),每个演员有一个自己面对的演员且成一个环(A面对B,B面对C,C面对A)。我们可以扇一个演员的耳光,这个演员不管谁扇的他,他都会去扇他面对的演员(所以我们只要任意扇一个人,他们就会一直成环的扇下去)。

首先写好演员的类:

public class Actor

{

private string m_sName; //名字

private bool m_bIsSlapped; //是否被扇

private Actor m_facedActor; //面对的演员

public string Name

{

set { m_sName = value; }

get { return m_sName; }

}

public Actor(string name)

{

m_sName = name;

Reset(); //构造时设为未被扇

}

public void Face(Actor actor) //设置面对演员

{

m_facedActor = actor;

}

public void Reset() //重置状态

{

m_bIsSlapped = false;

}

public void Slap() //被扇

{

m_bIsSlapped = true;

}

public bool WasSlapped() //是否被扇

{

return m_bIsSlapped;

}

public void CheckStatus() //检查状态,并作出输出

{

if (WasSlapped())

{

Reset();

Debug.Log(Name + " was slapped, so " + Name + " slapped " + m_facedActor.Name);

m_facedActor.Slap();

}

else

{

Debug.Log(Name + " was not slapped, so nothing happens");

}

}

}

然后是主类:

public class DoubleBufferMain : MonoBehaviour

{

private Actor[] actors = new Actor[3];

void Start()

{

Actor april = new Actor("April");

Actor bella = new Actor("Bella");

Actor charlie = new Actor("Charlie");

april.Face(bella);

bella.Face(charlie);

charlie.Face(april);

actors[0] = april;

actors[1] = bella;

actors[2] = charlie;

april.Slap(); //扇A

CheckStatus();

}

private void CheckStatus()

{

for(int i = 0; i < actors.Length; i ++)

{

actors[i].CheckStatus();

}

Invoke("CheckStatus", 1); //每一秒检测一下状态

}

}

在这种情况下每个演员都会在自己被扇的同一帧扇下一个演员,他们会无限的互相伤害下去。

d26b44781649e18d63498f9bae0351aa.png

但是,如果我们换一下他们在主类里actors里的顺序,会发现输出的结果会发生错误,有的演员会再被扇的同一帧做出反应,有的演员会再被扇的下一帧做出反馈。

da4063814a985268bb57095c4d6f6b89.png

f6549f9db98b067d37d19af50740be87.png

只因为我们改变了顺序,两次输出的结果就不一样了(第一次每帧都是3人扇人,第二次每帧有1个或者2个人扇人),显然我们的结果我应该因为仅仅因为我们改变了数组中演员的顺序就发生了改变,所以需要引入双缓冲的模式。修改后的Actor类和主类:

public class Actor

{

private string m_sName; //名字

private bool m_bIsCurrentSlapped; //当前是否被扇

private bool m_bIsNextSlapped; //next是否被扇

private Actor m_facedActor; //面对的演员

public string Name

{

set { m_sName = value; }

get { return m_sName; }

}

public Actor(string name)

{

m_sName = name;

m_bIsCurrentSlapped = false;

m_bIsNextSlapped = false;

}

public void Face(Actor actor) //设置面对演员

{

m_facedActor = actor;

}

public void Slap() //被扇

{

m_bIsNextSlapped = true;

}

public void Swap() //交换状态

{

m_bIsCurrentSlapped = m_bIsNextSlapped;

m_bIsNextSlapped = false;

}

public bool WasSlapped() //是否被扇

{

return m_bIsCurrentSlapped;

}

public void CheckStatus() //检查状态,并作出输出

{

if (WasSlapped())

{

Debug.Log(Name + " was slapped, so " + Name + " slapped " + m_facedActor.Name);

m_facedActor.Slap();

}

else

{

Debug.Log(Name + " was not slapped, so nothing happens");

}

}

}

public class DoubleBufferMain : MonoBehaviour

{

private Actor[] actors = new Actor[3];

// Start is called before the first frame update

void Start()

{

Actor april = new Actor("April");

Actor bella = new Actor("Bella");

Actor charlie = new Actor("Charlie");

april.Face(bella);

bella.Face(charlie);

charlie.Face(april);

actors[0] = april;

actors[1] = bella;

actors[2] = charlie;

april.Slap(); //扇A

CheckStatus();

}

private void CheckStatus()

{

for (int i = 0; i < actors.Length; i ++)

{

actors[i].CheckStatus();

}

for (int i = 0; i < actors.Length; i++)

{

actors[i].Swap();

}

Invoke("CheckStatus", 1); //每一秒检测一下状态

}

}

此时不管我们怎么改变演员的顺序,每帧获得的结果都是一样的,并且每个演员都会在自己被扇到的下一帧去扇下一个人。两次结果都是:

d939bf49ea36e74cccd8d1d02b914e01.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值