我知道,在stackoverflow和网上的其他地方有很多这样的问题,但在我读了很多这些,以及官方的android处理程序文档后,我真的不明白它是如何工作的
游戏的概念是,玩家应该猜出一个数字。
我想做什么? 我有4名球员,3名是机器人,1名是人(我)。 我在UI上制作了4个插槽(只是视图),并将图像和文本视图放入其中。
目标是迭代4个玩家,如果是机器人,那么稍等一下(随机),更新其插槽文本,然后跳转到下一个玩家。
如果是人类,请显示一些按钮,等待玩家按下按钮,然后隐藏按钮。
如果人类之后有更多的机器人玩家,那么就按照我上面描述的关于机器人做的事情。
好的,我有一个代码,它似乎有效,特别是当我处于调试模式时,但是当我在手机上运行时,有时会发生事情,应该在它应该之前。
例如,玩家的顺序是: Robot 1,Robot2,Human,Robot3。
机器人1正在更新它的文本,但由于某种原因机器人2没有,人类来了,等我按下按钮,机器人3也更新。
当我尝试记录而不是调试时,我看到,该程序完全混乱。
好的,所以代码: 我有一个可运行的引擎,实现了runnable:
...
public abstract void update();
@Override
public void run() {
// TODO Auto-generated method stub
while (isRunning) {
if (!isComplete) {
update();
}
isComplete = true;
}
}
...
这是活动,扩展了上面的代码。
private Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
// update your view here
if (msg.what == ROBOT_GUESS) {
activeSlot.setSlotGuess();
Log.d(LOG_TAG, "Robot update: " + activeSlot.getPlayerId());
} else if (msg.what == HUMAN_GUESS) {
buttonsContainer.setVisibility(View.VISIBLE);
Log.d(LOG_TAG, "Human buttons");
} else if (msg.what == HUMAN_HAS_GUESSED) {
buttonsContainer.setVisibility(View.GONE);
activeSlot.setSlotGuess();
Log.d(LOG_TAG, "Human buttons removed");
}
}
};
private OnClickListener playerGuessClickListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Your guess: " + v.getId(), Toast.LENGTH_LONG).show();
activeSlot.getPlayer().setGuess(v.getId());
isPlayerGuessed = true;
}
};
@Override
public void update() {
// TODO Auto-generated method stub
Log.d(LOG_TAG, "Update");
for (Slot slot : slots) {
SnobliPlayer player = slot.getPlayer();
if (player.getType() != PlayerTypes.HUMAN.getTypeValue()) {
Log.d(LOG_TAG, "This is a robot");
// This player doesn't hide yet. He should hide.
// And it should be a Robot player
player.guess();
try {
// Waiting some time between 1 - 3 second.
Random random = new Random();
Thread.sleep(random.nextInt(2000) + 1000);
Log.d("UPDATE", String.valueOf("ROBOT GUESS"));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
activeSlot = slot;
messageHandler.sendEmptyMessage(ROBOT_GUESS);
} else {
// Now the human player comes.
Log.d(LOG_TAG, "I am the player");
activeSlot = slot;
messageHandler.sendEmptyMessage(HUMAN_GUESS);
while (!isPlayerGuessed) {
// Do nothing
}
messageHandler.sendEmptyMessage(HUMAN_HAS_GUESSED);
}
}
}
为什么会发生这种情况,我怎么能这样做,玩家会等待对方的猜测?
谢谢。
答案 0 :(得分:0)
我认为你在这里有一个线程问题......
例如,玩家的顺序是:Robot 1,Robot2,Human,Robot3
你说Robot2被跳过了。这是因为update方法中的for循环不会等待处理程序完成执行,因为它们位于不同的线程上。在Robot2移动之后,人类转向接下来你打电话
activeSlot = slot;
messageHandler.sendEmptyMessage(HUMAN_GUESS);
问题是......您不确定处理程序是否已调用
activeSlot.setSlotGuess();
最后一次机器人的猜测..所以当轮到人的时候,人类设置了activeSlot,你不知道Robot2是否有机会设定它的猜测。最好等到转弯,直到使用activeSlot对象完成处理程序。
你可以这样做..
for (Slot slot : slots) {
// at the end of your for loop..
synchronized (activeSlot) {
activeSlot.wait();
}
}
然后在你的处理程序中的if语句之后......
synchronized (activeSlot) {
activeSlot.notify();
}
这将确保在下一回合再次设置处理程序之前使用activeSlot对象完成处理程序。