2012-10-10 63 views
0

我有一个蓝牙游戏应用程序,架构很像的API演示的BluetoothChat应用,除了在发送消息的代替,两名球员送“东西”给对方播放游戏。Android的蓝牙游戏不同步

为了简化,让我们说,例如,两位选手都选择枚举的一个{红,绿,蓝},并按下发送按钮,通过蓝牙消息机制来发送。如果两个玩家选择相同的枚举,他们玩的游戏就是“相同”,否则就是“不相同”。对不起,你知道我为什么隐藏这个,我希望它不会影响讨论。

枚举通过按钮来表示,如

redButton.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      myColor = Red; 
     } 

发送按钮就像

send.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

       sendChoiceViaBluetooth(); 
       //inside this method I used some stuff from the 
       //BluetoothChat API Demo to send the choice 
     } 

,如果我打了一个不同的“颜色”按钮,发送按钮后,我可以重新发送一个新的选择。

并且有这样

if (myColor != null && otherColor != null){ 

    compareColors(); 
    showResult(); 
    myColor = null; 
    otherColor =null; 
} 

两个myColor和otherColor是在开始时为空,并在判断结束时()被复位法官()方法。

的问题是,如果我两个设备上播放速度非常快了很多次,有时我只是不知道为什么,这场比赛将是不同步的。即我仅从设备A发送颜色,设备B做出判断(),但不是设备A,然后我去设备B并发送一种颜色,设备A作为裁判,但设备B上没有任何东西。双方似乎都是从上届会议的“其他颜色”中做出评判。这可以继续,但有时它会在一段时间后消失。

我想某处的东西可能是不同步的,但我不知道在哪里。许多通信方法都来自API Demo中的BluetoothChatService.java,它们大部分是同步的。

有人能指出一个方向,我去寻找答案?我应该在哪里检查等?对不起,冗长的帖子,实际的代码更糟糕,但我试图简化这种情况。

.............................................. ............ 我发现这个bug可能是由于传输丢失。假设播放A和B都比较localColor和remoteColor以获得结果。如果玩家A将他的颜色到B,但它丢失,则此时的游戏状况是这样的:(V指选择,X意味着什么)

      A   |    B 

Time 1:  localColor remoteColor | localColor remoteColor 

       v    x   x   x 

什么都不会玩。 现在,如果B选择颜色和成功发送后,状态变为:

      A   |    B 

Time 2:  localColor remoteColor | localColor remoteColor 

       v    v   v   x 

只有A两全的选择所以只能做法官(),B什么都不做。不同步。下一个选择的东西,只有B判断(),A什么都不做。

我应该怎么做,以保持在同一页面两位球员?即确保其他玩家接受本地选择?

回答

1

这听起来像你需要禁用发送按钮,直到结果从其他设备回来,并发生judge(),然后你可以重新启用它。

+0

谢谢。它可以解决问题。我会试一试。但是如果玩家改变主意,我不想禁用发送按钮。比方说,如果玩A选择红色,然后点击发送。现在玩A选择蓝色,然后在玩家B做任何事情之前点击发送。然后蓝色应该与玩家B进行比较。即,最后的选择(如果两个玩家击中发送)进行比较。 –

+0

另外,没有“结果”。两位球员都一次又一次地发送选择。 “result”是由judge()方法在本地获得的。 –

0

如果你只想判断两个结果是否到位,也就是说A在B做出选择前可能已经改变了他们的想法100次,那么你应该只是在双方都有选择的时候进行判断。

所以在行动响应样的方式通常情况下,将蓝色和B选择红色。法官然后会看到两个选择和判断。这需要法官行动实际上在两个设备上同步,或者至少有权访问这两个设备选择。 (如锁定发送按钮,使其不能被改变,直到判断。)

这听起来对我来说,与选择沿着你还需要发送一个法官状态,这样一台设备不会,而另一个判断才不是。此外,收到的每一个回应都应回应裁判状态和其他选手的选择。

我只从设备A发送颜色,设备B作出判断(),但不是设备A,然后我去设备B并发送颜色,设备A作出判断,但设备B没有任何作用双方似乎是从上届会议的“其他颜色”做出评判。

这对我来说很有意义,如果你不同步评委或回应当前的选择,当你从另一位球员那里收到新的选择。 A中的法官只有A的选择权,如果由于某种原因没有被清除,则选择B是在上次判断时做出的。

在上面的例子中,这可能是为什么它是使用旧数据的原因是,要设置在设备中的价值,同时也被清除或当它被检查空。这将是一个线程安全问题。

我假定法官在一个单独的线程作为工人运行,并检查这些变量的几乎所有的时间的状态。如果是这种情况,您需要以某种方式锁定变量或对其进行排队,并让裁判消耗队列,而不是使用无效值。否则,在法官试图清除变量时,没有什么可以阻止您修改变量。

双方似乎是从上届会议的“otherColor”作出判断。

这也有道理,因为最后一次会议是它如果发送事件没有得到回应有数据的唯一地方,或者如果你正在改变本地变量比法官快可以清除它。如果您要同步裁判事件,这也将得到解决。

所以总结:

  • 尝试同步法官事件,如果这是通过握手期望。

  • 尝试将所有'选项'放入队列并在裁判中使用它们,这样您就不会输入竞争条件,您在检查变量时为空而为其分配值。

  • 确保当应用程序收到“发送”事件或“选择”时,回显当前接收设备所做的选择,因此该设备总是有值。不要判断,直到你得到这个回应,如果你没有得到回应,请不要判断。

有一点信息我可能缩小答案,真正解决问题。

+0

感谢您的信息。虽然没有增加太多我已经知道。 –